Skip to content

Commit

Permalink
pair programming updates
Browse files Browse the repository at this point in the history
  • Loading branch information
JoeKarow committed Aug 3, 2023
1 parent 238b1a8 commit e14d508
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 115 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { fieldOpt } from '~ui/mockData/fieldOpt'
import { geoMocks } from '~ui/mockData/geo'
import { location } from '~ui/mockData/location'
import { organization } from '~ui/mockData/organization'
import { orgHours } from '~ui/mockData/orgHours'
import { service } from '~ui/mockData/orgService'

import { HoursDrawer } from './HoursDrawer'
Expand Down Expand Up @@ -37,6 +38,7 @@ export default {
type: 'mutation',
response: { id: 'oloc_00000RECORD22ID' },
}),
orgHours.forHoursDrawer,
],
},
args: {
Expand Down
219 changes: 104 additions & 115 deletions packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,22 @@ import {
UnstyledButton,

Check warning on line 15 in packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx

View check run for this annotation

InReachBot / Check Code for Errors

packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx#L15

[@typescript-eslint/no-unused-vars] 'UnstyledButton' is defined but never used. Allowed unused vars must match /^_/u.
} from '@mantine/core'
import { TimeInput } from '@mantine/dates'
import { zodResolver } from '@mantine/form'
import { useDebouncedValue, useDisclosure } from '@mantine/hooks'
import { Form, useForm, zodResolver } from '@mantine/form'

Check warning on line 18 in packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx

View check run for this annotation

InReachBot / Check Code for Errors

packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx#L18

[@typescript-eslint/no-unused-vars] 'Form' is defined but never used. Allowed unused vars must match /^_/u.
import { useDebouncedValue, useDisclosure, useListState } from '@mantine/hooks'

Check warning on line 19 in packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx

View check run for this annotation

InReachBot / Check Code for Errors

packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx#L19

[@typescript-eslint/no-unused-vars] 'useDebouncedValue' is defined but never used. Allowed unused vars must match /^_/u.

Check warning on line 19 in packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx

View check run for this annotation

InReachBot / Check Code for Errors

packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx#L19

[@typescript-eslint/no-unused-vars] 'useListState' is defined but never used. Allowed unused vars must match /^_/u.
import { DateTime, Interval } from 'luxon'

Check warning on line 20 in packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx

View check run for this annotation

InReachBot / Check Code for Errors

packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx#L20

[@typescript-eslint/no-unused-vars] 'DateTime' is defined but never used. Allowed unused vars must match /^_/u.

Check warning on line 20 in packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx

View check run for this annotation

InReachBot / Check Code for Errors

packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx#L20

[@typescript-eslint/no-unused-vars] 'Interval' is defined but never used. Allowed unused vars must match /^_/u.
import { type ComponentPropsWithRef, forwardRef, useEffect, useState } from 'react'
import { type ComponentPropsWithRef, forwardRef, type ReactNode, useEffect, useMemo, useState } from 'react'

Check warning on line 21 in packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx

View check run for this annotation

InReachBot / Check Code for Errors

packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx#L21

[@typescript-eslint/no-unused-vars] 'ComponentPropsWithRef' is defined but never used. Allowed unused vars must match /^_/u.

Check warning on line 21 in packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx

View check run for this annotation

InReachBot / Check Code for Errors

packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx#L21

[@typescript-eslint/no-unused-vars] 'useEffect' is defined but never used. Allowed unused vars must match /^_/u.

Check warning on line 21 in packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx

View check run for this annotation

InReachBot / Check Code for Errors

packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx#L21

[@typescript-eslint/no-unused-vars] 'useMemo' is defined but never used. Allowed unused vars must match /^_/u.
import timezones from 'timezones-list'
import { z } from 'zod'

import { type ApiOutput } from '@weareinreach/api'

Check warning on line 25 in packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx

View check run for this annotation

InReachBot / Check Code for Errors

packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx#L25

[@typescript-eslint/no-unused-vars] 'ApiOutput' is defined but never used. Allowed unused vars must match /^_/u.
import { generateId } from '@weareinreach/db/lib/idGen'
import { Breadcrumb } from '~ui/components/core/Breadcrumb'
import { Button } from '~ui/components/core/Button'
import { useCustomVariant } from '~ui/hooks/useCustomVariant'
import { Icon } from '~ui/icon'
import { trpc as api } from '~ui/lib/trpcClient'

import { HoursDrawerFormProvider, useForm } from './HoursDrawerContext'
// import { HoursDrawerFormProvider, useForm } from './HoursDrawerContext'

const useStyles = createStyles((theme) => ({
drawerContent: {
Expand All @@ -53,17 +54,27 @@ const useStyles = createStyles((theme) => ({
},
}))

const FormSchema = z.object({
data: z
.object({
dayIndex: z.coerce.number().nullable(),
start: z.coerce.date().nullable(),
end: z.coerce.date().nullable(),
close: z.coerce.boolean().nullable(),
tz: z.string().nullable(),
})
.partial(),
})
const FormSchema = z
.object({
data: z
.object({
id: z.string().optional(),
dayIndex: z.coerce.number(),
start: z
.string({ required_error: 'Start time is required', invalid_type_error: 'Invalid entry' })
.length(5),
end: z
.string({ required_error: 'End time is required', invalid_type_error: 'Invalid entry' })
.length(5),
closed: z.coerce.boolean(),
tz: z.string().nullable(),
delete: z.boolean().optional(),
})
.array(),
})
.superRefine((val, ctx) => {
// https://zod.dev/?id=superrefine
})

const schemaTransform = ({ id, data }: FormSchema) => ({

Check warning on line 79 in packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx

View check run for this annotation

InReachBot / Check Code for Errors

packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx#L79

[@typescript-eslint/no-unused-vars] 'schemaTransform' is assigned a value but never used. Allowed unused vars must match /^_/u.
id,
Expand Down Expand Up @@ -103,16 +114,19 @@ const sortedTimezoneData = timezoneData.sort((a, b) => {
})

const _HoursDrawer = forwardRef<HTMLButtonElement, HoursDrawerProps>(({ locationId, ...props }, ref) => {
const [opened, handler] = useDisclosure(false)
const [opened, handler] = useDisclosure(true) //TODO: Change back to 'false' when done.
const [isSaved, setIsSaved] = useState(false)

Check warning on line 118 in packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx

View check run for this annotation

InReachBot / Check Code for Errors

packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx#L118

[@typescript-eslint/no-unused-vars] 'setIsSaved' is assigned a value but never used. Allowed unused vars must match /^_/u.
const form = useForm<FormSchema>({
const form = useForm<z.infer<typeof FormSchema>>({
validate: zodResolver(FormSchema),
initialValues: { data: [] },
transformValues: FormSchema.transform(schemaTransform).parse,
initialValues: {
data: [],
},
})
const [tzValue, setTzValue] = useState<string | null>(null)
const { classes } = useStyles()
const variants = useCustomVariant()

/** Remove this */
const [checked, setChecked] = useState<{ [key: number]: boolean }>({

Check warning on line 130 in packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx

View check run for this annotation

InReachBot / Check Code for Errors

packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx#L130

[@typescript-eslint/no-unused-vars] 'checked' is assigned a value but never used. Allowed unused vars must match /^_/u.

Check warning on line 130 in packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx

View check run for this annotation

InReachBot / Check Code for Errors

packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx#L130

[@typescript-eslint/no-unused-vars] 'setChecked' is assigned a value but never used. Allowed unused vars must match /^_/u.
0: false, // Sunday
1: false, // Monday
Expand All @@ -122,6 +136,7 @@ const _HoursDrawer = forwardRef<HTMLButtonElement, HoursDrawerProps>(({ location
5: false, // Friday
6: false, // Saturday
})
/** Remove this */
const [timeValues, setTimeValues] = useState<{

Check warning on line 140 in packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx

View check run for this annotation

InReachBot / Check Code for Errors

packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx#L140

[@typescript-eslint/no-unused-vars] 'setTimeValues' is assigned a value but never used. Allowed unused vars must match /^_/u.
[key: number]: { start: Date | null; end: Date | null }
}>({
Expand All @@ -133,117 +148,76 @@ const _HoursDrawer = forwardRef<HTMLButtonElement, HoursDrawerProps>(({ location
5: { start: null, end: null }, // Friday
6: { start: null, end: null }, // Saturday
})
console.log(timeValues)
const handleUpdate = () => {
//TODO save to DB instead of sending to console.log
const data = generateDataArray()
console.log(data)
}

const TimeRangeComponent = (title: string, dayIndex: number) => {
const [timeRangeGroups, setTimeRangeGroups] = useState<JSX.Element[]>([]) // Define the type for state variable

const handleCheckboxChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const { checked } = event.currentTarget
//data comes back here
const { data: initialData } = api.orgHours.forHoursDrawer.useQuery(locationId ?? '', {

Check warning on line 153 in packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx

View check run for this annotation

InReachBot / Check Code for Errors

packages/ui/components/data-portal/HoursDrawer/HoursDrawer.tsx#L153

[@typescript-eslint/no-unused-vars] 'initialData' is assigned a value but never used. Allowed unused vars must match /^_/u.
onSuccess: (data) => form.setValues({ data }),
})
console.log('form values', form.values)

setChecked((prevChecked) => {
if (checked) {
setTimeRangeGroups([])
setTimeValues((prevTimeValues) => ({
...prevTimeValues,
[dayIndex]: {
start: DateTime.fromMillis(0).toUTC().toISO(), // Set start time to 1970-01-01T00:00:00.000Z
end: DateTime.fromObject(
{ year: 1970, month: 1, day: 1, hour: 23, minute: 59, second: 59, millisecond: 0 },
{ zone: 'utc' }
).toISO(), // Set end time to 1970-01-01T23:59:59.000Z
},
}))
}
// Docs: https://mantine.dev/form/nested/

return {
...prevChecked,
[dayIndex]: checked,
}
})
}
const handleUpdate = () => {
//TODO save to DB instead of sending to console.log
// const data = generateDataArray()
console.log('clicked save', form.isValid(), form.errors)
}

const handleAddTimeRangeGroup = () => {
// Add a new time range group to the state
setTimeRangeGroups((prevTimeRangeGroups) => [
...prevTimeRangeGroups,
<Group key={prevTimeRangeGroups.length}>
const TimeRangeComponent = ({ arrayIdx }: { arrayIdx: number }) => {
return (
<Stack>
<Group>
<TimeInput
label='Open time'
ref={ref}
maw={200}
mx='auto'
disabled={isCheckboxChecked}
onChange={(event) => handleTimeChange(event, dayIndex, 'start')}
name='start'
{...form.getInputProps(`data.${arrayIdx}.start`)}
onFocus={undefined}
/>
<TimeInput
label='Close time'
ref={ref}
maw={200}
mx='auto'
disabled={isCheckboxChecked}
onChange={(event) => handleTimeChange(event, dayIndex, 'end')}
name='end'
{...form.getInputProps(`data.${arrayIdx}.end`)}
onFocus={undefined}
/>
</Group>,
])
}

const handleTimeChange = (
event: React.ChangeEvent<HTMLInputElement>,
dayIndex: number,
timeType: 'start' | 'end'
) => {
const { name, value } = event.currentTarget
const [hours, minutes] = value.split(':')

const date = new Date(1970, 0, 1, parseInt(hours, 10), parseInt(minutes, 10))

setTimeValues((prevTimeValues) => ({
...prevTimeValues,
[dayIndex]: {
...prevTimeValues[dayIndex],
[name]: date,
},
}))
</Group>
<Button onClick={() => form.setFieldValue(`data.${arrayIdx}.delete`, true)}>Delete</Button>
</Stack>
)
}
const DayWrap = ({ dayIndex, children }: { dayIndex: number; children: ReactNode }) => {
const days = {
0: 'Sunday',
1: 'Monday',
2: 'Tuesday',
3: 'Wednesday',
4: 'Thursday',
5: 'Friday',
6: 'Saturday',
}

const isCheckboxChecked = checked[dayIndex]

return (
<Stack>
<Group position='apart'>
<Title order={3}>{title}</Title>
<Checkbox checked={isCheckboxChecked} onChange={handleCheckboxChange} label='Open 24 Hours' />
<Title order={3}>{days[dayIndex.toString()] ?? ''}</Title>
<Checkbox label='Open 24 Hours' />
</Group>
<Group>
<TimeInput
label='Open time'
ref={ref}
maw={200}
mx='auto'
disabled={isCheckboxChecked}
onChange={(event) => handleTimeChange(event, dayIndex, 'start')}
name='start'
/>
<TimeInput
label='Close time'
ref={ref}
maw={200}
mx='auto'
disabled={isCheckboxChecked}
onChange={(event) => handleTimeChange(event, dayIndex, 'end')}
name='end'
/>
</Group>
{timeRangeGroups} {/* Render the dynamically added HTML when button is clicked*/}
<Button variant='secondary' onClick={handleAddTimeRangeGroup} disabled={isCheckboxChecked}>
{children}
<Button
variant='secondary'
onClick={() =>
form.insertListItem('data', {
dayIndex,
closed: false,
id: generateId('orgHours'),
start: '',
end: '',
})
}
>
<Group noWrap spacing={8}>
<Icon icon='carbon:add' className={classes.addNewText} height={24} />
<Text variant={variants.Text.utility2} className={classes.addNewText}>
Expand All @@ -257,6 +231,21 @@ const _HoursDrawer = forwardRef<HTMLButtonElement, HoursDrawerProps>(({ location
)
}

const dayRender: Record<string, JSX.Element[]> = {
0: [],
1: [],
2: [],
3: [],
4: [],
5: [],
6: [],
}

form.values.data.forEach((item, idx) => {
if (item.delete || !dayRender[item.dayIndex.toString()]) return
dayRender[item.dayIndex.toString()]?.push(<TimeRangeComponent arrayIdx={idx} key={item.id ?? idx} />)
})

const convertTimeToUTC = (timeInput, timezone) => {
return timeInput
}
Expand Down Expand Up @@ -312,13 +301,13 @@ const _HoursDrawer = forwardRef<HTMLButtonElement, HoursDrawerProps>(({ location
/>
<Divider my='sm' />
</Stack>
{TimeRangeComponent('Sunday', 0)}
{TimeRangeComponent('Monday', 1)}
{TimeRangeComponent('Tuesday', 2)}
{TimeRangeComponent('Wednesday', 3)}
{TimeRangeComponent('Thursday', 4)}
{TimeRangeComponent('Friday', 5)}
{TimeRangeComponent('Saturday', 6)}
<form>
{Object.entries(dayRender).map(([dayIndex, children]) => (
<DayWrap key={dayIndex} dayIndex={parseInt(dayIndex)}>
{children}
</DayWrap>
))}
</form>
</Drawer.Body>
</Drawer.Content>
</Drawer.Root>
Expand Down

0 comments on commit e14d508

Please sign in to comment.