소스 검색

New Login page layout

master
azri 1 일 전
부모
커밋
96e9942d91
8개의 변경된 파일409개의 추가작업 그리고 56개의 파일을 삭제
  1. 19
    40
      app/guest/layout.tsx
  2. 175
    0
      app/guest/login/page.tsx
  3. 14
    8
      app/guest/page.tsx
  4. 182
    0
      app/guest/signup/page.tsx
  5. 13
    8
      app/page.tsx
  6. 6
    0
      public/facebook_icon.svg
  7. BIN
      public/google_logo.png
  8. BIN
      public/ruccan_bg.jpg

+ 19
- 40
app/guest/layout.tsx 파일 보기

@@ -1,49 +1,28 @@
1 1
 'use client'
2 2
 
3 3
 import React from 'react'
4
-import { Layout, Flex, Row, Col } from 'antd'
5
-import Header from '@/components/layout/Header'
6
-import Navigation from '@/components/layout/Navigation'
7
-import { usePathname } from 'next/navigation'
8
-
4
+import { Layout, Flex } from 'antd'
9 5
 
10 6
 const AppLayout = ({ children }: { children: React.ReactNode }) => {
11
-
12
-  const pathname = usePathname()
13
-
14
-  const skipLayoutPrefixes = [
15
-    '/user/chat/',
16
-    '/user/persona/create',
17
-    '/user/knowledge/create',
18
-    '/user/settings/profile',
19
-    '/user/payment',
20
-    '/user/payment'
21
-  ];
22
-
23
-  const shouldSkipLayout = skipLayoutPrefixes.some(prefix =>
24
-    pathname.startsWith(prefix)
25
-  );
26
-
27
-  if (shouldSkipLayout) {
28
-    return <>{children}</>;
29
-  }
30
-
31 7
   return (
32
-    <Layout className="!w-full !max-w-[430px] !mx-auto !relative !bg-white">
33
-      <Flex vertical className='!h-screen'>
34
-        <Row>
35
-          <Col span={24}>
36
-            <Header />
37
-          </Col>
38
-        </Row>
39
-
40
-        <Row className='flex-1 overflow-y-scroll overflow-x-hidden'>
41
-          <Col span={24}>{children}</Col>
42
-        </Row>
43
-
44
-        <div>
45
-          <Navigation />
46
-        </div>
8
+    <Layout className="!w-full !max-w-[430px] !mx-auto !relative overflow-hidden">
9
+      {/* Background Image Layer */}
10
+      <div
11
+        className="absolute inset-0 z-0 bg-cover bg-center blur-sm scale-105"
12
+        style={{
13
+          backgroundImage: "url('/ruccan_bg.jpg')", // Change this to your image path
14
+        }}
15
+      />
16
+
17
+      {/* Foreground Content */}
18
+      <Flex
19
+        vertical
20
+        style={{ minHeight: "100vh" }}
21
+        align="center"
22
+        justify="center"
23
+        className="relative z-10 !bg-gray-50/60 backdrop-blur-md !px-2 !py-10"
24
+      >
25
+        {children}
47 26
       </Flex>
48 27
     </Layout>
49 28
   );

+ 175
- 0
app/guest/login/page.tsx 파일 보기

@@ -0,0 +1,175 @@
1
+"use client";
2
+
3
+import {
4
+  Button,
5
+  Checkbox,
6
+  Form,
7
+  Input,
8
+  Typography,
9
+  Flex,
10
+  Row,
11
+  Col,
12
+  message,
13
+} from "antd";
14
+import Image from "next/image";
15
+import React from "react";
16
+
17
+const { Title, Text, Link } = Typography;
18
+
19
+const LoginPage: React.FC = () => {
20
+  const [form] = Form.useForm();
21
+
22
+  const onFinish = (values: any) => {
23
+    console.log("✅ Success:", values);
24
+    message.success("Logged in successfully (dummy handler)");
25
+    window.location.href = "/user"
26
+  };
27
+
28
+  const onFinishFailed = (errorInfo: any) => {
29
+    console.log("❌ Failed:", errorInfo);
30
+    message.error("Please check your input.");
31
+  };
32
+
33
+  return (
34
+    <Row>
35
+      <Col span={24}>
36
+        {/* Logo on Top */}
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
+
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
+                  Get started now
60
+                </Title>
61
+                <Text type="secondary" className="!text-xs">
62
+                  Create an account or log in to explore our app
63
+                </Text>
64
+              </Flex>
65
+
66
+              {/* Social Buttons */}
67
+              <Flex vertical gap="middle" className="mb-6">
68
+                <Button
69
+                  block
70
+                  className="!bg-white !text-black !border !border-gray-300 hover:!border-blue-400"
71
+                  icon={
72
+                    <Image
73
+                      src="/google_logo.png"
74
+                      alt="Google"
75
+                      width={18}
76
+                      height={18}
77
+                    />
78
+                  }
79
+                >
80
+                  Sign in with Google
81
+                </Button>
82
+
83
+                <Button
84
+                  block
85
+                  className="!bg-white !text-black !border !border-gray-300 hover:!border-blue-600"
86
+                  icon={
87
+                    <Image
88
+                      src="/facebook_icon.svg"
89
+                      alt="Facebook"
90
+                      width={18}
91
+                      height={18}
92
+                    />
93
+                  }
94
+                >
95
+                  Sign in with Facebook
96
+                </Button>
97
+              </Flex>
98
+
99
+              {/* Divider */}
100
+              <Row align="middle" className="!my-2">
101
+                <Col flex="auto">
102
+                  <div className="!border-t !border-gray-300 !w-full" />
103
+                </Col>
104
+                <Col>
105
+                  <Text type="secondary" className="!px-4 !text-sm">
106
+                    OR
107
+                  </Text>
108
+                </Col>
109
+                <Col flex="auto">
110
+                  <div className="!border-t !border-gray-300 !w-full" />
111
+                </Col>
112
+              </Row>
113
+
114
+              {/* Login Form */}
115
+              <Form
116
+                form={form}
117
+                layout="vertical"
118
+                onFinish={onFinish}
119
+                onFinishFailed={onFinishFailed}
120
+                autoComplete="off"
121
+                initialValues={{ remember: true }}
122
+              >
123
+                <Form.Item
124
+                  label="Email"
125
+                  name="email"
126
+                  rules={[
127
+                    { required: true, message: "Please input your email!" },
128
+                    { type: "email", message: "Invalid email format" },
129
+                  ]}
130
+                >
131
+                  <Input placeholder="Enter your email" />
132
+                </Form.Item>
133
+
134
+                <Form.Item
135
+                  label="Password"
136
+                  name="password"
137
+                  rules={[{ required: true, message: "Please input your password!" }]}
138
+                >
139
+                  <Input.Password placeholder="Enter your password" />
140
+                </Form.Item>
141
+
142
+                <Flex justify="space-between" wrap align="center" className="!mb-4">
143
+                  <Form.Item name="remember" valuePropName="checked" noStyle>
144
+                    <Checkbox>Remember me</Checkbox>
145
+                  </Form.Item>
146
+                  <Link href="#" className="!text-blue-500">
147
+                    Forgot password?
148
+                  </Link>
149
+                </Flex>
150
+
151
+                <Form.Item>
152
+                  <Button type="primary" htmlType="submit" block>
153
+                    Log In
154
+                  </Button>
155
+                </Form.Item>
156
+              </Form>
157
+
158
+              {/* Sign Up */}
159
+              <Flex justify="center" className="!mt-6">
160
+                <Text>
161
+                  Don’t have an account?{" "}
162
+                  <Link href="/guest/signup" className="!text-blue-500">
163
+                    Sign Up
164
+                  </Link>
165
+                </Text>
166
+              </Flex>
167
+            </Flex>
168
+          </Col>
169
+        </Row>
170
+      </Col>
171
+    </Row>
172
+  );
173
+};
174
+
175
+export default LoginPage;

+ 14
- 8
app/guest/page.tsx 파일 보기

@@ -1,10 +1,16 @@
1
-'use client'
2
-import { useEffect } from "react"
1
+"use client";
3 2
 
4
-export default function HomePage() {
3
+import LoadingScreen from "@/components/layout/LoadingScreen";
4
+import React from "react";
5 5
 
6
-  return (
7
-    <div className="space-y-6">
8
-    </div>
9
-  )
10
-}
6
+const GuestPage: React.FC = () => {
7
+
8
+  React.useEffect(() => {
9
+    window.location.href = "/guest/login"
10
+  }, [])
11
+  
12
+
13
+  return <LoadingScreen/>;
14
+};
15
+
16
+export default GuestPage;

+ 182
- 0
app/guest/signup/page.tsx 파일 보기

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

+ 13
- 8
app/page.tsx 파일 보기

@@ -1,11 +1,16 @@
1
-'use client'
2
-import { useEffect } from "react"
1
+"use client";
3 2
 
4
-export default function HomePage() {
3
+import LoadingScreen from "@/components/layout/LoadingScreen";
4
+import React from "react";
5 5
 
6
+const MainPage: React.FC = () => {
6 7
 
7
-  return (
8
-    <div className="space-y-6">
9
-    </div>
10
-  )
11
-}
8
+  React.useEffect(() => {
9
+    window.location.href = "/guest/login"
10
+  }, [])
11
+
12
+
13
+  return <LoadingScreen />;
14
+};
15
+
16
+export default MainPage;

+ 6
- 0
public/facebook_icon.svg 파일 보기

@@ -0,0 +1,6 @@
1
+<svg xmlns="http://www.w3.org/2000/svg" width="48.544" height="48.558" viewBox="0 0 48.544 48.558">
2
+  <g id="Group" transform="translate(1290.54 1031.211)">
3
+    <path id="Vector" d="M48.544,24.28A24.281,24.281,0,0,1,27.652,48.325a24.588,24.588,0,0,1-7.267-.077A24.28,24.28,0,1,1,48.544,24.28Z" transform="translate(-1290.54 -1031.211)" fill="#1877f2"/>
4
+    <path id="Vector-2" data-name="Vector" d="M13.3,8.453v5.289h6.541l-1.036,7.125H13.3V37.283a24.6,24.6,0,0,1-3.379.233,24.4,24.4,0,0,1-3.888-.31V20.867H0V13.743H6.033V7.271A7.27,7.27,0,0,1,13.3,0V0c.012,0,.022,0,.034,0h6.507V6.162H15.591A2.29,2.29,0,0,0,13.3,8.452Z" transform="translate(-1276.188 -1020.17)" fill="#fff"/>
5
+  </g>
6
+</svg>

BIN
public/google_logo.png 파일 보기


BIN
public/ruccan_bg.jpg 파일 보기


Loading…
취소
저장