Skip to content

Commit

Permalink
Add data logic related tags
Browse files Browse the repository at this point in the history
  • Loading branch information
kanatagu committed Jan 30, 2024
1 parent 2a1becc commit 0cbf271
Show file tree
Hide file tree
Showing 24 changed files with 1,186 additions and 147 deletions.
106 changes: 106 additions & 0 deletions app/components/date/custom-date-picker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import DatePicker from 'react-datepicker'
import { Box, useColorMode } from '@chakra-ui/react'
import { FiCalendar } from 'react-icons/fi'
import 'react-datepicker/dist/react-datepicker.css'
import { InputForm } from '@/components/input'

type DatePickerProps = {
selectedDate: Date | null
onChange: (date: Date) => void
placeholderText: string
dateFormat?: string | string[] | undefined
}

export const CustomDatePicker = ({
selectedDate,
onChange,
placeholderText,
dateFormat
}: DatePickerProps) => {
const { colorMode } = useColorMode()

const datePickerStyles = {
'.react-datepicker-wrapper': {
width: '100%'
},
'.react-datepicker-popper': {
right: { base: 0, md: 'unset' }
},
'.react-datepicker ': {
width: '100%',
border: 'none',
boxShadow: '0px 2px 16px 0px rgba(0,0,0,.25);',
fontSize: 'sm'
},
'.react-datepicker__month-container': {
backgroundColor: colorMode === 'dark' ? 'gray.700' : 'white',
width: { base: '100%', md: '400px' }
},
'.react-datepicker__triangle': {
display: 'none'
},
'.react-datepicker__header': {
backgroundColor: colorMode === 'dark' ? 'gray.700' : 'white',
borderBottomColor: colorMode === 'dark' ? 'gray.500' : 'gray.300'
},
'.react-datepicker__current-month': {
color: colorMode === 'dark' ? 'primary.700' : 'primary.800',
paddingY: '8px',
fontSize: 'lg'
},
'.react-datepicker__navigation': {
top: '11px'
},
'.react-datepicker__navigation--previous': {
left: '32px'
},
'.react-datepicker__navigation--next': {
right: '32px'
},
'.react-datepicker__navigation-icon': {
'&::before': {
borderColor: colorMode === 'dark' ? 'gray.500' : 'gray.400'
}
},
'.react-datepicker__month': {
margin: '1rem'
},
'.react-datepicker__day-names': {
paddingY: '4px'
},
'.react-datepicker__day-name': {
width: { base: '2.4rem', md: '2.8rem' },
lineHeight: { base: '2.4rem', md: '2.8rem' },
color: colorMode === 'dark' ? 'gray.300' : 'black'
},
'.react-datepicker__day': {
width: { base: '2.4rem', md: '2.8rem' },
lineHeight: { base: '2.2rem', md: '2.4rem' },
':hover': {
backgroundColor: colorMode === 'dark' ? 'gray.600' : 'gray.100'
},
color: colorMode === 'dark' ? 'gray.300' : 'black'
},
'.react-datepicker__day--selected': {
fontWeight: 'bold',
color: 'white',
backgroundColor: colorMode === 'dark' ? 'primary.700' : 'primary.500'
},
'.react-datepicker__day--keyboard-selected': {
background: 'none'
}
}

return (
<Box sx={datePickerStyles}>
<DatePicker
selected={selectedDate}
placeholderText={placeholderText}
onChange={onChange}
dateFormat={dateFormat}
popperPlacement="bottom-start"
customInput={<InputForm rightIcon={FiCalendar} />}
/>
</Box>
)
}
1 change: 1 addition & 0 deletions app/components/date/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { CustomDatePicker } from './custom-date-picker'
2 changes: 1 addition & 1 deletion app/components/input/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export { InputForm } from './input-form'
export { InputIcon } from './input-icon'
export { InputIconButton } from './input-icon-button'
export { TextareaForm } from './textarea-form'
14 changes: 12 additions & 2 deletions app/components/input/input-form.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import { IconType } from 'react-icons'
import {
Input as ChakraFormInput,
InputProps as ChakraInputProps,
InputGroup,
InputRightElement,
forwardRef,
useColorModeValue
} from '@chakra-ui/react'

export const InputForm = forwardRef(
(props: ChakraInputProps, ref: React.Ref<HTMLInputElement>) => {
type InputFormProps = {
rightIcon?: IconType
}
export const InputForm = forwardRef<ChakraInputProps & InputFormProps, 'input'>(
({ rightIcon: RightIcon, ...props }, ref) => {
const bgColor = useColorModeValue('white', 'gray.700')
const borderColor = useColorModeValue('gray.300', 'gray.500')
const placeholdercolor = useColorModeValue('gray.400', 'gray.600')
Expand All @@ -24,6 +29,11 @@ export const InputForm = forwardRef(
color: placeholdercolor
}}
/>
{RightIcon && (
<InputRightElement color="gray.500">
<RightIcon />
</InputRightElement>
)}
</InputGroup>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import {
useColorModeValue
} from '@chakra-ui/react'

type InputIconProps = {
type InputIconButtonProps = {
ariaLabel: string
icon: IconType
onClick?: () => void
}

export const InputIcon = forwardRef<ChakraInputProps & InputIconProps, 'input'>(
export const InputIconButton = forwardRef<ChakraInputProps & InputIconButtonProps, 'input'>(
({ ariaLabel, icon: Icon, onClick, ...props }, ref) => {
const bgColor = useColorModeValue('white', 'gray.700')
const borderColor = useColorModeValue('primary.700', 'gray.500')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { Meta, StoryObj } from '@storybook/react'
import { FiSearch } from 'react-icons/fi'
import { InputIcon } from '@/components/input'
import { InputIconButton } from '@/components/input'

const meta: Meta<typeof InputIcon> = {
title: 'Input Icon',
component: InputIcon
const meta: Meta<typeof InputIconButton> = {
title: 'Input Icon Button',
component: InputIconButton
}
export default meta
type Story = StoryObj<typeof InputIcon>
type Story = StoryObj<typeof InputIconButton>

export const Default: Story = {
args: {
Expand Down
26 changes: 26 additions & 0 deletions app/libs/utils/date.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import { zonedTimeToUtc, toDate, utcToZonedTime, format } from 'date-fns-tz'

const TIMEZONE = 'Asia/Tokyo'

/**
* @param date - ISO date string e.g. '2023-01-01'
* @param type - 'dayMonthYear' | 'dayMonth'
Expand Down Expand Up @@ -54,3 +58,25 @@ export const formatToDateTime = (date: string | null | undefined) => {

return `${monthDay} ${hours}:${minutes}`
}

/**
*
* @param isoString - ISO date string
* @returns - Date Object ex. Mon Jan 01 2024 00:00:00 GMT-0800 (Pacific Standard Time)
*/
export const getDateObj = (isoString: string) => {
const parsedDate = toDate(isoString, { timeZone: TIMEZONE })
const dateObj = utcToZonedTime(parsedDate, TIMEZONE)
return dateObj
}

/**
* @param date - Date Object
* @returns - ISO date string with Tokyo timezone ex.2024-01-01T12:00:00+09:00
*/
export const formatToISODate = (date: Date) => {
const isoString = format(date, "yyyy-MM-dd'T'HH:mm:ssXXX", {
timeZone: TIMEZONE
})
return isoString
}
4 changes: 3 additions & 1 deletion app/libs/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@ export {
formatDateToSlash,
extractTimeFromDate,
formatDbTimeToDate,
formatToDateTime
formatToDateTime,
getDateObj,
formatToISODate
} from './date'
109 changes: 78 additions & 31 deletions app/trip/[id]/edit/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,36 @@ import { Loading } from '@/components/loading'
import { Header, Footer } from '@/components/navigation'
import { useUserId } from '@/providers/session-provider'
import { TripForm } from '../../components'
import { useTagsCollectionQuery, useTripDetailsQuery } from '@generated/api'
import {
useTagsCollectionQuery,
useTripDetailsQuery,
useTripTagsCollectionQuery
} from '@generated/api'

export default function TripEditPage({ params }: { params: { id: string } }) {
const bg = useColorModeValue('white', 'gray.800')
const color = useColorModeValue('black', 'gray.300')

const userId = useUserId()

const { data: tripData, loading: tripLoading } = useTripDetailsQuery({
const {
data: tripData,
loading: tripLoading,
refetch: tripRefetch,
networkStatus: tripNetWorkStatus
} = useTripDetailsQuery({
variables: {
id: params.id
}
},
notifyOnNetworkStatusChange: true
})

const tripDataCollection = tripData?.tripsCollection?.edges[0]?.node
const tripDetailsRefetch = () => {
tripRefetch()
}
const tripDetailsRefetchLoading = tripNetWorkStatus === NetworkStatus.refetch

const {
data: tagsData,
loading: tagsLoading,
Expand All @@ -30,17 +46,39 @@ export default function TripEditPage({ params }: { params: { id: string } }) {
notifyOnNetworkStatusChange: true
})

if ((!tripData && !tripLoading) || (!tagsData && !tagsLoading))
throw new Error('No trip data found')

const tripDataCollection = tripData?.tripsCollection?.edges[0]?.node

const tagsCollectionRefetch = () => {
tagsRefetch()
}

const tagsRefetchLoading = tagsNetWorkStatus === NetworkStatus.refetch

const {
data: tripTagsData,
refetch: tripTagsRefetch,
networkStatus: tripTagsNetWorkStatus
} = useTripTagsCollectionQuery({
variables: {
filter: {
trip_id: { eq: params.id }
}
},
notifyOnNetworkStatusChange: true
})

const tripsTagsDataArray = tripTagsData?.trip_tagsCollection?.edges.map(
(tag) => ({
id: tag.node.id,
tag_id: tag.node.tag_id || '',
trip_id: tag.node.trip_id || ''
})
)
const tripTagsCollectionRefetch = () => {
tripTagsRefetch()
}
const tripTagsRefetchLoading = tripTagsNetWorkStatus === NetworkStatus.refetch

if ((!tripData && !tripLoading) || (!tagsData && !tagsLoading))
throw new Error('No trip data found')

console.log('tripDataCollection', tripDataCollection)
console.log('tagsData', tagsData)

Expand All @@ -57,31 +95,40 @@ export default function TripEditPage({ params }: { params: { id: string } }) {
Edit Trip
</Heading>
<Box mt="40px">
{!tripDataCollection || tripLoading ? (
{!tripDataCollection || tripLoading || !tripsTagsDataArray ? (
<Loading />
) : (
<TripForm
id={tripDataCollection.id}
image={tripDataCollection.image_storage_object_id}
title={tripDataCollection.title}
dateFrom={tripDataCollection.date_from}
dateTo={tripDataCollection.date_to}
allTags={
tagsData?.tagsCollection?.edges.map((tag) => ({
id: tag.node.id,
name: tag.node.name
})) || []
}
checkedTags={
tripDataCollection.trip_tagsCollection?.edges.map((tag) => ({
id: tag.node.tags?.id || '',
name: tag.node.tags?.name || ''
})) || []
}
cost={tripDataCollection.cost}
costUnit={tripDataCollection.cost_unit}
tagsCollectionRefetch={tagsCollectionRefetch}
tagsRefetchLoading={tagsRefetchLoading}
tripDetails={{
id: tripDataCollection.id,
image: tripDataCollection.image_storage_object_id,
title: tripDataCollection.title,
dateFrom: tripDataCollection.date_from,
dateTo: tripDataCollection.date_to,
cost: tripDataCollection.cost,
costUnit: tripDataCollection.cost_unit,
refetch: tripDetailsRefetch,
refetchLoading: tripDetailsRefetchLoading
}}
tags={{
data:
tagsData?.tagsCollection?.edges.map((tag) => ({
id: tag.node.id,
name: tag.node.name
})) || [],
refetch: tagsCollectionRefetch,
refetchLoading: tagsRefetchLoading
}}
tripTags={{
data:
tripTagsData?.trip_tagsCollection?.edges.map((tripTag) => ({
id: tripTag.node.id,
tag_id: tripTag.node.tag_id || '',
trip_id: tripTag.node.trip_id || ''
})) || [],
refetch: tripTagsCollectionRefetch,
refetchLoading: tripTagsRefetchLoading
}}
/>
)}
</Box>
Expand Down
5 changes: 3 additions & 2 deletions app/trip/components/tag-form-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
useToast
} from '@chakra-ui/react'
import { FiPlusCircle, FiX } from 'react-icons/fi'
import { InputIcon } from '@/components/input'
import { InputIconButton } from '@/components/input'
import { Loading } from '@/components/loading'
import { useUserId } from '@/providers/session-provider'
import { TagSchema, tagSchemaResolver } from '../schema'
Expand Down Expand Up @@ -54,6 +54,7 @@ export const TagFormModal = ({

const addTag = async (input: TagSchema) => {
try {

await createTagMutation({
variables: {
name: input.name,
Expand Down Expand Up @@ -155,7 +156,7 @@ export const TagFormModal = ({
</Heading>
<Box mt="8px">
<FormControl isInvalid={!!errors.name}>
<InputIcon
<InputIconButton
type={'text'}
placeholder={'Add tag'}
ariaLabel={'Add tag'}
Expand Down
Loading

0 comments on commit 0cbf271

Please sign in to comment.