this.gui 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,87 @@
1
+ import * as React from 'react';
2
+ import Box from '@mui/joy/Box';
3
+ import Sheet from '@mui/joy/Sheet';
4
+ import Stack from '@mui/joy/Stack';
5
+ import AvatarWithStatus from './AvatarWithStatus';
6
+ import ChatBubble from './ChatBubble';
7
+ import MessageInput from './MessageInput';
8
+ import MessagesPaneHeader from './MessagesPaneHeader';
9
+ import { ChatProps, MessageProps } from '../types';
10
+
11
+ type MessagesPaneProps = {
12
+ chat: ChatProps;
13
+ };
14
+
15
+ export default function MessagesPane({ chat }: MessagesPaneProps) {
16
+ const [chatMessages, setChatMessages] = React.useState(chat.messages);
17
+ const [textAreaValue, setTextAreaValue] = React.useState('');
18
+
19
+ React.useEffect(() => {
20
+ setChatMessages(chat.messages);
21
+ }, [chat.messages]);
22
+
23
+ return (
24
+ <Sheet
25
+ sx={{
26
+ height: { xs: 'calc(100dvh - var(--Header-height))', lg: '100dvh' },
27
+ display: 'flex',
28
+ flexDirection: 'column',
29
+ backgroundColor: 'background.level1',
30
+ }}
31
+ >
32
+ <MessagesPaneHeader sender={chat.sender} />
33
+
34
+ <Box
35
+ sx={{
36
+ display: 'flex',
37
+ flex: 1,
38
+ minHeight: 0,
39
+ px: 2,
40
+ py: 3,
41
+ overflowY: 'scroll',
42
+ flexDirection: 'column-reverse',
43
+ }}
44
+ >
45
+ <Stack spacing={2} justifyContent="flex-end">
46
+ {chatMessages.map((message: MessageProps, index: number) => {
47
+ const isYou = message.sender === 'You';
48
+ return (
49
+ <Stack
50
+ key={index}
51
+ direction="row"
52
+ spacing={2}
53
+ flexDirection={isYou ? 'row-reverse' : 'row'}
54
+ >
55
+ {message.sender !== 'You' && (
56
+ <AvatarWithStatus
57
+ online={message.sender.online}
58
+ src={message.sender.avatar}
59
+ />
60
+ )}
61
+ <ChatBubble variant={isYou ? 'sent' : 'received'} {...message} />
62
+ </Stack>
63
+ );
64
+ })}
65
+ </Stack>
66
+ </Box>
67
+
68
+ <MessageInput
69
+ textAreaValue={textAreaValue}
70
+ setTextAreaValue={setTextAreaValue}
71
+ onSubmit={() => {
72
+ const newId = chatMessages.length + 1;
73
+ const newIdString = newId.toString();
74
+ setChatMessages([
75
+ ...chatMessages,
76
+ {
77
+ id: newIdString,
78
+ sender: 'You',
79
+ content: textAreaValue,
80
+ timestamp: 'Just now',
81
+ },
82
+ ]);
83
+ }}
84
+ />
85
+ </Sheet>
86
+ );
87
+ }
@@ -0,0 +1,105 @@
1
+ import * as React from 'react';
2
+ import Avatar from '@mui/joy/Avatar';
3
+ import Button from '@mui/joy/Button';
4
+ import Chip from '@mui/joy/Chip';
5
+ import IconButton from '@mui/joy/IconButton';
6
+ import Stack from '@mui/joy/Stack';
7
+ import Typography from '@mui/joy/Typography';
8
+ import CircleIcon from '@mui/icons-material/Circle';
9
+ import ArrowBackIosNewRoundedIcon from '@mui/icons-material/ArrowBackIosNewRounded';
10
+ import PhoneInTalkRoundedIcon from '@mui/icons-material/PhoneInTalkRounded';
11
+ import MoreVertRoundedIcon from '@mui/icons-material/MoreVertRounded';
12
+ import { UserProps } from '../types';
13
+ import { toggleMessagesPane } from '../utils';
14
+
15
+ type MessagesPaneHeaderProps = {
16
+ sender: UserProps;
17
+ };
18
+
19
+ export default function MessagesPaneHeader({ sender }: MessagesPaneHeaderProps) {
20
+ return (
21
+ <Stack
22
+ direction="row"
23
+ justifyContent="space-between"
24
+ sx={{
25
+ borderBottom: '1px solid',
26
+ borderColor: 'divider',
27
+ backgroundColor: 'background.body',
28
+ }}
29
+ py={{ xs: 2, md: 2 }}
30
+ px={{ xs: 1, md: 2 }}
31
+ >
32
+ <Stack direction="row" spacing={{ xs: 1, md: 2 }} alignItems="center">
33
+ <IconButton
34
+ variant="plain"
35
+ color="neutral"
36
+ size="sm"
37
+ sx={{
38
+ display: { xs: 'inline-flex', sm: 'none' },
39
+ }}
40
+ onClick={() => toggleMessagesPane()}
41
+ >
42
+ <ArrowBackIosNewRoundedIcon />
43
+ </IconButton>
44
+ <Avatar size="lg" src={sender.avatar} />
45
+ <div>
46
+ <Typography
47
+ fontWeight="lg"
48
+ fontSize="lg"
49
+ component="h2"
50
+ noWrap
51
+ endDecorator={
52
+ sender.online ? (
53
+ <Chip
54
+ variant="outlined"
55
+ size="sm"
56
+ color="neutral"
57
+ sx={{
58
+ borderRadius: 'sm',
59
+ }}
60
+ startDecorator={
61
+ <CircleIcon sx={{ fontSize: 8 }} color="success" />
62
+ }
63
+ slotProps={{ root: { component: 'span' } }}
64
+ >
65
+ Online
66
+ </Chip>
67
+ ) : undefined
68
+ }
69
+ >
70
+ {sender.name}
71
+ </Typography>
72
+
73
+ <Typography level="body-sm">{sender.username}</Typography>
74
+ </div>
75
+ </Stack>
76
+ <Stack spacing={1} direction="row" alignItems="center">
77
+ <Button
78
+ startDecorator={<PhoneInTalkRoundedIcon />}
79
+ color="neutral"
80
+ variant="outlined"
81
+ size="sm"
82
+ sx={{
83
+ display: { xs: 'none', md: 'inline-flex' },
84
+ }}
85
+ >
86
+ Call
87
+ </Button>
88
+ <Button
89
+ color="neutral"
90
+ variant="outlined"
91
+ size="sm"
92
+ sx={{
93
+ display: { xs: 'none', md: 'inline-flex' },
94
+ }}
95
+ >
96
+ View profile
97
+ </Button>
98
+
99
+ <IconButton size="sm" variant="plain" color="neutral">
100
+ <MoreVertRoundedIcon />
101
+ </IconButton>
102
+ </Stack>
103
+ </Stack>
104
+ );
105
+ }
@@ -0,0 +1,34 @@
1
+ import * as React from 'react';
2
+ import AspectRatio, { AspectRatioProps } from '@mui/joy/AspectRatio';
3
+
4
+ export default function MuiLogo({ sx, ...props }: AspectRatioProps) {
5
+ return (
6
+ <AspectRatio
7
+ ratio="1"
8
+ variant="plain"
9
+ {...props}
10
+ sx={[
11
+ {
12
+ width: 36,
13
+ borderRadius: 'sm',
14
+ },
15
+ ...(Array.isArray(sx) ? sx : [sx]),
16
+ ]}
17
+ >
18
+ <div>
19
+ <svg
20
+ xmlns="http://www.w3.org/2000/svg"
21
+ width="24"
22
+ height="20"
23
+ viewBox="0 0 36 32"
24
+ fill="none"
25
+ >
26
+ <path
27
+ d="M30.343 21.976a1 1 0 00.502-.864l.018-5.787a1 1 0 01.502-.864l3.137-1.802a1 1 0 011.498.867v10.521a1 1 0 01-.502.867l-11.839 6.8a1 1 0 01-.994.001l-9.291-5.314a1 1 0 01-.504-.868v-5.305c0-.006.007-.01.013-.007.005.003.012 0 .012-.007v-.006c0-.004.002-.008.006-.01l7.652-4.396c.007-.004.004-.015-.004-.015a.008.008 0 01-.008-.008l.015-5.201a1 1 0 00-1.5-.87l-5.687 3.277a1 1 0 01-.998 0L6.666 9.7a1 1 0 00-1.499.866v9.4a1 1 0 01-1.496.869l-3.166-1.81a1 1 0 01-.504-.87l.028-16.43A1 1 0 011.527.86l10.845 6.229a1 1 0 00.996 0L24.21.86a1 1 0 011.498.868v16.434a1 1 0 01-.501.867l-5.678 3.27a1 1 0 00.004 1.735l3.132 1.783a1 1 0 00.993-.002l6.685-3.839zM31 7.234a1 1 0 001.514.857l3-1.8A1 1 0 0036 5.434V1.766A1 1 0 0034.486.91l-3 1.8a1 1 0 00-.486.857v3.668z"
28
+ fill="#007FFF"
29
+ />
30
+ </svg>
31
+ </div>
32
+ </AspectRatio>
33
+ );
34
+ }
@@ -0,0 +1,49 @@
1
+ import * as React from 'react';
2
+ import Sheet from '@mui/joy/Sheet';
3
+ import MessagesPane from './MessagesPane';
4
+ import ChatsPane from './ChatsPane';
5
+ import { ChatProps } from '../types';
6
+ import { chats } from '../data';
7
+
8
+ export default function MyProfile() {
9
+ const [selectedChat, setSelectedChat] = React.useState<ChatProps>(chats[0]);
10
+ return (
11
+ <Sheet
12
+ sx={{
13
+ flex: 1,
14
+ width: '100%',
15
+ mx: 'auto',
16
+ pt: { xs: 'var(--Header-height)', sm: 0 },
17
+ display: 'grid',
18
+ gridTemplateColumns: {
19
+ xs: '1fr',
20
+ sm: 'minmax(min-content, min(30%, 400px)) 1fr',
21
+ },
22
+ }}
23
+ >
24
+ <Sheet
25
+ sx={{
26
+ position: {
27
+ xs: 'fixed',
28
+ sm: 'sticky',
29
+ },
30
+ transform: {
31
+ xs: 'translateX(calc(100% * (var(--MessagesPane-slideIn, 0) - 1)))',
32
+ sm: 'none',
33
+ },
34
+ transition: 'transform 0.4s, width 0.4s',
35
+ zIndex: 100,
36
+ width: '100%',
37
+ top: 52,
38
+ }}
39
+ >
40
+ <ChatsPane
41
+ chats={chats}
42
+ selectedChatId={selectedChat.id}
43
+ setSelectedChat={setSelectedChat}
44
+ />
45
+ </Sheet>
46
+ <MessagesPane chat={selectedChat} />
47
+ </Sheet>
48
+ );
49
+ }
@@ -0,0 +1,320 @@
1
+ import * as React from 'react';
2
+ import GlobalStyles from '@mui/joy/GlobalStyles';
3
+ import Avatar from '@mui/joy/Avatar';
4
+ import Box from '@mui/joy/Box';
5
+ import Button from '@mui/joy/Button';
6
+ import Card from '@mui/joy/Card';
7
+ import Chip from '@mui/joy/Chip';
8
+ import Divider from '@mui/joy/Divider';
9
+ import IconButton from '@mui/joy/IconButton';
10
+ import Input from '@mui/joy/Input';
11
+ import LinearProgress from '@mui/joy/LinearProgress';
12
+ import List from '@mui/joy/List';
13
+ import ListItem from '@mui/joy/ListItem';
14
+ import ListItemButton, { listItemButtonClasses } from '@mui/joy/ListItemButton';
15
+ import ListItemContent from '@mui/joy/ListItemContent';
16
+ import Typography from '@mui/joy/Typography';
17
+ import Sheet from '@mui/joy/Sheet';
18
+ import Stack from '@mui/joy/Stack';
19
+ import SearchRoundedIcon from '@mui/icons-material/SearchRounded';
20
+ import HomeRoundedIcon from '@mui/icons-material/HomeRounded';
21
+ import DashboardRoundedIcon from '@mui/icons-material/DashboardRounded';
22
+ import CollectionsBookmarkRoundedIcon from '@mui/icons-material/CollectionsBookmarkRounded';
23
+ import AssignmentRoundedIcon from '@mui/icons-material/AssignmentRounded';
24
+ import QuestionAnswerRoundedIcon from '@mui/icons-material/QuestionAnswerRounded';
25
+ import GroupRoundedIcon from '@mui/icons-material/GroupRounded';
26
+ import SupportRoundedIcon from '@mui/icons-material/SupportRounded';
27
+ import SettingsRoundedIcon from '@mui/icons-material/SettingsRounded';
28
+ import CloseRoundedIcon from '@mui/icons-material/CloseRounded';
29
+ import LogoutRoundedIcon from '@mui/icons-material/LogoutRounded';
30
+ import BadgeRoundedIcon from '@mui/icons-material/BadgeRounded';
31
+ import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
32
+
33
+ import ColorSchemeToggle from './ColorSchemeToggle';
34
+ import { closeSidebar } from '../utils';
35
+
36
+ function Toggler({
37
+ defaultExpanded = false,
38
+ renderToggle,
39
+ children,
40
+ }: {
41
+ defaultExpanded?: boolean;
42
+ children: React.ReactNode;
43
+ renderToggle: (params: {
44
+ open: boolean;
45
+ setOpen: React.Dispatch<React.SetStateAction<boolean>>;
46
+ }) => React.ReactNode;
47
+ }) {
48
+ const [open, setOpen] = React.useState(defaultExpanded);
49
+ return (
50
+ <React.Fragment>
51
+ {renderToggle({ open, setOpen })}
52
+ <Box
53
+ sx={{
54
+ display: 'grid',
55
+ gridTemplateRows: open ? '1fr' : '0fr',
56
+ transition: '0.2s ease',
57
+ '& > *': {
58
+ overflow: 'hidden',
59
+ },
60
+ }}
61
+ >
62
+ {children}
63
+ </Box>
64
+ </React.Fragment>
65
+ );
66
+ }
67
+
68
+ export default function Sidebar() {
69
+ return (
70
+ <Sheet
71
+ className="Sidebar"
72
+ sx={{
73
+ position: {
74
+ xs: 'fixed',
75
+ md: 'sticky',
76
+ },
77
+ transform: {
78
+ xs: 'translateX(calc(100% * (var(--SideNavigation-slideIn, 0) - 1)))',
79
+ md: 'none',
80
+ },
81
+ transition: 'transform 0.4s, width 0.4s',
82
+ zIndex: 10000,
83
+ height: '100dvh',
84
+ width: 'var(--Sidebar-width)',
85
+ top: 0,
86
+ p: 1.5,
87
+ py: 2,
88
+ flexShrink: 0,
89
+ display: 'flex',
90
+ flexDirection: 'column',
91
+ gap: 2,
92
+ borderRight: '1px solid',
93
+ borderColor: 'divider',
94
+ }}
95
+ >
96
+ <GlobalStyles
97
+ styles={(theme) => ({
98
+ ':root': {
99
+ '--Sidebar-width': '220px',
100
+ [theme.breakpoints.up('lg')]: {
101
+ '--Sidebar-width': '240px',
102
+ },
103
+ },
104
+ })}
105
+ />
106
+ <Box
107
+ className="Sidebar-overlay"
108
+ sx={{
109
+ position: 'fixed',
110
+ zIndex: 9998,
111
+ top: 0,
112
+ left: 0,
113
+ width: '100vw',
114
+ height: '100vh',
115
+ opacity: 'var(--SideNavigation-slideIn)',
116
+ backgroundColor: 'var(--joy-palette-background-backdrop)',
117
+ transition: 'opacity 0.4s',
118
+ transform: {
119
+ xs: 'translateX(calc(100% * (var(--SideNavigation-slideIn, 0) - 1) + var(--SideNavigation-slideIn, 0) * var(--Sidebar-width, 0px)))',
120
+ lg: 'translateX(-100%)',
121
+ },
122
+ }}
123
+ onClick={() => closeSidebar()}
124
+ />
125
+ <Box sx={{ display: 'flex', gap: 1, alignItems: 'center' }}>
126
+ <IconButton variant="soft" color="primary" size="sm">
127
+ <BadgeRoundedIcon />
128
+ </IconButton>
129
+ <Typography level="title-lg">Profiles</Typography>
130
+ <ColorSchemeToggle sx={{ ml: 'auto' }} />
131
+ </Box>
132
+ <Input size="sm" startDecorator={<SearchRoundedIcon />} placeholder="Search" />
133
+ <Box
134
+ sx={{
135
+ minHeight: 0,
136
+ overflow: 'hidden auto',
137
+ flexGrow: 1,
138
+ display: 'flex',
139
+ flexDirection: 'column',
140
+ [`& .${listItemButtonClasses.root}`]: {
141
+ gap: 1.5,
142
+ },
143
+ }}
144
+ >
145
+ <List
146
+ size="sm"
147
+ sx={{
148
+ gap: 1,
149
+ '--List-nestedInsetStart': '30px',
150
+ '--ListItem-radius': (theme) => theme.vars.radius.sm,
151
+ }}
152
+ >
153
+ <ListItem>
154
+ <ListItemButton>
155
+ <HomeRoundedIcon />
156
+ <ListItemContent>
157
+ <Typography level="title-sm">Home</Typography>
158
+ </ListItemContent>
159
+ </ListItemButton>
160
+ </ListItem>
161
+
162
+ <ListItem>
163
+ <ListItemButton>
164
+ <DashboardRoundedIcon />
165
+ <ListItemContent>
166
+ <Typography level="title-sm">Dashboard</Typography>
167
+ </ListItemContent>
168
+ </ListItemButton>
169
+ </ListItem>
170
+
171
+ <ListItem>
172
+ <ListItemButton>
173
+ <CollectionsBookmarkRoundedIcon />
174
+ <ListItemContent>
175
+ <Typography level="title-sm">Projects</Typography>
176
+ </ListItemContent>
177
+ </ListItemButton>
178
+ </ListItem>
179
+
180
+ <ListItem nested>
181
+ <Toggler
182
+ renderToggle={({ open, setOpen }) => (
183
+ <ListItemButton onClick={() => setOpen(!open)}>
184
+ <AssignmentRoundedIcon />
185
+ <ListItemContent>
186
+ <Typography level="title-sm">Tasks</Typography>
187
+ </ListItemContent>
188
+ <KeyboardArrowDownIcon
189
+ sx={{ transform: open ? 'rotate(180deg)' : 'none' }}
190
+ />
191
+ </ListItemButton>
192
+ )}
193
+ >
194
+ <List sx={{ gap: 0.5 }}>
195
+ <ListItem sx={{ mt: 0.5 }}>
196
+ <ListItemButton>All tasks</ListItemButton>
197
+ </ListItem>
198
+ <ListItem>
199
+ <ListItemButton>Backlog</ListItemButton>
200
+ </ListItem>
201
+ <ListItem>
202
+ <ListItemButton>In progress</ListItemButton>
203
+ </ListItem>
204
+ <ListItem>
205
+ <ListItemButton>Done</ListItemButton>
206
+ </ListItem>
207
+ </List>
208
+ </Toggler>
209
+ </ListItem>
210
+
211
+ <ListItem>
212
+ <ListItemButton selected>
213
+ <QuestionAnswerRoundedIcon />
214
+ <ListItemContent>
215
+ <Typography level="title-sm">Messages</Typography>
216
+ </ListItemContent>
217
+ <Chip size="sm" color="primary" variant="solid">
218
+ 4
219
+ </Chip>
220
+ </ListItemButton>
221
+ </ListItem>
222
+
223
+ <ListItem nested>
224
+ <Toggler
225
+ renderToggle={({ open, setOpen }) => (
226
+ <ListItemButton onClick={() => setOpen(!open)}>
227
+ <GroupRoundedIcon />
228
+ <ListItemContent>
229
+ <Typography level="title-sm">Users</Typography>
230
+ </ListItemContent>
231
+ <KeyboardArrowDownIcon
232
+ sx={{ transform: open ? 'rotate(180deg)' : 'none' }}
233
+ />
234
+ </ListItemButton>
235
+ )}
236
+ >
237
+ <List sx={{ gap: 0.5 }}>
238
+ <ListItem sx={{ mt: 0.5 }}>
239
+ <ListItemButton
240
+ role="menuitem"
241
+ component="a"
242
+ href="/joy-ui/getting-started/templates/profile-dashboard/"
243
+ >
244
+ My profile
245
+ </ListItemButton>
246
+ </ListItem>
247
+ <ListItem>
248
+ <ListItemButton>Create a new user</ListItemButton>
249
+ </ListItem>
250
+ <ListItem>
251
+ <ListItemButton>Roles & permission</ListItemButton>
252
+ </ListItem>
253
+ </List>
254
+ </Toggler>
255
+ </ListItem>
256
+ </List>
257
+
258
+ <List
259
+ size="sm"
260
+ sx={{
261
+ mt: 'auto',
262
+ flexGrow: 0,
263
+ '--ListItem-radius': (theme) => theme.vars.radius.sm,
264
+ '--List-gap': '8px',
265
+ mb: 2,
266
+ }}
267
+ >
268
+ <ListItem>
269
+ <ListItemButton>
270
+ <SupportRoundedIcon />
271
+ Support
272
+ </ListItemButton>
273
+ </ListItem>
274
+ <ListItem>
275
+ <ListItemButton>
276
+ <SettingsRoundedIcon />
277
+ Settings
278
+ </ListItemButton>
279
+ </ListItem>
280
+ </List>
281
+ <Card
282
+ invertedColors
283
+ variant="soft"
284
+ color="warning"
285
+ size="sm"
286
+ sx={{ boxShadow: 'none' }}
287
+ >
288
+ <Stack direction="row" justifyContent="space-between" alignItems="center">
289
+ <Typography level="title-sm">Used space</Typography>
290
+ <IconButton size="sm">
291
+ <CloseRoundedIcon />
292
+ </IconButton>
293
+ </Stack>
294
+ <Typography level="body-xs">
295
+ Your team has used 80% of your available space. Need more?
296
+ </Typography>
297
+ <LinearProgress variant="outlined" value={80} determinate sx={{ my: 1 }} />
298
+ <Button size="sm" variant="solid">
299
+ Upgrade plan
300
+ </Button>
301
+ </Card>
302
+ </Box>
303
+ <Divider />
304
+ <Box sx={{ display: 'flex', gap: 1, alignItems: 'center' }}>
305
+ <Avatar
306
+ variant="outlined"
307
+ size="sm"
308
+ src="https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?auto=format&fit=crop&w=286"
309
+ />
310
+ <Box sx={{ minWidth: 0, flex: 1 }}>
311
+ <Typography level="title-sm">Siriwat K.</Typography>
312
+ <Typography level="body-xs">siriwatk@test.com</Typography>
313
+ </Box>
314
+ <IconButton size="sm" variant="plain" color="neutral">
315
+ <LogoutRoundedIcon />
316
+ </IconButton>
317
+ </Box>
318
+ </Sheet>
319
+ );
320
+ }
@@ -0,0 +1,52 @@
1
+ // In production, we register a service worker to serve assets from local cache.
2
+
3
+ // This lets the app load faster on subsequent visits in production, and gives
4
+ // it offline capabilities. However, it also means that developers (and users)
5
+ // will only see deployed updates on the "N+1" visit to a page, since previously
6
+ // cached resources are updated in the background.
7
+
8
+ // To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
9
+ // This link also includes instructions on opting out of this behavior.
10
+
11
+ export default function register() {
12
+ if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
13
+ window.addEventListener('load', () => {
14
+ const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
15
+ navigator.serviceWorker
16
+ .register(swUrl)
17
+ .then(registration => {
18
+ // eslint-disable-next-line no-param-reassign
19
+ registration.onupdatefound = () => {
20
+ const installingWorker = registration.installing;
21
+ installingWorker.onstatechange = () => {
22
+ if (installingWorker.state === 'installed') {
23
+ if (navigator.serviceWorker.controller) {
24
+ // At this point, the old content will have been purged and
25
+ // the fresh content will have been added to the cache.
26
+ // It's the perfect time to display a "New content is
27
+ // available; please refresh." message in your web app.
28
+ console.log('New content is available; please refresh.'); // eslint-disable-line no-console
29
+ } else {
30
+ // At this point, everything has been precached.
31
+ // It's the perfect time to display a
32
+ // "Content is cached for offline use." message.
33
+ console.log('Content is cached for offline use.'); // eslint-disable-line no-console
34
+ }
35
+ }
36
+ };
37
+ };
38
+ })
39
+ .catch(error => {
40
+ console.error('Error during service worker registration:', error);
41
+ });
42
+ });
43
+ }
44
+ }
45
+
46
+ export function unregister() {
47
+ if ('serviceWorker' in navigator) {
48
+ navigator.serviceWorker.ready.then(registration => {
49
+ registration.unregister();
50
+ });
51
+ }
52
+ }