1
+ import React , { useState } from "react" ;
2
+ import { Button } from "../components/Button" ;
3
+ import { useDarkMode } from "../contexts/DarkModeContext" ;
1
4
import { ClerkProvider , SignIn } from "@clerk/clerk-react" ;
2
- import React from "react" ;
3
5
import { useLoaderData , useNavigate } from "react-router-dom" ;
4
6
7
+ const slides = [
8
+ { text : "This is going to be the way to\u00A0make apps." , author : "Boorad / Brad Anderson" , role : "startup founder" } ,
9
+ { text : "Fastest I’ve ever developed any app of any kind." , author : "Mykle Hansen" , role : "developer" }
10
+ ] ;
11
+
5
12
export async function loader ( { request } ) {
6
13
const url = new URL ( request . url ) ;
7
14
const nextUrl = url . searchParams . get ( "next_url" ) || "/" ;
@@ -11,26 +18,112 @@ export async function loader({ request }) {
11
18
export default function Login ( ) {
12
19
const nextUrl = useLoaderData ( ) as string ;
13
20
const navigate = useNavigate ( ) ;
21
+ const [ emailPreference , setEmailPreference ] = useState ( false ) ;
22
+ const [ activeSlide , setActiveSlide ] = useState ( 0 ) ;
23
+ const isDarkMode = useDarkMode ( ) . isDarkMode ;
24
+
25
+ function incSlide ( ) {
26
+ setActiveSlide ( cur => cur === slides . length - 1 ? 0 : ++ cur ) ;
27
+ }
28
+
29
+ function decSlide ( ) {
30
+ setActiveSlide ( cur => cur === 0 ? slides . length - 1 : -- cur ) ;
31
+ }
14
32
15
33
return (
16
- < ClerkProvider
17
- routerPush = { ( to ) => navigate ( to ) }
18
- routerReplace = { ( to ) => navigate ( to , { replace : true } ) }
19
- publishableKey = { import . meta. env . VITE_CLERK_PUBLISHABLE_KEY }
20
- signInFallbackRedirectUrl = { nextUrl }
21
- >
22
- < div className = "h-screen w-screen flex items-center justify-center" >
23
- < div className = "flex flex-col items-center gap-4" >
24
- < SignIn
25
- appearance = { {
26
- elements : {
27
- headerSubtitle : { display : "none" } ,
28
- footer : { display : "none" } ,
29
- } ,
30
- } }
31
- />
34
+ < div className = "grid grid-cols-1 lg:grid-cols-[1.1fr_1fr] min-h-screen overflow-hidden" >
35
+ < div className = "relative lg:min-h-screen order-2 lg:order-1" >
36
+ < div className = "relative flex justify-center flex-col p-10 sm:p-14 lg:p-20 z-10 h-full z-1" >
37
+ < div className = "flex flex-col gap-10 sm:gap-16 mt-4 sm:mt-[30px]" >
38
+ { slides . map ( slide => < Slide data = { slide } isDarkMode = { isDarkMode } /> ) }
39
+ </ div >
40
+ </ div >
41
+ < img
42
+ className = "absolute top-0 bottom-0 right-0 left-0 w-full h-full object-cover z-0"
43
+ src = { isDarkMode ? "/login-bg-dark.png" : "/login-bg-light.png" }
44
+ />
45
+ </ div >
46
+
47
+ < div className = "flex items-center justify-center h-full order-1 lg:order-2" >
48
+ < div className = { `relative max-w-[445px] p-10 sm:px-[48px] sm:py-[60px] mx-10 my-20 sm:m-14 sm:ml-6 grow-0 rounded-fp-l ${ isDarkMode ? "bg-fp-bg-01" : "" } ` } >
49
+ < ClerkProvider
50
+ routerPush = { ( to ) => navigate ( to ) }
51
+ routerReplace = { ( to ) => navigate ( to , { replace : true } ) }
52
+ publishableKey = { import . meta. env . VITE_CLERK_PUBLISHABLE_KEY }
53
+ signInFallbackRedirectUrl = { nextUrl } >
54
+ < div className = "flex items-center justify-center" >
55
+ < div className = "flex flex-col items-center gap-4" >
56
+ < SignIn
57
+ appearance = { {
58
+ elements : {
59
+ headerSubtitle : { display : "none" } ,
60
+ footer : { display : "none" } ,
61
+ } ,
62
+ } }
63
+ />
64
+ </ div >
65
+ </ div >
66
+ </ ClerkProvider >
67
+ < svg className = "absolute scale-[0.7] sm:scale-100 right-[-68px] bottom-[60px] sm:right-[-60px] sm:bottom-[95px] text-fp-a-02 pointer-events-none" width = "187" height = "186" viewBox = "0 0 187 186" fill = "none" xmlns = "http://www.w3.org/2000/svg" >
68
+ < path
69
+ className = "animate-stroke-dash-500"
70
+ d = "M44.0833 175.38C119.188 155.145 160.007 78.4817 142.027 1.9999"
71
+ stroke = "currentColor"
72
+ strokeWidth = "4"
73
+ strokeDasharray = "500"
74
+ strokeDashoffset = "-500"
75
+ strokeLinecap = "round"
76
+ strokeLinejoin = "round"
77
+ vectorEffect = "non-scaling-stroke"
78
+ />
79
+ < path
80
+ className = "animate-stroke-dash-500"
81
+ d = "M59.8737 159.466L44.0832 175.38L67.7991 178.707"
82
+ stroke = "currentColor"
83
+ strokeWidth = "4"
84
+ strokeDasharray = "500"
85
+ strokeDashoffset = "-500"
86
+ strokeLinecap = "round"
87
+ strokeLinejoin = "round"
88
+ vectorEffect = "non-scaling-stroke"
89
+ />
90
+ </ svg >
91
+ < div className = "absolute scale-[0.85] sm:scale-100 right-[-75px] bottom-[210px] sm:right-[-86px] sm:bottom-[285px]" >
92
+ < p className = "animate-show absolute max-w-[120px] top-[16px] left-[18px] text-center text-[14px] font-bold text-fp-a-02 leading-[1.3] tracking-[-0.04em] rotate-[-11deg]" > Sign in to see your data live!</ p >
93
+ < svg className = "text-fp-a-02" width = "161" height = "67" viewBox = "0 0 161 67" fill = "none" xmlns = "http://www.w3.org/2000/svg" >
94
+ < path
95
+ className = "animate-stroke-dash-2000"
96
+ stroke = "currentColor"
97
+ strokeWidth = "1"
98
+ strokeDasharray = "2000"
99
+ strokeDashoffset = "-2000"
100
+ vectorEffect = "non-scaling-stroke"
101
+ d = "M73.7212 1C36.2218 13 4.22102 24.001 1.2211 44.501C-3.29427 75.3568 62.2205 69.2017 118.221 50.0015C169.722 32.3441 167.379 13.6053 146.721 7.50098C124.721 1 97.2212 4.00098 62.2205 13.0015" />
102
+ </ svg >
103
+ </ div >
32
104
</ div >
33
105
</ div >
34
- </ ClerkProvider >
106
+ </ div >
107
+ ) ;
108
+ }
109
+
110
+ function Slide ( { data, isDarkMode } ) {
111
+ return (
112
+ < div className = "flex flex-col text-white" >
113
+ < p className = "text-[20px] sm:text-[34px] lg:text-[2vw] text-main font-bold text-balance mb-4 leading-[1.3]" > “{ data . text } “</ p >
114
+ < div className = "" >
115
+ < p className = "text-14-bold sm:text-16" > < b > – { data . author } </ b > </ p >
116
+ < p className = { `text-14 ${ isDarkMode ? "text-fp-dec-02" : "text-fp-dec-01" } ` } > { data . role } </ p >
117
+ </ div >
118
+ </ div >
119
+ ) ;
120
+ }
121
+
122
+ function SlideButtonIcon ( { isDarkMode } ) {
123
+ return (
124
+ < svg className = { `${ isDarkMode ? "text-fp-s hover:text-fp-p" : "text-fp-bg-00 hover:text-fp-dec-01" } active:scale-95 transition-transform` } width = "48" height = "48" viewBox = "0 0 48 48" fill = "none" xmlns = "http://www.w3.org/2000/svg" >
125
+ < circle cx = "24" cy = "24" r = "23.5" stroke = "currentColor" />
126
+ < path d = "M33.623 24.5H16.623M16.623 24.5L24.0004 17M16.623 24.5L24.0004 32" stroke = "currentColor" strokeLinecap = "round" strokeLinejoin = "round" />
127
+ </ svg >
35
128
) ;
36
129
}
0 commit comments