11// src/components/Header.tsx
2- import React , { useState , useEffect } from 'react' ;
2+ import React , { useState } from 'react' ;
33import { useEntries } from '../hooks/useEntries' ;
4-
5- import {
6- Dialog ,
7- DialogTrigger ,
8- DialogContent ,
9- DialogFooter ,
10- DialogDescription ,
11- } from './ui/dialog' ;
12- import { Button } from './ui/button' ;
13- import { Input } from './ui/input' ;
14- import { Edit2 , Save , X } from 'lucide-react' ;
15- import { Tooltip , TooltipTrigger , TooltipContent } from './ui/tooltip' ;
16- import { validateEmail } from '../../utils/validateEmail' ;
17- import QuestionCounter from './ui/questionCounter/QuestionCounter' ;
4+ import { Dialog , DialogTrigger } from './ui/dialog' ;
185import SmallCircularQuestionCounter from './ui/questionCounter/smallCircularQuestionCounter' ;
19- import LargeCircularQuestionCounter from './ui/questionCounter/LargeCircularQuestionCounter ' ;
6+ import UserDataModal from './UserDataModal ' ;
207
218const Header : React . FC = ( ) => {
22- const { data, setData } = useEntries ( ) ;
9+ const { data } = useEntries ( ) ;
2310 const [ isDashboardOpen , setIsDashboardOpen ] = useState ( false ) ;
24- // Combined editing state for manager details
25- const [ isEditingContact , setIsEditingContact ] = useState ( false ) ;
26- const [ managerEmailInput , setManagerEmailInput ] = useState (
27- data . managerEmail || ''
28- ) ;
29- const [ managerNameInput , setManagerNameInput ] = useState (
30- data . managerName || ''
31- ) ;
32- const [ emailError , setEmailError ] = useState ( '' ) ;
33-
34- // Sync local inputs with context when edit mode is activated.
35- useEffect ( ( ) => {
36- if ( isEditingContact ) {
37- setManagerEmailInput ( data . managerEmail || '' ) ;
38- setManagerNameInput ( data . managerName || '' ) ;
39- }
40- } , [ isEditingContact , data . managerEmail , data . managerName ] ) ;
41-
42- const handleSaveContact = ( ) => {
43- if ( managerEmailInput . trim ( ) && ! validateEmail ( managerEmailInput . trim ( ) ) ) {
44- setEmailError ( 'Please enter a valid email address.' ) ;
45- return ;
46- }
47- setData ( { type : 'SET_MANAGER_EMAIL' , payload : managerEmailInput } ) ;
48- setData ( { type : 'SET_MANAGER_NAME' , payload : managerNameInput } ) ;
49- setIsEditingContact ( false ) ;
50- setEmailError ( '' ) ;
51- } ;
5211
5312 return (
5413 < header className = 'bg-brand-pink text-white p-4 shadow-md' >
@@ -58,135 +17,20 @@ const Header: React.FC = () => {
5817 < img src = '/lift_logo.png' alt = 'Logo' className = 'h-10 mr-2' />
5918 < h1 className = 'text-2xl font-bold' > Beacons</ h1 >
6019 </ div >
61- { /* Right side: User info & dashboard */ }
20+
21+ { /* Right side: User info & dashboard trigger */ }
6222 { data . username ? (
6323 < Dialog open = { isDashboardOpen } onOpenChange = { setIsDashboardOpen } >
6424 < DialogTrigger asChild >
65- < div className = 'flex items-center border-2 border-white rounded-full px-4 py-2 cursor-pointer' >
66- { data . username ? (
67- < span className = 'mr-2' > Logged as: { data . username } </ span >
68- ) : (
69- < span className = 'mr-2' > Not logged in</ span >
70- ) }
25+ < div className = 'flex items-center border-2 border-white rounded-full px-4 py-2 cursor-pointer hover:bg-pink-600 transition-colors' >
26+ < span className = 'mr-2' > Logged as: { data . username } </ span >
7127 < SmallCircularQuestionCounter />
7228 </ div >
7329 </ DialogTrigger >
74- < DialogContent
75- headerTitle = "User's Data"
76- className = 'sm:max-w-md p-0'
77- >
78- < DialogDescription className = 'sr-only' >
79- Dashboard with user information and settings.
80- </ DialogDescription >
81- < div className = 'bg-gray-50 p-4' >
82- { /* Username section */ }
83- < div >
84- < div className = 'text-sm font-semibold text-gray-700 mb-1' >
85- Your name:
86- </ div >
87- < div className = 'text-sm text-gray-800' >
88- { data . username || 'Not set' }
89- </ div >
90- </ div >
91- { /* Manager contact section */ }
92- < div className = 'mt-4' >
93- < div className = 'text-sm font-semibold text-gray-700 mb-1' >
94- Your line manager's details:
95- </ div >
96- { isEditingContact ? (
97- < div className = 'space-y-2' >
98- < Input
99- value = { managerNameInput }
100- onChange = { ( e ) => setManagerNameInput ( e . target . value ) }
101- placeholder = "Enter manager's name (optional)"
102- aria-label = 'Manager Name'
103- className = 'w-full'
104- />
105- < Input
106- value = { managerEmailInput }
107- onChange = { ( e ) => setManagerEmailInput ( e . target . value ) }
108- placeholder = "Enter manager's email (optional)"
109- aria-label = 'Manager Email'
110- className = 'w-full'
111- />
112- { emailError && (
113- < div className = 'text-red-500 text-xs mt-1' >
114- { emailError }
115- </ div >
116- ) }
117- < div className = 'flex space-x-2' >
118- < Button
119- onClick = { handleSaveContact }
120- variant = 'outline'
121- size = 'sm'
122- aria-label = 'Save Contact'
123- disabled = {
124- managerEmailInput . trim ( ) !== '' &&
125- ! validateEmail ( managerEmailInput . trim ( ) )
126- }
127- >
128- < Save size = { 16 } className = 'text-green-500' />
129- </ Button >
130- < Button
131- onClick = { ( ) => {
132- setIsEditingContact ( false ) ;
133- setManagerEmailInput ( data . managerEmail || '' ) ;
134- setManagerNameInput ( data . managerName || '' ) ;
135- setEmailError ( '' ) ;
136- } }
137- variant = 'outline'
138- size = 'sm'
139- aria-label = 'Cancel Editing'
140- >
141- < X size = { 16 } />
142- </ Button >
143- </ div >
144- </ div >
145- ) : (
146- < div className = 'flex items-center space-x-2' >
147- < div className = 'text-sm text-gray-800' >
148- { data . managerName ? data . managerName : 'Name not set' } |{ ' ' }
149- { data . managerEmail
150- ? data . managerEmail
151- : 'Email not set' }
152- </ div >
153- < Tooltip >
154- < TooltipTrigger asChild >
155- < button
156- className = 'flex items-center justify-center rounded-full bg-white p-2 text-brand-pink'
157- aria-label = "Edit your line manager's details"
158- onClick = { ( ) => setIsEditingContact ( true ) }
159- >
160- < Edit2 size = { 16 } />
161- </ button >
162- </ TooltipTrigger >
163- < TooltipContent >
164- Edit your line manager's details
165- </ TooltipContent >
166- </ Tooltip >
167- </ div >
168- ) }
169- </ div >
170- { /* Progress section */ }
171- < div >
172- < div className = 'text-sm font-semibold text-gray-700 mb-1' >
173- Your progress:
174- </ div >
175- < div className = 'text-sm text-gray-800' >
176- < QuestionCounter />
177- < LargeCircularQuestionCounter />
178- </ div >
179- </ div >
180- </ div >
181- < DialogFooter className = 'p-4 bg-gray-50 sm:rounded-b-lg' >
182- < Button
183- onClick = { ( ) => setIsDashboardOpen ( false ) }
184- variant = 'outline'
185- >
186- Close
187- </ Button >
188- </ DialogFooter >
189- </ DialogContent >
30+ < UserDataModal
31+ isOpen = { isDashboardOpen }
32+ onOpenChange = { setIsDashboardOpen }
33+ />
19034 </ Dialog >
19135 ) : (
19236 < div className = 'flex items-center border-2 border-white rounded-full px-4 py-2 cursor-default' >
0 commit comments