1
1
'use client' ;
2
2
3
+ import Cookies from 'js-cookie' ;
4
+ import { X } from 'lucide-react' ;
3
5
import { useSession } from 'next-auth/react' ;
6
+ import { useLocale } from 'next-intl' ;
4
7
import Image from 'next/image' ;
5
- import React from 'react' ;
8
+ import React , { useState } from 'react' ;
6
9
10
+ import { Button } from '@o2s/ui/components/button' ;
11
+ import { Collapsible , CollapsibleContent , CollapsibleTrigger } from '@o2s/ui/components/collapsible' ;
7
12
import { Link } from '@o2s/ui/components/link' ;
13
+ import { Typography } from '@o2s/ui/components/typography' ;
8
14
9
15
import { Link as NextLink } from '@/i18n' ;
10
16
@@ -17,10 +23,29 @@ import { MobileNavigation } from './MobileNavigation/MobileNavigation';
17
23
import { NotificationInfo } from './NotificationInfo/NotificationInfo' ;
18
24
import { UserInfo } from './UserInfo/UserInfo' ;
19
25
20
- export const Header : React . FC < HeaderProps > = ( { headerData, children } ) => {
26
+ const MOCK : { [ key : string ] : { info : string ; link : string } } = {
27
+ en : {
28
+ info : 'You are currently viewing a demo version, where parts of the app may not be fully ready yet. If you notice any issues or want to give us your feedback, you can' ,
29
+ link : 'do it here' ,
30
+ } ,
31
+ de : {
32
+ info : 'Sie sehen derzeit eine Demoversion, in der Teile der App möglicherweise noch nicht vollständig fertiggestellt sind. Wenn Sie Probleme bemerken oder uns Ihr Feedback geben möchten, können Sie' ,
33
+ link : 'das hier tun' ,
34
+ } ,
35
+ pl : {
36
+ info : 'Obecnie przeglądasz wersję demonstracyjną, gdzie niektóre części aplikacji mogą nie być jeszcze w pełni gotowe. Jeśli zauważysz jakieś problemy lub chcesz przekazać nam swoją opinię, możesz' ,
37
+ link : 'zrobić to tutaj' ,
38
+ } ,
39
+ } ;
40
+
41
+ export const Header : React . FC < HeaderProps > = ( { headerData, isDemoHidden, children } ) => {
21
42
const session = useSession ( ) ;
22
43
const isSignedIn = session ?. status === 'authenticated' ;
23
44
45
+ const locale = useLocale ( ) ;
46
+
47
+ const [ demoHidden , setDemoHidden ] = useState ( isDemoHidden ) ;
48
+
24
49
const LogoSlot = (
25
50
< Link asChild >
26
51
< NextLink href = "/" aria-label = { headerData . logo ?. name } >
@@ -60,32 +85,69 @@ export const Header: React.FC<HeaderProps> = ({ headerData, children }) => {
60
85
isSignedIn && headerData . contextSwitcher && < ContextSwitcher context = { headerData . contextSwitcher } /> ;
61
86
62
87
return (
63
- < header className = "flex flex-col gap-4" >
64
- < >
65
- < div className = "md:block hidden" >
66
- < DesktopNavigation
67
- logoSlot = { LogoSlot }
68
- contextSlot = { < ContextSwitchSlot /> }
69
- localeSlot = { < LocaleSlot /> }
70
- notificationSlot = { < NotificationSlot /> }
71
- userSlot = { < UserSlot /> }
72
- items = { headerData . items }
73
- />
74
- </ div >
75
- < div className = "md:hidden" >
76
- < MobileNavigation
77
- logoSlot = { LogoSlot }
78
- contextSlot = { < ContextSwitchSlot /> }
79
- localeSlot = { < LocaleSlot /> }
80
- notificationSlot = { < NotificationSlot /> }
81
- userSlot = { < UserSlot /> }
82
- items = { headerData . items }
83
- title = { headerData . title }
84
- mobileMenuLabel = { headerData . mobileMenuLabel }
85
- />
86
- </ div >
87
- </ >
88
- { children }
89
- </ header >
88
+ < >
89
+ < Collapsible
90
+ open = { ! demoHidden }
91
+ onOpenChange = { ( ) => {
92
+ setDemoHidden ( true ) ;
93
+ Cookies . set ( 'demoHidden' , 'true' , { expires : 1 } ) ;
94
+ } }
95
+ >
96
+ < CollapsibleContent defaultOpen = { ! demoHidden } >
97
+ < div className = "bg-primary text-primary-foreground" >
98
+ < div className = "px-4 md:px-6 py-2 ml-auto mr-auto w-full md:max-w-7xl" >
99
+ < div className = "flex gap-4 items-center justify-between" >
100
+ < Typography variant = "small" >
101
+ { ( MOCK [ locale ] || MOCK . en ) ! . info } { ' ' }
102
+ < Link
103
+ href = "https://github.com/o2sdev/openselfservice/issues"
104
+ target = "_blank"
105
+ className = "text-primary-foreground underline"
106
+ >
107
+ { ( MOCK [ locale ] || MOCK . en ) ! . link }
108
+ </ Link >
109
+ .
110
+ </ Typography >
111
+
112
+ < CollapsibleTrigger asChild >
113
+ < Button variant = "ghost" size = "sm" className = "w-9 p-0 shrink-0" >
114
+ < X className = "h-4 w-4" />
115
+ < span className = "sr-only" > Close</ span >
116
+ </ Button >
117
+ </ CollapsibleTrigger >
118
+ </ div >
119
+ </ div >
120
+ </ div >
121
+ </ CollapsibleContent >
122
+ </ Collapsible >
123
+
124
+ < header className = "flex flex-col gap-4" >
125
+ < >
126
+ < div className = "md:block hidden" >
127
+ < DesktopNavigation
128
+ logoSlot = { LogoSlot }
129
+ contextSlot = { < ContextSwitchSlot /> }
130
+ localeSlot = { < LocaleSlot /> }
131
+ notificationSlot = { < NotificationSlot /> }
132
+ userSlot = { < UserSlot /> }
133
+ items = { headerData . items }
134
+ />
135
+ </ div >
136
+ < div className = "md:hidden" >
137
+ < MobileNavigation
138
+ logoSlot = { LogoSlot }
139
+ contextSlot = { < ContextSwitchSlot /> }
140
+ localeSlot = { < LocaleSlot /> }
141
+ notificationSlot = { < NotificationSlot /> }
142
+ userSlot = { < UserSlot /> }
143
+ items = { headerData . items }
144
+ title = { headerData . title }
145
+ mobileMenuLabel = { headerData . mobileMenuLabel }
146
+ />
147
+ </ div >
148
+ </ >
149
+ { children }
150
+ </ header >
151
+ </ >
90
152
) ;
91
153
} ;
0 commit comments