>
)
// Is it a button with an onClick handler?
if (onClick)
return (
)
// Returns a link to an internal page
if (href && !useA)
return (
{inner}
)
// Returns a link to an external page
if (href && useA)
return (
{inner}
)
// Returns a div
return
{inner}
}
export const Mset = ({ id, publicOnly = false }) => {
// Hooks
const { account, control } = useAccount()
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
const backend = useBackend()
const { t, i18n } = useTranslation(ns)
// FIXME: implement a solution for loading docs dynamically the is simple and work as expected
const docs = {}
for (const option of ['name', 'units', 'public', 'notes', 'image']) {
docs[option] =
}
// FIXME: implement a solution for loading docs dynamically the is simple and work as expected
const measieDocs = {}
for (const m of measurements) {
measieDocs[m] =
}
// Context
const { setModal } = useContext(ModalContext)
const [filter, setFilter] = useState(false)
const [edit, setEdit] = useState(false)
const [mset, setMset] = useState()
// Set fields for editing
const [name, setName] = useState(mset?.name)
const [image, setImage] = useState(mset?.image)
const [isPublic, setIsPublic] = useState(mset?.public ? true : false)
const [imperial, setImperial] = useState(mset?.imperial ? true : false)
const [notes, setNotes] = useState(mset?.notes || '')
const [measies, setMeasies] = useState({})
// Effect
useEffect(() => {
const getSet = async () => {
setLoadingStatus([true, t('backendLoadingStarted')])
const result = await backend.getSet(id)
if (result.success) {
setMset(result.data.set)
setName(result.data.set.name)
setImage(result.data.set.image)
setIsPublic(result.data.set.public ? true : false)
setImperial(result.data.set.imperial ? true : false)
setNotes(result.data.set.notes)
setMeasies(result.data.set.measies)
setLoadingStatus([true, 'backendLoadingCompleted', true, true])
} else setLoadingStatus([true, 'backendError', true, false])
}
const getPublicSet = async () => {
setLoadingStatus([true, t('backendLoadingStarted')])
const result = await backend.getPublicSet(id)
if (result.success) {
setMset({
...result.data,
public: true,
measies: result.data.measurements,
})
setName(result.data.name)
setImage(result.data.image)
setIsPublic(result.data.public ? true : false)
setImperial(result.data.imperial ? true : false)
setNotes(result.data.notes)
setMeasies(result.data.measurements)
setLoadingStatus([true, 'backendLoadingCompleted', true, true])
} else setLoadingStatus([true, 'backendError', true, false])
}
if (id) {
if (publicOnly) getPublicSet()
else getSet()
}
}, [id, publicOnly])
const filterMeasurements = () => {
if (!filter) return measurements.map((m) => t(`measurements:${m}`) + `|${m}`).sort()
else return designMeasurements[filter].map((m) => t(`measurements:${m}`) + `|${m}`).sort()
}
if (!id || !mset) return null
const updateMeasies = (m, val) => {
const newMeasies = { ...measies }
newMeasies[m] = val
setMeasies(newMeasies)
}
const save = async () => {
setLoadingStatus([true, 'gatheringInfo'])
// Compile data
const data = { measies: {} }
if (name || name !== mset.name) data.name = name
if (image || image !== mset.image) data.img = image
if ([true, false].includes(isPublic) && isPublic !== mset.public) data.public = isPublic
if ([true, false].includes(imperial) && imperial !== mset.imperial) data.imperial = imperial
if (notes || notes !== mset.notes) data.notes = notes
// Add measurements
for (const m of measurements) {
if (measies[m] || measies[m] !== mset.measies[m]) data.measies[m] = measies[m]
}
setLoadingStatus([true, 'savingSet'])
const result = await backend.updateSet(mset.id, data)
if (result.success) {
setMset(result.data.set)
setEdit(false)
setLoadingStatus([true, 'nailedIt', true, true])
} else setLoadingStatus([true, 'backendError', true, false])
}
const heading = (
<>
{/* Name is always shown */}
val && val.length > 0}
/>
{/* img: Control level determines whether or not to show this */}
{account.control >= conf.account.sets.img ? (
val.length > 0}
/>
) : null}
{/* public: Control level determines whether or not to show this */}
{account.control >= conf.account.sets.public ? (
{t('publicSet')}
)
// Is it a button with an onClick handler?
if (onClick)
return (
)
// Returns a link to an internal page
if (href && !useA)
return (
{inner}
)
// Returns a link to an external page
if (href && useA)
return (
{inner}
)
// Returns a div
return
{inner}
}
export const MsetButton = (props) =>
export const MsetLink = (props) =>
export const MsetA = (props) =>
export const UserSetPicker = ({ design, t, href, clickHandler }) => {
// Hooks
const backend = useBackend()
const { control } = useAccount()
// State
const [sets, setSets] = useState({})
// Effects
useEffect(() => {
const getSets = async () => {
const result = await backend.getSets()
if (result.success) {
const all = {}
for (const set of result.data.sets) all[set.id] = set
setSets(all)
}
}
getSets()
}, [backend])
let hasSets = false
const okSets = []
const lackingSets = []
if (Object.keys(sets).length > 0) {
hasSets = true
for (const setId in sets) {
const [hasMeasies] = hasRequiredMeasurements(
designMeasurements[design],
sets[setId].measies,
true
)
if (hasMeasies) okSets.push(sets[setId])
else lackingSets.push(sets[setId])
}
}
if (!hasSets)
return (
{t('account:noOwnSets')}
{t('account:pleaseMtm')}
{t('account:noOwnSetsMsg')}
{t('account:newSet')}
)
return (
<>
{t('yourSets')}
{okSets.length > 0 && (
<>
{t('account:theseSetsReady')}
{okSets.map((set) => (
))}
>
)}
{lackingSets.length > 0 && (
{t('account:someSetsLacking')}
{lackingSets.map((set) => (
))}
)}
>
)
}
export const CuratedSetPicker = ({ design, language, href, clickHandler }) => {
// Hooks
const backend = useBackend()
const { t, i18n } = useTranslation('sets')
const { control } = useAccount()
// State
const [curatedSets, setCuratedSets] = useState([])
const [filter, setFilter] = useState([])
const [tags, setTags] = useState([])
// 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()
}, [backend, language])
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)}`
if (set[key]) 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()
// Need to sort designs by their translated title
const translated = {}
for (const d of list) translated[t(`${d}.t`)] = d
return (
<>