1
0
Fork 0
freesewing/sites/shared/components/submissions/index.mjs

217 lines
7.6 KiB
JavaScript
Raw Normal View History

// Dependencies
import { cloudflareImageUrl, nsMerge } from 'shared/utils.mjs'
2023-09-04 08:40:05 +02:00
// Context
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
// Hooks
import { useTranslation } from 'next-i18next'
2023-09-04 12:18:52 +02:00
import { useEffect, useState, useContext } from 'react'
import { useBackend } from 'shared/hooks/use-backend.mjs'
import { useRouter } from 'next/router'
// Components
import { AuthWrapper } from 'shared/components/wrappers/auth/index.mjs'
import { Loading } from 'shared/components/spinner.mjs'
import { DisplayRow } from 'shared/components/account/shared.mjs'
import { PageLink } from 'shared/components/link.mjs'
import { Mdx } from 'shared/components/mdx/dynamic.mjs'
import { Error404, ns as errNs } from 'shared/components/errors/404.mjs'
2023-09-04 17:12:52 +02:00
import { TrashIcon } from 'shared/components/icons.mjs'
import { Popout } from 'shared/components/popout/index.mjs'
export const ns = nsMerge('account', 'submissions', errNs)
2023-09-04 17:12:52 +02:00
export const CsetSubmissions = () => {
const { t } = useTranslation(ns)
const { setLoadingStatus, LoadingProgress } = useContext(LoadingStatusContext)
const backend = useBackend()
const [suggested, setSuggested] = useState([])
const [selected, setSelected] = useState({})
const [refresh, setRefresh] = useState(0)
useEffect(() => {
const loadSuggestedSets = async () => {
setLoadingStatus([true, 'status:loadingData'])
const result = await backend.getSuggestedSets()
if (result.success) {
setLoadingStatus([true, 'status:dataLoaded', true, true])
setSuggested(result.data.suggested)
} else setLoadingStatus([true, 'status:backendError', true, false])
}
loadSuggestedSets()
}, [refresh])
// Helper var to see how many are selected
const selCount = Object.keys(selected).length
// Helper method to toggle single selection
const toggleSelect = (id) => {
const newSelected = { ...selected }
if (newSelected[id]) delete newSelected[id]
else newSelected[id] = 1
setSelected(newSelected)
}
// Helper method to toggle select all
const toggleSelectAll = () => {
if (selCount === suggested.length) setSelected({})
else {
const newSelected = {}
2023-09-04 17:45:03 +02:00
for (const sug of suggested) newSelected[sug.id] = 1
2023-09-04 17:12:52 +02:00
setSelected(newSelected)
}
}
// Helper to delete one or more apikeys
const removeSelectedSuggestions = async () => {
let i = 0
for (const key in selected) {
i++
await backend.removeSuggestedMeasurementsSet(key)
setLoadingStatus([
true,
<LoadingProgress val={i} max={selCount} msg={t('removingRecords')} key="linter" />,
])
}
setSelected({})
setRefresh(refresh + 1)
setLoadingStatus([true, 'nailedIt', true, true])
}
if (suggested.length < 1)
return (
<Popout note>
<h5>There are no suggested measurements sets</h5>
</Popout>
)
return (
<>
{selCount ? (
<button className="btn btn-error" onClick={removeSelectedSuggestions}>
<TrashIcon /> {selCount} {t('curate:suggestedSets')}
</button>
) : null}
<table className="table table-auto">
<thead className="border border-base-300 border-b-2 border-t-0 border-x-0">
<tr className="b">
<th className="text-base-300 text-base">
<input
type="checkbox"
className="checkbox checkbox-secondary"
onClick={toggleSelectAll}
checked={suggested.length === selCount}
/>
</th>
<th className="text-base-300 text-base">{t('curate:img')}</th>
<th className="text-base-300 text-base">{t('curate:name')}</th>
<th className="text-base-300 text-base">{t('curate:user')}</th>
<th className="text-base-300 text-base">{t('curate:set')}</th>
<th className="text-base-300 text-base">{t('curate:height')}</th>
<th className="text-base-300 text-base">{t('curate:createdAt')}</th>
</tr>
</thead>
<tbody>
{suggested.map((sug, i) => (
<tr key={i}>
<td className="text-base font-medium">
<input
type="checkbox"
checked={selected[sug.id] ? true : false}
className="checkbox checkbox-secondary"
onClick={() => toggleSelect(sug.id)}
/>
</td>
<td className="text-base font-medium">
<img
className="h-12 w-auto"
src={cloudflareImageUrl({ variant: 'w200', id: sug.data.img })}
/>
</td>
<td className="text-base font-medium">
2023-10-22 16:13:30 +02:00
<PageLink href={`/curate/sets/suggested?id=${sug.id}`} txt={sug.data.name} />
2023-09-04 17:12:52 +02:00
</td>
<td className="text-base font-medium">
2023-10-22 16:13:30 +02:00
<PageLink href={`/user?id=${sug.userId}`} txt={`/user?id=${sug.userId}`} />
2023-09-04 17:12:52 +02:00
</td>
<td className="text-base font-medium">
2023-10-22 16:13:30 +02:00
<PageLink href={`/set?id=${sug.data.set}`} txt={`/set?id=${sug.data.set}`} />
2023-09-04 17:12:52 +02:00
</td>
<td className="text-base font-medium">{sug.data.height}</td>
</tr>
))}
</tbody>
</table>
</>
)
}
export const CsetSubmission = ({ id }) => {
// Hooks
const { t } = useTranslation(ns)
const backend = useBackend()
2023-09-04 08:40:05 +02:00
const { setLoadingStatus } = useContext(LoadingStatusContext)
const router = useRouter()
const [submission, setSubmission] = useState(false)
const [error, setError] = useState(false)
useEffect(() => {
const loadSubmission = async () => {
setLoadingStatus([true, 'status:contactingBackend'])
const result = await backend.loadConfirmation({ id, check: 'check' })
if (result.success) {
setLoadingStatus([true, 'status:dataLoaded', true, true])
setSubmission(result.data.submission)
} else {
if (result.status === 404) setError(404)
setLoadingStatus([true, 'status:backendError', true, false])
}
}
if (id) loadSubmission()
}, [id])
const csetFromSuggestedSet = async () => {
setLoadingStatus([true, 'status:contactingBackend'])
const result = await backend.csetFromSuggestedSet(submission.id)
console.log(result)
if (result.success) {
setLoadingStatus([true, 'status:nailedIt', true, true])
router.push(`/curated-set?id=${result.data.set.id}`)
} else setLoadingStatus([true, 'backendError', true, false])
}
if (!id) return <Loading />
if (error === 404) return <Error404 />
return (
<div className="max-w-2xl">
<DisplayRow title={t('account:name')} keyWidth="w-48">
{submission.name}
</DisplayRow>
<DisplayRow title={t('submissions:id')} keyWidth="w-48">
2023-10-22 16:13:30 +02:00
<PageLink href={`/curate/sets/suggested?id=${submission.id}`} txt={submission.id} />
</DisplayRow>
<DisplayRow title={t('account:set')} keyWidth="w-48">
2023-10-22 16:13:30 +02:00
<PageLink href={`/set?id=${submission.set}`} txt={`/set?id=${submission.set}`} />
</DisplayRow>
<DisplayRow title={t('account:height')} keyWidth="w-48">
{submission.height}
</DisplayRow>
<DisplayRow title={t('account:notes')} keyWidth="w-48">
<Mdx md={submission.notes} />
</DisplayRow>
<DisplayRow title={t('account:image')} keyWidth="w-48">
<img src={cloudflareImageUrl({ type: 'w500', id: submission.img })} />
</DisplayRow>
{submission.id && (
<AuthWrapper role="curator">
<button className="btn btn-primary w-full mt-4" onClick={csetFromSuggestedSet}>
{t('submissions:convertToCset')}
</button>
</AuthWrapper>
)}
</div>
)
}