Skip to content

Commit

Permalink
Fix bugs (post update date, poll choice order, color) (#245)
Browse files Browse the repository at this point in the history
* fix bugs (post update date, poll choice order, color

* fix for loop commit problem
  • Loading branch information
vcai122 authored Feb 27, 2024
1 parent a31640b commit c5e7088
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 32 deletions.
49 changes: 29 additions & 20 deletions frontend/components/form/FormHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,47 +28,54 @@ const FormHeader = ({ createMode, state, prevOptionIds }: iFormHeaderProps) => {
const [, setSuccess] = useLocalStorage<string | null>('success', null)
const [error, setError] = useState<string | null>(null)

const onSubmit = async () => {
if (
!isPost(state) &&
(state.options[0]?.choice === '' || state.options[1]?.choice === '')
) {
setError('Polls must have at least 2 options')
return
const getBody = () => {
if (!isPost(state)) {
return state
}

const form_data = new FormData()
if (isPost(state)) {
Object.entries(state).forEach(([key, value]) => {
if (key === 'start_date' || key === 'expire_date') {
const val = value.toISOString()
const val = (value as Date)?.toISOString()
form_data.append(key, val)
} else if (key !== 'image') {
form_data.append(key, value.toString())
form_data.append(key, value?.toString())
} else {
form_data.append(key, value)
}
})
}
return form_data
}

const onSubmit = async () => {
if (
!isPost(state) &&
(state.options[0]?.choice === '' || state.options[1]?.choice === '')
) {
setError('Polls must have at least 2 options')
return
}

const res = await doApiRequest(`/api/portal/${route}/`, {
method: 'POST',
body: isPost(state) ? form_data : state,
body: getBody(),
})

if (res.ok) {
// post each poll option if creating a poll
if (!isPost(state)) {
const pollRes = await res.json()
state.options.map((option) =>
doApiRequest('/api/portal/options/', {
for (const option of state.options) {
/* eslint-disable no-await-in-loop */
await doApiRequest('/api/portal/options/', {
method: 'POST',
body: {
poll: pollRes.id,
choice: option.choice,
},
})
)
}
}

// redirect to dashboard after submitting with success message
Expand Down Expand Up @@ -104,15 +111,16 @@ const FormHeader = ({ createMode, state, prevOptionIds }: iFormHeaderProps) => {
}
const res = await doApiRequest(`/api/portal/${route}/${state.id}/`, {
method: 'PATCH',
body: isPost(state) ? form_data : state,
body: getBody(),
})

if (res.ok) {
if (!isPost(state)) {
const currOptionIds = state.options.map((option) => {
for (const option of state.options) {
/* eslint-disable no-await-in-loop */
// post new poll option
if (!prevOptionIds?.includes(option.id)) {
doApiRequest('/api/portal/options/', {
await doApiRequest('/api/portal/options/', {
method: 'POST',
body: {
poll: state.id,
Expand All @@ -121,16 +129,17 @@ const FormHeader = ({ createMode, state, prevOptionIds }: iFormHeaderProps) => {
})
} else {
// update existing poll option
doApiRequest(`/api/portal/options/${option.id}/`, {
await doApiRequest(`/api/portal/options/${option.id}/`, {
method: 'PATCH',
body: {
poll: state.id,
choice: option.choice,
},
})
}
return option.id
})
}

const currOptionIds = state.options.map((option) => option.id)

prevOptionIds?.forEach((optionId) => {
if (!currOptionIds.includes(optionId)) {
Expand Down
12 changes: 6 additions & 6 deletions frontend/components/styles/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ const DatePickerForm = ({
? [moment(startDate), moment(expireDate)]
: undefined
}
onChange={(dates) =>
onChange={(dates) => {
dates &&
updateState({
start_date: dates[0]?.toDate(),
expire_date: dates[1]?.toDate(),
})
}
updateState({
start_date: dates[0]?.toDate(),
expire_date: dates[1]?.toDate(),
})
}}
style={{
fontFamily: 'inherit',
padding: '0.5rem',
Expand Down
1 change: 0 additions & 1 deletion frontend/pages/polls/[...pollId].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ const PollPage = ({
filters,
}: iPollPageProps & { user: User }) => {
const [state, setState] = useState<PollType>(poll || initialPoll)

const updateState = useCallback((newState) => {
setState((currentState) => ({ ...currentState, ...newState }))
}, [])
Expand Down
10 changes: 9 additions & 1 deletion frontend/pages/posts/[...postId].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,15 @@ const PostPage = ({
post,
filters,
}: iPostPageProps & { user: User }) => {
const [state, setState] = useState<PostType>(post || initialPost)
const [state, setState] = useState<PostType>(
post
? {
...post,
start_date: new Date(post.start_date!), // deserialize date strings since they have to be sent as strings
expire_date: new Date(post.expire_date!),
}
: initialPost
)

const updateState = useCallback((newState) => {
setState((currentState) => ({ ...currentState, ...newState }))
Expand Down
10 changes: 6 additions & 4 deletions frontend/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ export const setStatuses = (contentList: PostType[] | PollType[]) => {
// returns a rgb string from a string input. used for generating colors for polls
// based on string hash for consistent colors
export const stringToRGB = (str: string) => {
const hash = Array.from(str).reduce((acc, char) => {
acc = (acc << 5) - acc + char.charCodeAt(0)
return acc & acc
}, 0)
const hash = Array.from(str)
.reverse() // good heuristic
.reduce((acc, char) => {
acc = (acc << 5) - acc + char.charCodeAt(0)
return acc & acc
}, 0)
const rgb = Array.from({ length: 3 }, (_, i) => (hash >> (i * 8)) & 255)
return `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`
}

0 comments on commit c5e7088

Please sign in to comment.