@@ -5,119 +5,138 @@ import { QRCodeSVG } from "qrcode.react";
55import { apiClient } from "@/lib/apiClient" ;
66import { setAuthToken , setAuthId } from "@/lib/authUtils" ;
77import { useRouter } from "next/navigation" ;
8+ import Image from "next/image" ;
89
910export default function LoginScreen ( ) {
10- const [ qrData , setQrData ] = useState < string > ( "" ) ;
11- const [ isLoading , setIsLoading ] = useState ( true ) ;
12- const [ isAuthenticating , setIsAuthenticating ] = useState ( false ) ;
13- const router = useRouter ( ) ;
14-
15- useEffect ( ( ) => {
16- initializeAuth ( ) ;
17- } , [ ] ) ;
18-
19- const initializeAuth = async ( ) => {
20- try {
21- const { data } = await apiClient . get ( '/api/auth/offer' ) ;
22- setQrData ( data . uri ) ;
23- setIsLoading ( false ) ;
24-
25- // Start watching for authentication
26- const sessionId = new URL ( data . uri ) . searchParams . get ( 'session' ) ;
27- if ( sessionId ) {
28- watchEventStream ( sessionId ) ;
29- }
30- } catch ( error ) {
31- console . error ( 'Failed to get auth offer:' , error ) ;
32- setIsLoading ( false ) ;
33- }
34- } ;
11+ const [ qrData , setQrData ] = useState < string > ( "" ) ;
12+ const [ isLoading , setIsLoading ] = useState ( true ) ;
13+ const [ isAuthenticating , setIsAuthenticating ] = useState ( false ) ;
14+ const router = useRouter ( ) ;
3515
36- const watchEventStream = ( sessionId : string ) => {
37- const baseUrl = process . env . NEXT_PUBLIC_GROUP_CHARTER_BASE_URL || 'http://localhost:3001' ;
38- const sseUrl = `${ baseUrl } /api/auth/sessions/${ sessionId } ` ;
39- const eventSource = new EventSource ( sseUrl ) ;
16+ useEffect ( ( ) => {
17+ initializeAuth ( ) ;
18+ } , [ ] ) ;
4019
41- eventSource . onopen = ( ) => {
42- console . log ( 'Successfully connected to auth stream.' ) ;
43- } ;
20+ const initializeAuth = async ( ) => {
21+ try {
22+ const { data } = await apiClient . get ( "/api/auth/offer" ) ;
23+ setQrData ( data . uri ) ;
24+ setIsLoading ( false ) ;
4425
45- eventSource . onmessage = ( e ) => {
46- const data = JSON . parse ( e . data ) ;
47- console . log ( 'Auth data received:' , data ) ;
48-
49- const { user, token } = data ;
50-
51- // Set authentication data
52- setAuthId ( user . id ) ;
53- setAuthToken ( token ) ;
54-
55- // Close the event source
56- eventSource . close ( ) ;
57-
58- // Set authenticating state
59- setIsAuthenticating ( true ) ;
60-
61- // Force a page refresh to trigger AuthProvider re-initialization
62- window . location . reload ( ) ;
26+ // Start watching for authentication
27+ const sessionId = new URL ( data . uri ) . searchParams . get ( "session" ) ;
28+ if ( sessionId ) {
29+ watchEventStream ( sessionId ) ;
30+ }
31+ } catch ( error ) {
32+ console . error ( "Failed to get auth offer:" , error ) ;
33+ setIsLoading ( false ) ;
34+ }
6335 } ;
6436
65- eventSource . onerror = ( error ) => {
66- console . error ( 'EventSource error:' , error ) ;
67- eventSource . close ( ) ;
37+ const watchEventStream = ( sessionId : string ) => {
38+ const baseUrl =
39+ process . env . NEXT_PUBLIC_GROUP_CHARTER_BASE_URL ||
40+ "http://localhost:3001" ;
41+ const sseUrl = `${ baseUrl } /api/auth/sessions/${ sessionId } ` ;
42+ const eventSource = new EventSource ( sseUrl ) ;
43+
44+ eventSource . onopen = ( ) => {
45+ console . log ( "Successfully connected to auth stream." ) ;
46+ } ;
47+
48+ eventSource . onmessage = ( e ) => {
49+ const data = JSON . parse ( e . data ) ;
50+ console . log ( "Auth data received:" , data ) ;
51+
52+ const { user, token } = data ;
53+
54+ // Set authentication data
55+ setAuthId ( user . id ) ;
56+ setAuthToken ( token ) ;
57+
58+ // Close the event source
59+ eventSource . close ( ) ;
60+
61+ // Set authenticating state
62+ setIsAuthenticating ( true ) ;
63+
64+ // Force a page refresh to trigger AuthProvider re-initialization
65+ window . location . reload ( ) ;
66+ } ;
67+
68+ eventSource . onerror = ( error ) => {
69+ console . error ( "EventSource error:" , error ) ;
70+ eventSource . close ( ) ;
71+ } ;
6872 } ;
69- } ;
7073
71- if ( isLoading ) {
72- return (
73- < div className = "flex h-screen items-center justify-center" >
74- < div className = "animate-spin rounded-full h-32 w-32 border-b-2 border-gray-900" > </ div >
75- </ div >
76- ) ;
77- }
74+ if ( isLoading ) {
75+ return (
76+ < div className = "flex h-screen items-center justify-center" >
77+ < div className = "animate-spin rounded-full h-32 w-32 border-b-2 border-gray-900" > </ div >
78+ </ div >
79+ ) ;
80+ }
81+
82+ if ( isAuthenticating ) {
83+ return (
84+ < div className = "flex h-screen items-center justify-center" >
85+ < div className = "text-center" >
86+ < div className = "animate-spin rounded-full h-32 w-32 border-b-2 border-gray-900 mx-auto mb-4" > </ div >
87+ < p className = "text-lg text-gray-600" > Authenticating...</ p >
88+ </ div >
89+ </ div >
90+ ) ;
91+ }
7892
79- if ( isAuthenticating ) {
8093 return (
81- < div className = "flex h-screen items-center justify-center" >
82- < div className = "text-center" >
83- < div className = "animate-spin rounded-full h-32 w-32 border-b-2 border-gray-900 mx-auto mb-4" > </ div >
84- < p className = "text-lg text-gray-600" > Authenticating...</ p >
85- </ div >
86- </ div >
87- ) ;
88- }
89-
90- return (
91- < div className = "flex h-screen items-center justify-center bg-gray-50" >
92- < div className = "bg-white p-8 rounded-lg shadow-lg max-w-md w-full" >
93- < div className = "text-center mb-8" >
94- < h1 className = "text-2xl font-bold text-gray-900 mb-2" >
95- Group Charter Manager
96- </ h1 >
97- < p className = "text-gray-600" >
98- Scan the QR code to login with your W3DS identity
99- </ p >
100- </ div >
94+ < div className = "flex h-screen items-center justify-center bg-gray-50" >
95+ < div className = "bg-white p-8 rounded-lg shadow-lg max-w-md w-full" >
96+ < div className = "text-center mb-8" >
97+ < h1 className = "text-2xl font-bold text-gray-900 mb-2" >
98+ Group Charter Manager
99+ </ h1 >
100+ < p className = "text-gray-600" >
101+ Scan the QR code to login with your W3DS identity
102+ </ p >
103+ </ div >
101104
102- { qrData && (
103- < div className = "flex justify-center mb-6" >
104- < div className = "bg-white p-4 rounded-lg border" >
105- < QRCodeSVG
106- value = { qrData }
107- size = { 200 }
108- level = "M"
109- includeMargin = { true }
110- />
111- </ div >
112- </ div >
113- ) }
105+ { qrData && (
106+ < div className = "flex justify-center mb-6" >
107+ < div className = "bg-white p-4 rounded-lg border" >
108+ < QRCodeSVG
109+ value = { qrData }
110+ size = { 200 }
111+ level = "M"
112+ includeMargin = { true }
113+ />
114+ </ div >
115+ </ div >
116+ ) }
114117
115- < div className = "text-center" >
116- < p className = "text-sm text-gray-500" >
117- Use your W3DS wallet to scan this QR code and authenticate
118- </ p >
118+ < div className = "text-center" >
119+ < p className = "text-sm text-gray-500" >
120+ Use your W3DS wallet to scan this QR code and
121+ authenticate
122+ </ p >
123+ </ div >
124+ < p className = "p-4 rounded-xl bg-gray-100 text-gray-700 mt-4" >
125+ You are entering Group Charter - a group charter management
126+ platform built on the Web 3.0 Data Space (W3DS)
127+ architecture. This system is designed around the principle
128+ of data-platform separation, where all your personal content
129+ is stored in your own sovereign eVault, not on centralised
130+ servers.
131+ </ p >
132+ < Image
133+ src = "/W3DS.svg"
134+ alt = "W3DS Logo"
135+ width = { 50 }
136+ height = { 20 }
137+ className = "mx-auto mt-5"
138+ />
139+ </ div >
119140 </ div >
120- </ div >
121- </ div >
122- ) ;
123- }
141+ ) ;
142+ }
0 commit comments