You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

page.tsx 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. "use client";
  2. import {
  3. Button,
  4. Form,
  5. Input,
  6. Typography,
  7. Flex,
  8. Row,
  9. Col,
  10. message,
  11. } from "antd";
  12. import Image from "next/image";
  13. import React, { useState } from "react";
  14. import PhoneInput from "react-phone-input-2";
  15. import "react-phone-input-2/lib/style.css";
  16. const { Title, Text, Link } = Typography;
  17. const SignupPage: React.FC = () => {
  18. const [form] = Form.useForm();
  19. const [phone, setPhone] = useState("");
  20. const onFinish = (values: any) => {
  21. if (values.password !== values.confirmPassword) {
  22. message.error("Passwords do not match");
  23. return;
  24. }
  25. console.log("✅ Success:", { ...values, phone });
  26. message.success("Registered successfully (dummy handler)");
  27. // TODO: Submit to backend API here
  28. };
  29. const onFinishFailed = (errorInfo: any) => {
  30. console.log("❌ Failed:", errorInfo);
  31. message.error("Please check your input.");
  32. };
  33. return (
  34. <Row>
  35. <Col span={24}>
  36. {/* Logo */}
  37. <Flex justify="center" align="center" gap={10} className="!mb-6">
  38. <Image
  39. src="/ruccan_logo2.png"
  40. alt="Ruccan Logo"
  41. height={40}
  42. width={40}
  43. className="object-contain"
  44. />
  45. <Title level={3} className="!font-bold !m-0">
  46. Ruccan.com
  47. </Title>
  48. </Flex>
  49. {/* Form Container */}
  50. <Row style={{ width: "100%" }} justify="center">
  51. <Col span={24} className="!px-5">
  52. <Flex vertical className="!bg-white !p-8 !rounded-2xl !shadow-xl !min-w-[360px]">
  53. {/* Title */}
  54. <Flex vertical align="center" className="!mb-8 !text-center">
  55. <Title
  56. level={2}
  57. className="!mb-2 !text-transparent !font-bold !bg-clip-text bg-gradient-to-r from-blue-500 to-pink-500"
  58. >
  59. Sign Up
  60. </Title>
  61. <Flex justify="center" className="!mt-6">
  62. <Text>
  63. Already have an account?{" "}
  64. <Link href="/guest/login" className="!text-blue-500">
  65. Login
  66. </Link>
  67. </Text>
  68. </Flex>
  69. </Flex>
  70. {/* Form */}
  71. <Form
  72. form={form}
  73. layout="vertical"
  74. onFinish={onFinish}
  75. onFinishFailed={onFinishFailed}
  76. autoComplete="off"
  77. >
  78. <Row gutter={12}>
  79. <Col span={12}>
  80. <Form.Item
  81. label="First Name"
  82. name="firstName"
  83. rules={[{ required: true, message: "First name is required" }]}
  84. >
  85. <Input placeholder="John" />
  86. </Form.Item>
  87. </Col>
  88. <Col span={12}>
  89. <Form.Item
  90. label="Last Name"
  91. name="lastName"
  92. rules={[{ required: true, message: "Last name is required" }]}
  93. >
  94. <Input placeholder="Doe" />
  95. </Form.Item>
  96. </Col>
  97. </Row>
  98. <Form.Item
  99. label="Email"
  100. name="email"
  101. rules={[
  102. { required: true, message: "Email is required" },
  103. { type: "email", message: "Invalid email format" },
  104. ]}
  105. >
  106. <Input placeholder="you@example.com" />
  107. </Form.Item>
  108. <Form.Item
  109. label="Company Name"
  110. name="company"
  111. rules={[{ required: true, message: "Company name is required" }]}
  112. >
  113. <Input placeholder="Ruccan Sdn Bhd" />
  114. </Form.Item>
  115. <Form.Item label="Phone Number" required>
  116. <PhoneInput
  117. country={"my"}
  118. value={phone}
  119. onChange={(value) => setPhone(value)}
  120. inputProps={{
  121. name: "phone",
  122. required: true,
  123. }}
  124. inputClass="!w-full"
  125. containerClass="!w-full"
  126. />
  127. </Form.Item>
  128. <Form.Item
  129. label="Password"
  130. name="password"
  131. rules={[{ required: true, message: "Password is required" }]}
  132. >
  133. <Input.Password placeholder="Create a password" />
  134. </Form.Item>
  135. <Form.Item
  136. label="Confirm Password"
  137. name="confirmPassword"
  138. dependencies={["password"]}
  139. rules={[
  140. { required: true, message: "Please confirm your password" },
  141. ({ getFieldValue }) => ({
  142. validator(_, value) {
  143. if (!value || getFieldValue("password") === value) {
  144. return Promise.resolve();
  145. }
  146. return Promise.reject("Passwords do not match");
  147. },
  148. }),
  149. ]}
  150. >
  151. <Input.Password placeholder="Repeat your password" />
  152. </Form.Item>
  153. <Form.Item>
  154. <Button type="primary" htmlType="submit" block>
  155. Register
  156. </Button>
  157. </Form.Item>
  158. </Form>
  159. </Flex>
  160. </Col>
  161. </Row>
  162. </Col>
  163. </Row>
  164. );
  165. };
  166. export default SignupPage;