// Dependencies
import { capitalize } from 'shared/utils.mjs'
import { siteConfig } from 'site/site.config.mjs'
// Context
import { LoadingContext } from 'shared/context/loading-context.mjs'
import { ModalContext } from 'shared/context/modal-context.mjs'
// Hooks
import { useState, useEffect, useContext } from 'react'
import { useTranslation } from 'next-i18next'
import { useAccount } from 'shared/hooks/use-account.mjs'
import { useBackend } from 'shared/hooks/use-backend.mjs'
import { useToast } from 'shared/hooks/use-toast.mjs'
// Components
import Link from 'next/link'
import { Collapse } from 'shared/components/collapse.mjs'
import { TrashIcon, EditIcon, FilterIcon } from 'shared/components/icons.mjs'
import { ModalWrapper } from 'shared/components/wrappers/modal.mjs'
import Timeago from 'react-timeago'
import { Tag } from 'shared/components/tag.mjs'
export const ns = ['toast', 'curate', 'sets', 'account']
export const Row = ({ title, children }) => (
{title}
{children}
)
const CuratedSet = ({
set,
account,
t,
startLoading,
stopLoading,
backend,
refresh,
toast,
language,
}) => {
const { setModal } = useContext(ModalContext)
const remove = async () => {
startLoading()
const result = await backend.removeCuratedMeasurementsSet(set.id)
if (result) toast.success(t('gone'))
else toast.for.backendError()
// This just forces a refresh of the list from the server
// We obviously did not add a key here, but rather removed one
refresh()
stopLoading()
}
const removeModal = () => {
setModal(
{t('curate:areYouCertain')}
{t('curate:deleteCuratedItemWarning')}
)
}
return (
,
,
]}
>
{set.id}
{siteConfig.languages
.sort()
.map((lang) => capitalize(lang))
.map((lang) => (
{lang} {t('name')}
>
}
key={`name${lang}`}
>
{set[`name${lang}`]}
))}
edit
)
}
export const CurateSets = () => {
// Context
const { startLoading, stopLoading } = useContext(LoadingContext)
// Hooks
const { account, token } = useAccount()
const backend = useBackend(token)
const { t, i18n } = useTranslation('sets', 'curate', 'toast', 'account')
const { language } = i18n
const toast = useToast()
// State
const [curatedSets, setCuratedSets] = useState([])
const [filter, setFilter] = useState([])
const [tags, setTags] = useState([])
const [reload, setReload] = useState(0)
// Force a refresh
const refresh = () => setReload(reload + 1)
// Effects
useEffect(() => {
const getCuratedSets = async () => {
const result = await backend.getCuratedSets()
if (result.success) {
const all = []
const allTags = new Set()
for (const set of result.data.curatedSets) {
all.push(set)
for (const tag of set[`tags${capitalize(language)}`]) allTags.add(tag)
}
setCuratedSets(all)
setTags([...allTags])
}
}
getCuratedSets()
}, [reload])
const addFilter = (tag) => {
const newFilter = [...filter, tag]
setFilter(newFilter)
}
const removeFilter = (tag) => {
const newFilter = filter.filter((t) => t !== tag)
setFilter(newFilter)
}
const applyFilter = () => {
const newList = new Set()
for (const set of curatedSets) {
const setTags = []
for (const lang of siteConfig.languages) {
const key = `tags${capitalize(lang)}`
setTags.push(...set[key])
}
let match = 0
for (const tag of filter) {
if (setTags.includes(tag)) match++
}
if (match === filter.length) newList.add(set)
}
return [...newList]
}
const list = applyFilter()
return (