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.

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