Skip to content

Commit

Permalink
add check-in page (event and session)
Browse files Browse the repository at this point in the history
  • Loading branch information
takaishi committed May 3, 2024
1 parent 4863598 commit d03e9e9
Show file tree
Hide file tree
Showing 20 changed files with 403 additions and 5 deletions.
79 changes: 79 additions & 0 deletions src/components/CheckIn/CheckIn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React, { useEffect, useState } from 'react'
import { uuid4 } from '@sentry/utils'
import { ConfirmDialog } from './internal/ConfirmDialog'
import { DummyCheckInButton } from './internal/DummyCheckInButton/DummyCheckInButton'
import { Debug } from './internal/Debug/Debug'
import { DummyCamera } from './internal/DummyCamera'
import { Typography } from '@material-ui/core'

type CheckInType = 'event' | 'session'

type Props = {
checkInType: CheckInType
}

export const CheckIn: React.FC<Props> = ({ checkInType }) => {
const [storedKeys, setStoredKeys] = React.useState<string[]>([])
const storedKeysRef = React.useRef(storedKeys)
const [open, setOpen] = useState(false)
useEffect(() => {
storedKeysRef.current = storedKeys
}, [storedKeys])
useEffect(() => {
for (const key in localStorage) {
if (key.startsWith('check_in_')) {
setStoredKeys((prev) => (prev.includes(key) ? prev : [...prev, key]))
}
}

const interval = setInterval(() => {
console.log('Send check-in logs to dreamkast api:')
console.log(storedKeys)

for (const key of storedKeysRef.current) {
console.log(
`Success to send check-in log: key:L ${key}, value: ${JSON.stringify(
localStorage.getItem(key),
)}`,
)
deleteItem(key)
}
}, 10000)
return () => clearInterval(interval)
}, [])

const checkInConference = () => {
;(async () => {
const uuid = uuid4()
const key = `check_in_${uuid}`
const value = {
checkInType: checkInType,
profileId: 2,
checkInTimestamp: Math.floor(Date.now() / 1000),
}
localStorage.setItem(key, JSON.stringify(value))
setStoredKeys((prev) => [...prev, key])
})()
setOpen(true)
}

const handleClose = () => {
setOpen(false)
}

const deleteItem = (key: string) => {
localStorage.removeItem(key)
setStoredKeys(storedKeys.filter((k) => k !== key))
}

return (
<div>
{/*<Camera height={100} width={100} />*/}
<DummyCamera />
<DummyCheckInButton onClick={checkInConference} />
<ConfirmDialog open={open} handleClose={handleClose} />
<Typography variant="h5">↓Debug↓</Typography>
<Debug storedKeys={storedKeys} deleteItem={deleteItem} />
</div>
)
}
Empty file.
47 changes: 47 additions & 0 deletions src/components/CheckIn/internal/ConfirmDialog/ConfirmDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
IconButton,
} from '@material-ui/core'
import React from 'react'
import { CloseIcon } from 'next/dist/client/components/react-dev-overlay/internal/icons/CloseIcon'

type Props = {
open: boolean
handleClose: () => void
}

export const ConfirmDialog: React.FC<Props> = ({ open, handleClose }) => {
return (
<Dialog
open={open}
onClose={handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">
<IconButton
aria-label="close"
onClick={handleClose}
style={{ position: 'absolute', right: '8px', top: '8px' }}
>
<CloseIcon />
</IconButton>
</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
チェックインが完了しました。
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleClose} color="primary" autoFocus>
確認
</Button>
</DialogActions>
</Dialog>
)
}
1 change: 1 addition & 0 deletions src/components/CheckIn/internal/ConfirmDialog/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ConfirmDialog } from './ConfirmDialog'
46 changes: 46 additions & 0 deletions src/components/CheckIn/internal/Debug/Debug.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Button, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from '@material-ui/core'
import React from 'react'

type Props = {
storedKeys: string[]
deleteItem: (key: string) => void
}

export const Debug: React.FC<Props> = ({ storedKeys, deleteItem }) => {
return (
<TableContainer>
<Table>
<TableHead>
<TableRow>
<TableCell>type</TableCell>
<TableCell>profileId</TableCell>
</TableRow>
</TableHead>

<TableBody>
{storedKeys.map((key) => {
const value = localStorage.getItem(key)
if (value) {
const { checkInType, profileId } = JSON.parse(value)
return (
<TableRow key={key}>
<TableCell>{checkInType}</TableCell>
<TableCell>{profileId}</TableCell>
<TableCell>
<Button
type="submit"
onClick={() => deleteItem(key)}
variant="contained"
>
Delete
</Button>
</TableCell>
</TableRow>
)
}
})}
</TableBody>
</Table>
</TableContainer>
)
}
1 change: 1 addition & 0 deletions src/components/CheckIn/internal/Debug/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Debug } from './Debug'
10 changes: 10 additions & 0 deletions src/components/CheckIn/internal/DummyCamera/DummyCamera.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react'
import * as Styled from './styled'

export const DummyCamera: React.FC = () => {
return (
<Styled.DummyCamera>
実際にはスマートフォンで見た際ここにカメラ映像が映ります
</Styled.DummyCamera>
)
}
1 change: 1 addition & 0 deletions src/components/CheckIn/internal/DummyCamera/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { DummyCamera } from './DummyCamera'
16 changes: 16 additions & 0 deletions src/components/CheckIn/internal/DummyCamera/styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import styled from 'styled-components'

export const DummyCamera = styled.div`
width: 500px;
height: 500px;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
border: 1px solid #000; /* Optional, just to visualize the space */
//
@media (max-width: 600px) {
width: 90vw;
height: 90vw;
}
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react'
import { Button } from '@material-ui/core'

type Props = {
onClick: () => void
}

export const DummyCheckInButton: React.FC<Props> = ({onClick}) => {
return (
<Button type="submit" onClick={onClick} variant="contained">
イベントチェックイン用のダミーボタン
</Button>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { DummyCheckInButton } from './DummyCheckInButton'
Empty file.
4 changes: 3 additions & 1 deletion src/components/Layout/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ type Props = {
children?: ReactNode
title?: string
event?: Event
isAdminRole?: boolean
}

export const Layout: React.FC<Props> = ({
children,
title = 'This is the default title',
event,
isAdminRole,
}) => {
return (
<Styled.Container eventAbbr={event?.abbr}>
Expand All @@ -36,7 +38,7 @@ export const Layout: React.FC<Props> = ({
src={`/${event?.abbr}/ui/${event?.abbr}_header_logo.png`}
/>
</Link>
<MobileMenu event={event} />
<MobileMenu event={event} isAdminRole={isAdminRole} />
<DesktopMenu event={event} />
</Styled.Header>
</AppBar>
Expand Down
12 changes: 8 additions & 4 deletions src/components/Menu/MobileMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,20 @@ import MenuIcon from '@material-ui/icons/Menu'
import ScheduleIcon from '@material-ui/icons/Schedule'
import ViewStreamIcon from '@material-ui/icons/ViewStream'
import SendIcon from '@material-ui/icons/Send'
import { Drawer, List, ListItem, ListItemIcon } from '@material-ui/core'
import { Drawer, ListItem, ListItemIcon } from '@material-ui/core'
import Link from 'next/link'
import { useMenuContents } from './hooks'
import { useAuth0 } from '@auth0/auth0-react'
import { authSelector } from '../../store/auth'
import { useSelector } from 'react-redux'
import { AdminMobileMenu } from './internal/AdminMobileMenu/AdminMobileMenu'

type Props = {
event?: Event
isAdminRole?: boolean
}

export const MobileMenu: React.FC<Props> = ({ event }) => {
export const MobileMenu: React.FC<Props> = ({ event, isAdminRole }) => {
const { logout } = useAuth0()
const { dkUrl } = useSelector(authSelector)
const { guideUrl, isPreEvent } = useMenuContents()
Expand All @@ -46,7 +48,7 @@ export const MobileMenu: React.FC<Props> = ({ event }) => {
onClick={toggleDrawer(false)}
onKeyDown={toggleDrawer(false)}
>
<List>
<Styled.RootList>
<ListItem button key="info">
<ListItemIcon>
<ViewStreamIcon />
Expand Down Expand Up @@ -139,6 +141,8 @@ export const MobileMenu: React.FC<Props> = ({ event }) => {
</CommonStyled.MenuLink>
</ListItem>

{isAdminRole && <AdminMobileMenu event={event} />}

<ListItem button key="logout">
<ListItemIcon>
<ExitToAppIcon />
Expand All @@ -156,7 +160,7 @@ export const MobileMenu: React.FC<Props> = ({ event }) => {
Logout
</Button>
</ListItem>
</List>
</Styled.RootList>
</div>
)

Expand Down
48 changes: 48 additions & 0 deletions src/components/Menu/internal/AdminMobileMenu/AdminMobileMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react'
import { Button, ListItem, ListItemIcon, ListItemText } from '@material-ui/core'
import CheckIcon from '@material-ui/icons/Check'
import KeyboardArrowRightIcon from '@material-ui/icons/KeyboardArrowRight'
import * as Styled from './styled'
import * as CommonStyled from '../../../../styles/styled'
import { Event } from '../../../../generated/dreamkast-api.generated'

type Props = {
event?: Event
}

export const AdminMobileMenu: React.FC<Props> = ({ event }) => {
return (
<div>
<ListItem button>
<ListItemIcon>
<KeyboardArrowRightIcon />
</ListItemIcon>
<ListItemText primary="Admin" />
</ListItem>

<Styled.NestedListItem button key="check_in_event">
<ListItemIcon>
<CheckIcon />
</ListItemIcon>
<CommonStyled.MenuLink
href={`/${event?.abbr}/ui/admin/check_in_event`}
rel="noreferrer noopener"
>
<Button style={{ color: '#423A57' }}>Check-In (Event)</Button>
</CommonStyled.MenuLink>
</Styled.NestedListItem>

<Styled.NestedListItem button key="check_in_session">
<ListItemIcon>
<CheckIcon />
</ListItemIcon>
<CommonStyled.MenuLink
href={`/${event?.abbr}/ui/admin/check_in_session`}
rel="noreferrer noopener"
>
<Button style={{ color: '#423A57' }}>Check-In (Session)</Button>
</CommonStyled.MenuLink>
</Styled.NestedListItem>
</div>
)
}
1 change: 1 addition & 0 deletions src/components/Menu/internal/AdminMobileMenu/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { AdminMobileMenu } from './AdminMobileMenu'
6 changes: 6 additions & 0 deletions src/components/Menu/internal/AdminMobileMenu/styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { ListItem } from '@material-ui/core'
import styled from 'styled-components'

export const NestedListItem = styled(ListItem)`
padding-left: ${(props) => `${props.theme.spacing(4)}px`};
`
7 changes: 7 additions & 0 deletions src/components/Menu/styled.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import styled from 'styled-components'
import Toolbar from '@material-ui/core/Toolbar'
import { List } from '@material-ui/core'

export const Container = styled.div`
background: rgba(255, 255, 255, 0.6);
Expand Down Expand Up @@ -61,3 +62,9 @@ export const MobileMenu = styled.div`
background-color: #fff;
}
`

export const RootList = styled(List)`
width: 100%;
max-width: 360px;
background-color: ${(props) => props.theme.palette.background.paper};
`;
Loading

0 comments on commit d03e9e9

Please sign in to comment.