|
| 1 | +import { Box, Text } from "ink" |
| 2 | +import { useReducer } from "react" |
| 3 | +import { Select } from "../../components/select" |
| 4 | +import { Badge, EmailInput, Spinner } from '@inkjs/ui'; |
| 5 | + |
| 6 | +import { registerAction, type Event } from "../../../actions/register" |
| 7 | +import Link from "ink-link"; |
| 8 | +import { useQuery, useZero } from "@rocicorp/zero/react"; |
| 9 | +import { schema } from "@lib/zero-sync/schema"; |
| 10 | +import { colors } from "../../theme"; |
| 11 | +import { initialState, reducer, toDate } from "./core"; |
| 12 | +import { ATW_BASEURL } from "../../../config"; |
| 13 | + |
| 14 | +type RegisterJourneyProps = { |
| 15 | + unmount: () => void |
| 16 | +} |
| 17 | + |
| 18 | +export const RegisterJourney = ({ unmount }: RegisterJourneyProps) => { |
| 19 | + const z = useZero<typeof schema>(); |
| 20 | + const [events] = useQuery(z.query.events.where('startDate', '>', (new Date()).getTime()).orderBy('startDate', 'desc').limit(10)) |
| 21 | + const [state, dispatch] = useReducer(reducer, initialState); |
| 22 | + const { event, hasSucceeded, isSubmitting, error } = state |
| 23 | + const isLoading = events.length <= 0 |
| 24 | + return <Box flexDirection="column" padding={1}> |
| 25 | + {isLoading && <Spinner type='aesthetic' label="Loading events..." />} |
| 26 | + {!event && !isLoading && <Text>Here is the list of the upcomping events:</Text>} |
| 27 | + {!event && <Select<Event> options={events.map((event) => { |
| 28 | + const link = `${ATW_BASEURL}/${event.slug}` |
| 29 | + return { |
| 30 | + label: event.name, |
| 31 | + value: event, |
| 32 | + render: (label, value, isSelected) => <Box> |
| 33 | + <Box flexDirection="column"> |
| 34 | + <Text bold={isSelected} color={isSelected ? colors.mainPurple : undefined} dimColor={!isSelected}>{label}</Text> |
| 35 | + <Text dimColor={!isSelected}>{toDate(event.startDate)} - {value.shortLocation}</Text> |
| 36 | + <Link url={link}> |
| 37 | + <Text color={colors.mainBlue} dimColor={!isSelected}>{link}</Text> |
| 38 | + </Link> |
| 39 | + </Box> |
| 40 | + </Box> |
| 41 | + } |
| 42 | + })} onSelect={(event) => { |
| 43 | + dispatch({ type: 'SELECT_EVENT', event }) |
| 44 | + }} />} |
| 45 | + |
| 46 | + {event && <Box flexDirection="column" padding={1} gap={1}> |
| 47 | + <Box flexDirection="column"> |
| 48 | + <Text bold color={colors.mainPurple}>{event.name}</Text> |
| 49 | + <Text>{toDate(event.startDate)} - {event.shortLocation}</Text> |
| 50 | + <Link url={`${ATW_BASEURL}/${event.slug}`}> |
| 51 | + <Text color={colors.mainBlue}>{`${ATW_BASEURL}/${event.slug}`}</Text> |
| 52 | + </Link> |
| 53 | + </Box> |
| 54 | + |
| 55 | + {hasSucceeded === null && !isSubmitting && <> |
| 56 | + <Text>To finalize registration, please enter your email address:</Text> |
| 57 | + <EmailInput |
| 58 | + domains={['gmail.com', 'yahoo.com', 'outlook.com', 'icloud.com', 'hotmail.com', 'protonmail.com']} |
| 59 | + placeholder="Your email..." |
| 60 | + onSubmit={async (email) => { |
| 61 | + dispatch({ type: 'SET_EMAIL', email }) |
| 62 | + const results = await registerAction(email, event.id) |
| 63 | + dispatch({ type: 'HANDLE_API_RESULTS', results }) |
| 64 | + setTimeout(() => { |
| 65 | + unmount() |
| 66 | + }, 2000) |
| 67 | + }} |
| 68 | + /> |
| 69 | + </>} |
| 70 | + </Box>} |
| 71 | + {isSubmitting && <Box flexDirection="row" gap={2} padding={2}> |
| 72 | + <Badge color="yellow">Registrating...</Badge><Text dimColor>{state.email}</Text><Spinner type='bouncingBall' label="Hang tight!" /> |
| 73 | + </Box>} |
| 74 | + {hasSucceeded === true && <Box flexDirection="row" gap={2} padding={2}> |
| 75 | + <Badge color="green">Registration Successful!</Badge><Spinner type='fingerDance' label="See you there" /><Text color={colors.mainOrange}>{state.email}</Text> |
| 76 | + </Box>} |
| 77 | + {hasSucceeded === false && <Box flexDirection="row" gap={2} padding={2}> |
| 78 | + <Badge color="red">Registration Failed!</Badge><Spinner type='monkey' label={error || 'Something went wrong!'} /> |
| 79 | + </Box>} |
| 80 | + </Box> |
| 81 | +} |
0 commit comments