feat(org): Bookmarks for docs
This commit is contained in:
parent
e21d262ec2
commit
2106a38154
66 changed files with 380 additions and 467 deletions
|
@ -1,8 +1,7 @@
|
|||
// Context
|
||||
import { LoadingContext } from 'shared/context/loading-context.mjs'
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useToast } from 'shared/hooks/use-toast.mjs'
|
||||
import { useState, useContext } from 'react'
|
||||
// Components
|
||||
import { ChoiceButton } from 'shared/components/choice-button.mjs'
|
||||
|
@ -43,12 +42,9 @@ const languages = [
|
|||
]
|
||||
|
||||
export const SuggestLanguageForm = () => {
|
||||
// Context
|
||||
const { startLoading, stopLoading } = useContext(LoadingContext)
|
||||
|
||||
// Hooks
|
||||
const backend = useBackend()
|
||||
const toast = useToast()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
// State
|
||||
const [language, setLanguage] = useState(false)
|
||||
|
@ -58,15 +54,12 @@ export const SuggestLanguageForm = () => {
|
|||
const [comments, setComments] = useState('')
|
||||
|
||||
const sendSuggestion = async () => {
|
||||
startLoading()
|
||||
setLoadingStatus([true, 'status:contactingBackend'])
|
||||
const result = await backend.sendLanguageSuggestion({ language, help, friends, comments })
|
||||
if (result.success) {
|
||||
setSent(true)
|
||||
stopLoading()
|
||||
toast.success('Suggestion submitted')
|
||||
} else {
|
||||
toast.for.backendError()
|
||||
}
|
||||
setLoadingStatus([true, 'status:nailedIt', true, true])
|
||||
} else setLoadingStatus([true, 'status:backendError', true, false])
|
||||
}
|
||||
|
||||
if (sent)
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
import { siteConfig } from 'site/site.config.mjs'
|
||||
import translators from 'site/prebuild/translators.json'
|
||||
// Context
|
||||
import { LoadingContext } from 'shared/context/loading-context.mjs'
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useToast } from 'shared/hooks/use-toast.mjs'
|
||||
import { useState, useContext } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Components
|
||||
|
@ -22,28 +21,22 @@ const languages = [
|
|||
].sort()
|
||||
|
||||
export const TranslatorInvite = () => {
|
||||
// Context
|
||||
const { startLoading, stopLoading } = useContext(LoadingContext)
|
||||
|
||||
// Hooks
|
||||
const { t } = useTranslation(ns)
|
||||
const backend = useBackend()
|
||||
const toast = useToast()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
// State
|
||||
const [team, setTeam] = useState(false)
|
||||
const [sent, setSent] = useState(false)
|
||||
|
||||
const sendInvite = async () => {
|
||||
startLoading()
|
||||
setLoadingStatus([true, 'status:contactingBackend'])
|
||||
const result = await backend.sendTranslatorInvite(team)
|
||||
if (result.success) {
|
||||
setSent(true)
|
||||
stopLoading()
|
||||
toast.success(t('translation:inviteSent'))
|
||||
} else {
|
||||
toast.for.backendError()
|
||||
}
|
||||
setLoadingStatus([true, 'status:settingsSaved', true, true])
|
||||
} else setLoadingStatus([true, 'status:backendError', true, false])
|
||||
}
|
||||
|
||||
if (sent)
|
||||
|
|
|
@ -5,14 +5,13 @@ import { freeSewingConfig as conf } from 'shared/config/freesewing.config.mjs'
|
|||
import { measurements } from 'config/measurements.mjs'
|
||||
import { measurements as designMeasurements } from 'shared/prebuild/data/design-measurements.mjs'
|
||||
// Context
|
||||
import { LoadingContext } from 'shared/context/loading-context.mjs'
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-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 { Collapse } from 'shared/components/collapse.mjs'
|
||||
import { ClearIcon, EditIcon, FilterIcon } from 'shared/components/icons.mjs'
|
||||
|
@ -22,7 +21,7 @@ import { PageLink } from 'shared/components/link.mjs'
|
|||
import { ModalDesignPicker } from 'shared/components/modal/design-picker.mjs'
|
||||
import { V3Wip } from 'shared/components/v3-wip.mjs'
|
||||
|
||||
export const ns = ['toast', 'curate', 'sets', 'account']
|
||||
export const ns = ['curate', 'sets', 'account']
|
||||
|
||||
const EditField = (props) => {
|
||||
if (props.field === 'nameEn') return <EditName {...props} lang="en" />
|
||||
|
@ -137,7 +136,7 @@ export const EditCuratedSet = ({ id }) => {
|
|||
|
||||
/*
|
||||
// Context
|
||||
const { startLoading, stopLoading } = useContext(LoadingContext)
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const { setModal } = useContext(ModalContext)
|
||||
|
||||
// Hooks
|
||||
|
@ -171,8 +170,6 @@ export const EditCuratedSet = ({ id }) => {
|
|||
}, [reload, backend, id])
|
||||
|
||||
const editProps = {
|
||||
startLoading,
|
||||
stopLoading,
|
||||
account,
|
||||
backend,
|
||||
t,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { capitalize } from 'shared/utils.mjs'
|
||||
import { siteConfig } from 'site/site.config.mjs'
|
||||
// Context
|
||||
import { LoadingContext } from 'shared/context/loading-context.mjs'
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
import { ModalContext } from 'shared/context/modal-context.mjs'
|
||||
// Hooks
|
||||
import { useState, useEffect, useContext } from 'react'
|
||||
|
@ -27,28 +27,17 @@ export const Row = ({ title, children }) => (
|
|||
</div>
|
||||
)
|
||||
|
||||
const CuratedSet = ({
|
||||
set,
|
||||
account,
|
||||
t,
|
||||
startLoading,
|
||||
stopLoading,
|
||||
backend,
|
||||
refresh,
|
||||
toast,
|
||||
language,
|
||||
}) => {
|
||||
const CuratedSet = ({ set, account, t, setLoadingStatus, backend, refresh, toast, language }) => {
|
||||
const { setModal } = useContext(ModalContext)
|
||||
|
||||
const remove = async () => {
|
||||
startLoading()
|
||||
setLoadingStatus([true, 'status:contactingBackend'])
|
||||
const result = await backend.removeCuratedMeasurementsSet(set.id)
|
||||
if (result) toast.success(t('gone'))
|
||||
else toast.for.backendError()
|
||||
if (result) setLoadingStatus([true, 'status:settingsSaved', true, true])
|
||||
else setLoadingStatus([true, 'status:backendError', true, false])
|
||||
// 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 = () => {
|
||||
|
@ -119,7 +108,7 @@ const CuratedSet = ({
|
|||
|
||||
export const CurateSets = () => {
|
||||
// Context
|
||||
const { startLoading, stopLoading } = useContext(LoadingContext)
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
// Hooks
|
||||
const { account } = useAccount()
|
||||
|
@ -209,7 +198,7 @@ export const CurateSets = () => {
|
|||
{list.map((set) => (
|
||||
<CuratedSet
|
||||
key={set.id}
|
||||
{...{ set, account, t, startLoading, stopLoading, backend, refresh, toast, language }}
|
||||
{...{ set, account, t, setLoadingStatus, backend, refresh, toast, language }}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
@ -5,6 +5,8 @@ import { useState, Fragment } from 'react'
|
|||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Components
|
||||
import { Popout } from 'shared/components/popout/index.mjs'
|
||||
import { AuthWrapper, ns as authNs } from 'shared/components/wrappers/auth/index.mjs'
|
||||
|
@ -22,7 +24,6 @@ import { CodeBox } from 'shared/components/code-box.mjs'
|
|||
import { PostArticle, ns as mdxNs } from 'site/components/mdx/posts/article.mjs'
|
||||
import { PageLink, WebLink } from 'shared/components/link.mjs'
|
||||
import { OkIcon, WarningIcon as KoIcon } from 'shared/components/icons.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
|
||||
export const ns = nsMerge('account', 'posts', authNs, mdxNs)
|
||||
|
||||
|
@ -64,7 +65,7 @@ export const CreatePost = ({ type = 'showcase' }) => {
|
|||
const backend = useBackend()
|
||||
const { account } = useAccount()
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
const { loading, setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { loading, setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
// State
|
||||
const [designs, setDesigns] = useState([])
|
||||
|
@ -151,7 +152,6 @@ export const CreatePost = ({ type = 'showcase' }) => {
|
|||
|
||||
return (
|
||||
<AuthWrapper>
|
||||
<LoadingStatus />
|
||||
{pr ? (
|
||||
<div className="w-full max-w-3xl m-auto p-4">
|
||||
<h1>Thank you for submitting this {type} post</h1>
|
||||
|
|
|
@ -5,6 +5,8 @@ import { useState, Fragment } from 'react'
|
|||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Components
|
||||
import { Popout } from 'shared/components/popout/index.mjs'
|
||||
import { AuthWrapper, ns as authNs } from 'shared/components/wrappers/auth/index.mjs'
|
||||
|
@ -22,7 +24,6 @@ import { CodeBox } from 'shared/components/code-box.mjs'
|
|||
import { PostArticle, ns as mdxNs } from 'site/components/mdx/posts/article.mjs'
|
||||
import { PageLink, WebLink } from 'shared/components/link.mjs'
|
||||
import { OkIcon, WarningIcon as KoIcon } from 'shared/components/icons.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
|
||||
export const ns = nsMerge('account', 'posts', authNs, mdxNs)
|
||||
|
||||
|
@ -53,7 +54,7 @@ export const CreateShowcasePost = () => {
|
|||
const { account } = useAccount()
|
||||
const backend = useBackend()
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
const { loading, setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { loading, setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
const [designs, setDesigns] = useState([])
|
||||
const [title, setTitle] = useState('')
|
||||
|
@ -135,7 +136,6 @@ export const CreateShowcasePost = () => {
|
|||
|
||||
return (
|
||||
<AuthWrapper>
|
||||
<LoadingStatus />
|
||||
{pr ? (
|
||||
<div className="w-full max-w-3xl m-auto p-4">
|
||||
<h1>Thank you for submitting this showcase</h1>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { NavigationContext } from 'shared/context/navigation-context.mjs'
|
||||
import { nsMerge } from 'shared/utils.mjs'
|
||||
// Hooks
|
||||
import { useContext } from 'react'
|
||||
// Components
|
||||
|
@ -16,10 +17,10 @@ import {
|
|||
ns as navNs,
|
||||
} from 'shared/components/navigation/sitenav.mjs'
|
||||
import { Toc } from 'shared/components/mdx/toc.mjs'
|
||||
import { MdxMetaData } from 'shared/components/mdx/meta.mjs'
|
||||
import { MdxMetaData, ns as metaNs } from 'shared/components/mdx/meta.mjs'
|
||||
import { PrevNext } from 'shared/components/prev-next.mjs'
|
||||
|
||||
export const ns = [navNs, 'docs'] //navNs
|
||||
export const ns = nsMerge(navNs, 'docs', metaNs)
|
||||
|
||||
export const FrontmatterHead = ({ frontmatter, slug, locale }) => (
|
||||
<Head>
|
||||
|
|
|
@ -4,7 +4,6 @@ import React from 'react'
|
|||
import Bugsnag from '@bugsnag/js'
|
||||
import BugsnagPluginReact from '@bugsnag/plugin-react'
|
||||
import { siteConfig } from 'site/site.config.mjs'
|
||||
import { Toaster as DefaultToaster } from 'react-hot-toast'
|
||||
import { ContextWrapper } from 'shared/components/wrappers/context.mjs'
|
||||
|
||||
Bugsnag.start({
|
||||
|
@ -19,24 +18,6 @@ const FreeSewingOrg = ({ Component, pageProps }) => (
|
|||
<ErrorBoundary>
|
||||
<ContextWrapper>
|
||||
<Component {...pageProps} />
|
||||
<DefaultToaster
|
||||
position="bottom-right"
|
||||
toastOptions={{
|
||||
className: 'bg-base-100 text-base-content',
|
||||
success: {
|
||||
className: 'bg-success text-success-content',
|
||||
},
|
||||
error: {
|
||||
className: 'bg-error text-error-content',
|
||||
},
|
||||
loading: {
|
||||
className: 'bg-warning text-warning-content',
|
||||
},
|
||||
custom: {
|
||||
className: 'bg-accent text-accent-content',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</ContextWrapper>
|
||||
</ErrorBoundary>
|
||||
)
|
||||
|
|
|
@ -6,14 +6,13 @@ import { nsMerge } from 'shared/utils.mjs'
|
|||
import { useTranslation } from 'next-i18next'
|
||||
import { useState, useEffect } from 'react'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs'
|
||||
import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs'
|
||||
import { ns as apikeysNs } from 'shared/components/account/apikeys.mjs'
|
||||
|
||||
// Translation namespaces used on this page
|
||||
const ns = nsMerge(apikeysNs, authNs, pageNs, 'status')
|
||||
const ns = nsMerge(apikeysNs, authNs, pageNs)
|
||||
|
||||
/*
|
||||
* Some things should never generated as SSR
|
||||
|
@ -38,26 +37,20 @@ const DynamicApikey = dynamic(
|
|||
const ApikeyPage = ({ page, id }) => {
|
||||
const { t } = useTranslation(ns)
|
||||
const backend = useBackend()
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
|
||||
const [apikey, setApikey] = useState()
|
||||
|
||||
useEffect(() => {
|
||||
const getApikey = async () => {
|
||||
setLoadingStatus([true, t('backendLoadingStarted')])
|
||||
const result = await backend.getApikey(id)
|
||||
if (result.success) {
|
||||
setApikey(result.data.apikey)
|
||||
console.log(result.data.apikey)
|
||||
setLoadingStatus([true, 'backendLoadingCompleted', true, true])
|
||||
} else setLoadingStatus([false])
|
||||
if (result.success) setApikey(result.data.apikey)
|
||||
else setLoadingStatus([false])
|
||||
}
|
||||
getApikey()
|
||||
}, [id])
|
||||
|
||||
return (
|
||||
<PageWrapper {...page} title={`${t('apikeys')}: ${apikey?.name}`}>
|
||||
<LoadingStatus />
|
||||
<DynamicAuthWrapper>
|
||||
<DynamicApikey apikey={apikey} t={t} />
|
||||
</DynamicAuthWrapper>
|
||||
|
|
|
@ -6,7 +6,6 @@ import { nsMerge } from 'shared/utils.mjs'
|
|||
import { useTranslation } from 'next-i18next'
|
||||
import { useState, useEffect } from 'react'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs'
|
||||
import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs'
|
||||
|
@ -38,25 +37,20 @@ const DynamicBookmark = dynamic(
|
|||
const BookmarkPage = ({ page, id }) => {
|
||||
const { t } = useTranslation(ns)
|
||||
const backend = useBackend()
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
|
||||
const [bookmark, setBookmark] = useState()
|
||||
|
||||
useEffect(() => {
|
||||
const getBookmark = async () => {
|
||||
setLoadingStatus([true, t('backendLoadingStarted')])
|
||||
const result = await backend.getBookmark(id)
|
||||
if (result.success) {
|
||||
setBookmark(result.data.bookmark)
|
||||
setLoadingStatus([true, 'backendLoadingCompleted', true, true])
|
||||
} else setLoadingStatus([false])
|
||||
if (result.success) setBookmark(result.data.bookmark)
|
||||
else setLoadingStatus([false])
|
||||
}
|
||||
getBookmark()
|
||||
}, [id])
|
||||
|
||||
return (
|
||||
<PageWrapper {...page} title={`${t('bookmarks')}: ${bookmark?.title}`}>
|
||||
<LoadingStatus />
|
||||
<DynamicAuthWrapper>
|
||||
<DynamicBookmark bookmark={bookmark} />
|
||||
</DynamicAuthWrapper>
|
||||
|
|
|
@ -2,11 +2,10 @@
|
|||
import { useEffect, useState, useContext } from 'react'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useToast } from 'shared/hooks/use-toast.mjs'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingContext } from 'shared/context/loading-context.mjs'
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Dependencies
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
import Link from 'next/link'
|
||||
|
@ -22,13 +21,10 @@ import { HelpIcon } from 'shared/components/icons.mjs'
|
|||
const ns = Array.from(new Set([...pageNs, 'account']))
|
||||
|
||||
const ConfirmSignUpPage = ({ page }) => {
|
||||
// Context
|
||||
const { startLoading, stopLoading } = useContext(LoadingContext)
|
||||
|
||||
// Hooks
|
||||
const { setAccount, setToken, token } = useAccount()
|
||||
const backend = useBackend()
|
||||
const toast = useToast()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const { t } = useTranslation(ns)
|
||||
const router = useRouter()
|
||||
// Get confirmation ID and check from url
|
||||
|
@ -41,7 +37,7 @@ const ConfirmSignUpPage = ({ page }) => {
|
|||
useEffect(() => {
|
||||
// Async inside useEffect requires this approach
|
||||
const confirmEmail = async () => {
|
||||
startLoading()
|
||||
setLoadingStatus([true, 'status:contactingBackend'])
|
||||
const confirmation = await backend.loadConfirmation({ id, check })
|
||||
if (confirmation?.result === 'success' && confirmation.confirmation) {
|
||||
const result = await backend.updateAccount({
|
||||
|
@ -50,35 +46,23 @@ const ConfirmSignUpPage = ({ page }) => {
|
|||
check: confirmation.confirmation.check,
|
||||
})
|
||||
if (result.success) {
|
||||
setLoadingStatus([true, 'status:settingsSaved', true, true])
|
||||
setAccount(result.data.account)
|
||||
setToken(result.data.token)
|
||||
stopLoading()
|
||||
setError(false)
|
||||
toast.for.settingsSaved()
|
||||
router.push('/account')
|
||||
} else {
|
||||
stopLoading()
|
||||
setLoadingStatus([true, 'status:backendError', true, false])
|
||||
setError(true)
|
||||
}
|
||||
} else {
|
||||
stopLoading()
|
||||
setLoadingStatus([true, 'status:backendError', true, false])
|
||||
setError(true)
|
||||
}
|
||||
}
|
||||
// Call async methods
|
||||
if (token) confirmEmail()
|
||||
}, [
|
||||
id,
|
||||
check,
|
||||
token,
|
||||
backend,
|
||||
router,
|
||||
setAccount,
|
||||
setToken,
|
||||
startLoading,
|
||||
stopLoading,
|
||||
toast.for,
|
||||
])
|
||||
}, [id, check, token, backend, router, setAccount, setToken])
|
||||
|
||||
// Update path with dynamic ID
|
||||
if (!page) return null
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { nsMerge } from 'shared/utils.mjs'
|
||||
// Used in static paths
|
||||
import { pages } from 'site/prebuild/docs.en.mjs'
|
||||
// Dependencies
|
||||
|
@ -11,7 +12,7 @@ import { MdxWrapper } from 'shared/components/wrappers/mdx.mjs'
|
|||
import { DocsLayout, ns as layoutNs } from 'site/components/layouts/docs.mjs'
|
||||
import { loaders } from 'shared/components/dynamic-docs/org.mjs'
|
||||
|
||||
export const ns = [...pageNs, layoutNs]
|
||||
export const ns = nsMerge(pageNs, layoutNs)
|
||||
|
||||
/**
|
||||
* a page to display documentation markdown
|
||||
|
@ -49,7 +50,7 @@ export default DocsPage
|
|||
export async function getStaticProps({ locale, params }) {
|
||||
return {
|
||||
props: {
|
||||
...(await serverSideTranslations('en', ['docs', ...ns])),
|
||||
...(await serverSideTranslations('en', ns)),
|
||||
slug: params.slug.join('/'),
|
||||
locale,
|
||||
page: {
|
||||
|
|
|
@ -6,7 +6,7 @@ import { useState, useContext } from 'react'
|
|||
import { useTranslation } from 'next-i18next'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
// Context
|
||||
import { LoadingContext } from 'shared/context/loading-context.mjs'
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Components
|
||||
import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs'
|
||||
import { Popout } from 'shared/components/popout/index.mjs'
|
||||
|
@ -23,15 +23,15 @@ const namespaces = nsMerge(pageNs, 'newsletter')
|
|||
*/
|
||||
const NewsletterPage = ({ page, id, ehash }) => {
|
||||
const { t } = useTranslation(namespaces)
|
||||
const { setLoading } = useContext(LoadingContext)
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const backend = useBackend()
|
||||
|
||||
const [confirmed, setConfirmed] = useState(false)
|
||||
|
||||
const handler = async () => {
|
||||
setLoading(true)
|
||||
setLoadingStatus([true, 'status:contactingBackend'])
|
||||
await backend.confirmNewsletterSubscribe({ id, ehash })
|
||||
setLoading(false)
|
||||
setLoadingStatus([true, 'status:settingsSaved', true, true])
|
||||
setConfirmed(true)
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import { useState, useContext } from 'react'
|
|||
import { useTranslation } from 'next-i18next'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
// Context
|
||||
import { LoadingContext } from 'shared/context/loading-context.mjs'
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Components
|
||||
import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs'
|
||||
import { Popout } from 'shared/components/popout/index.mjs'
|
||||
|
@ -23,15 +23,15 @@ const namespaces = nsMerge(pageNs, 'newsletter')
|
|||
*/
|
||||
const NewsletterPage = ({ page, id, ehash }) => {
|
||||
const { t } = useTranslation(namespaces)
|
||||
const { setLoading } = useContext(LoadingContext)
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const backend = useBackend()
|
||||
|
||||
const [confirmed, setConfirmed] = useState(false)
|
||||
|
||||
const handler = async () => {
|
||||
setLoading(true)
|
||||
setLoadingStatus([true, 'status:contactingBackend'])
|
||||
await backend.confirmNewsletterUnsubscribe({ id, ehash })
|
||||
setLoading(false)
|
||||
setLoadingStatus([true, 'status:settingsSaved', true, true])
|
||||
setConfirmed(true)
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,9 @@ import { useEffect } from 'react'
|
|||
import { useRouter } from 'next/router'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Components
|
||||
import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs'
|
||||
import { BareLayout } from 'site/components/layouts/bare.mjs'
|
||||
|
@ -27,7 +28,7 @@ const OauthCallbackPage = ({ page, provider }) => {
|
|||
const { t } = useTranslation(ns)
|
||||
const backend = useBackend()
|
||||
const { setAccount, setToken, setSeenUser } = useAccount()
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
useEffect(() => {
|
||||
const oauthFlow = async () => {
|
||||
|
@ -53,7 +54,6 @@ const OauthCallbackPage = ({ page, provider }) => {
|
|||
|
||||
return (
|
||||
<PageWrapper {...page} layout={BareLayout}>
|
||||
<LoadingStatus />
|
||||
<div className="flex flex-col items-center h-screen justify-center text-base-content px-4">
|
||||
<div className="max-w-lg w-full">
|
||||
<Loading />
|
||||
|
|
|
@ -4,11 +4,12 @@ import { useTranslation } from 'next-i18next'
|
|||
import { DateTime } from 'luxon'
|
||||
import { CopyToClipboard } from 'react-copy-to-clipboard'
|
||||
import { shortDate, formatNumber } from 'shared/utils.mjs'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import { BackToAccountButton, DisplayRow, NumberBullet } from './shared.mjs'
|
||||
import { Popout } from 'shared/components/popout/index.mjs'
|
||||
|
@ -55,7 +56,7 @@ const ExpiryPicker = ({ t, expires, setExpires }) => {
|
|||
|
||||
const CopyInput = ({ text }) => {
|
||||
const { t } = useTranslation(['status'])
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
const [copied, setCopied] = useState(false)
|
||||
|
||||
|
@ -67,7 +68,6 @@ const CopyInput = ({ text }) => {
|
|||
|
||||
return (
|
||||
<div className="flex flez-row gap-2 items-center w-full">
|
||||
<LoadingStatus />
|
||||
<input
|
||||
readOnly
|
||||
value={text}
|
||||
|
@ -147,7 +147,7 @@ const NewKey = ({ account, setGenerate, backend }) => {
|
|||
const [level, setLevel] = useState(1)
|
||||
const [expires, setExpires] = useState(Date.now())
|
||||
const [apikey, setApikey] = useState(false)
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
// FIXME: implement a solution for loading docs dynamically the is simple and work as expected
|
||||
const docs = {}
|
||||
|
@ -179,7 +179,6 @@ const NewKey = ({ account, setGenerate, backend }) => {
|
|||
|
||||
return (
|
||||
<div>
|
||||
<LoadingStatus />
|
||||
{apikey ? (
|
||||
<ShowKey {...{ apikey, t, clear }} />
|
||||
) : (
|
||||
|
@ -264,7 +263,7 @@ export const Apikeys = () => {
|
|||
const { account } = useAccount()
|
||||
const backend = useBackend()
|
||||
const { t } = useTranslation(ns)
|
||||
const { setLoadingStatus, LoadingStatus, LoadingProgress } = useLoadingStatus()
|
||||
const { setLoadingStatus, LoadingProgress } = useContext(LoadingStatusContext)
|
||||
|
||||
// State
|
||||
const [keys, setKeys] = useState([])
|
||||
|
@ -319,7 +318,6 @@ export const Apikeys = () => {
|
|||
|
||||
return (
|
||||
<div className="max-w-4xl xl:pl-4">
|
||||
<LoadingStatus />
|
||||
<p className="text-center md:text-right">
|
||||
<Link
|
||||
className="btn btn-primary capitalize w-full md:w-auto"
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Dependencies
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import { Icons, welcomeSteps, BackToAccountButton } from './shared.mjs'
|
||||
import { SaveSettingsButton } from 'shared/components/buttons/save-settings-button.mjs'
|
||||
|
@ -30,7 +31,7 @@ export const BioSettings = ({ welcome = false }) => {
|
|||
const { account, setAccount } = useAccount()
|
||||
const backend = useBackend()
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
// State
|
||||
const [bio, setBio] = useState(account.bio)
|
||||
|
@ -53,7 +54,6 @@ export const BioSettings = ({ welcome = false }) => {
|
|||
|
||||
return (
|
||||
<div className="max-w-xl xl:pl-4">
|
||||
<LoadingStatus />
|
||||
<MarkdownInput
|
||||
id="account-bio"
|
||||
label={t('bioTitle')}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Dependencies
|
||||
import { useState, useEffect, Fragment } from 'react'
|
||||
import { useState, useEffect, Fragment, useContext } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import { BackToAccountButton } from './shared.mjs'
|
||||
import { PlusIcon, TrashIcon, LeftIcon } from 'shared/components/icons.mjs'
|
||||
|
@ -43,7 +44,7 @@ export const Bookmark = ({ bookmark }) => {
|
|||
// Component for the 'new/apikey' page
|
||||
export const NewBookmark = () => {
|
||||
// Hooks
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const router = useRouter()
|
||||
const backend = useBackend()
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
|
@ -72,7 +73,6 @@ export const NewBookmark = () => {
|
|||
|
||||
return (
|
||||
<div className="max-w-2xl xl:pl-4">
|
||||
<LoadingStatus />
|
||||
<StringInput
|
||||
id="bookmark-title"
|
||||
label={t('title')}
|
||||
|
@ -109,7 +109,7 @@ export const Bookmarks = () => {
|
|||
// Hooks
|
||||
const backend = useBackend()
|
||||
const { t } = useTranslation(ns)
|
||||
const { setLoadingStatus, LoadingStatus, LoadingProgress } = useLoadingStatus()
|
||||
const { setLoadingStatus, LoadingProgress } = useContext(LoadingStatusContext)
|
||||
|
||||
// State
|
||||
const [bookmarks, setBookmarks] = useState([])
|
||||
|
@ -167,7 +167,6 @@ export const Bookmarks = () => {
|
|||
|
||||
return (
|
||||
<div className="max-w-4xl xl:pl-4">
|
||||
<LoadingStatus />
|
||||
<p className="text-center md:text-right">
|
||||
<Link
|
||||
className="btn btn-primary capitalize w-full md:w-auto"
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Dependencies
|
||||
import { useState } from 'react'
|
||||
import { useState, useContext } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import { Icons, welcomeSteps, BackToAccountButton } from './shared.mjs'
|
||||
import { ContinueButton } from 'shared/components/buttons/continue-button.mjs'
|
||||
|
@ -18,7 +19,7 @@ export const CompareSettings = ({ welcome = false }) => {
|
|||
// Hooks
|
||||
const { account, setAccount } = useAccount()
|
||||
const backend = useBackend()
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
|
||||
// State
|
||||
|
@ -47,7 +48,6 @@ export const CompareSettings = ({ welcome = false }) => {
|
|||
|
||||
return (
|
||||
<div className="max-w-xl">
|
||||
<LoadingStatus />
|
||||
<ListInput
|
||||
id="account-compare"
|
||||
label={t('compareTitle')}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
// Dependencies
|
||||
import { useState } from 'react'
|
||||
import { useState, useContext } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { nsMerge } from 'shared/utils.mjs'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import Link from 'next/link'
|
||||
import { Popout } from 'shared/components/popout/index.mjs'
|
||||
|
@ -13,7 +14,7 @@ import { BackToAccountButton } from './shared.mjs'
|
|||
import { SaveSettingsButton } from 'shared/components/buttons/save-settings-button.mjs'
|
||||
import { GdprAccountDetails, ns as gdprNs } from 'shared/components/gdpr/details.mjs'
|
||||
|
||||
export const ns = nsMerge(gdprNs, 'account', 'toast')
|
||||
export const ns = nsMerge(gdprNs, 'account', 'status')
|
||||
|
||||
const Checkbox = ({ value, setter, label, children = null }) => (
|
||||
<div
|
||||
|
@ -39,7 +40,7 @@ export const ConsentSettings = ({ title = false }) => {
|
|||
// Hooks
|
||||
const { account, setAccount, setToken } = useAccount()
|
||||
const backend = useBackend()
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const { t } = useTranslation(ns)
|
||||
|
||||
// State
|
||||
|
@ -73,7 +74,6 @@ export const ConsentSettings = ({ title = false }) => {
|
|||
|
||||
return (
|
||||
<div className="max-w-xl xl:pl-4">
|
||||
<LoadingStatus />
|
||||
{title ? <h2 className="text-4xl">{t('privacyMatters')}</h2> : null}
|
||||
<p>{t('compliant')}</p>
|
||||
<p>{t('consentWhyAnswer')}</p>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Dependencies
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import { BackToAccountButton, Icons, welcomeSteps } from './shared.mjs'
|
||||
import { ContinueButton } from 'shared/components/buttons/continue-button.mjs'
|
||||
|
@ -19,7 +20,7 @@ export const useControlState = () => {
|
|||
// Hooks
|
||||
const { account, setAccount, token } = useAccount()
|
||||
const backend = useBackend()
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
// State
|
||||
const [selection, setSelection] = useState(account.control)
|
||||
|
@ -44,7 +45,7 @@ export const useControlState = () => {
|
|||
}
|
||||
}
|
||||
|
||||
return { selection, update, LoadingStatus }
|
||||
return { selection, update }
|
||||
}
|
||||
|
||||
export const ControlSettings = ({ welcome = false, noBack = false }) => {
|
||||
|
@ -61,7 +62,6 @@ export const ControlSettings = ({ welcome = false, noBack = false }) => {
|
|||
|
||||
return (
|
||||
<div className="max-w-xl">
|
||||
<LoadingStatus />
|
||||
<ListInput
|
||||
id="account-control"
|
||||
label={t('controlTitle')}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Dependencies
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Verification methods
|
||||
import { validateEmail, validateTld } from 'shared/utils.mjs'
|
||||
// Components
|
||||
|
@ -20,7 +21,7 @@ export const EmailSettings = () => {
|
|||
const { account, setAccount } = useAccount()
|
||||
const backend = useBackend()
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
// State
|
||||
const [email, setEmail] = useState(account.email)
|
||||
|
@ -42,7 +43,6 @@ export const EmailSettings = () => {
|
|||
|
||||
return (
|
||||
<div className="max-w-xl">
|
||||
<LoadingStatus />
|
||||
{changed ? (
|
||||
<Popout note>
|
||||
<h3>{t('oneMoreThing')}</h3>
|
||||
|
|
|
@ -193,6 +193,7 @@ csetBookmark: Curated Measurements Sets
|
|||
docBookmark: Documentation
|
||||
customBookmark: Custom Bookmarks
|
||||
yourBookmarks: Your bookmarks
|
||||
bookmarkThisPage: Bookmark this page
|
||||
|
||||
# sets
|
||||
set: Measurements Set
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
// Dependencies
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useState } from 'react'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import { BackToAccountButton } from './shared.mjs'
|
||||
import { Popout } from 'shared/components/popout/index.mjs'
|
||||
|
@ -15,7 +16,7 @@ export const ExportAccount = () => {
|
|||
// Hooks
|
||||
const backend = useBackend()
|
||||
const { t } = useTranslation(ns)
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
const [link, setLink] = useState()
|
||||
|
||||
|
@ -31,7 +32,6 @@ export const ExportAccount = () => {
|
|||
|
||||
return (
|
||||
<div className="max-w-xl">
|
||||
<LoadingStatus />
|
||||
{link ? (
|
||||
<Popout link>
|
||||
<h5>{t('exportDownload')}</h5>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Dependencies
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import { BackToAccountButton } from './shared.mjs'
|
||||
import { SaveSettingsButton } from 'shared/components/buttons/save-settings-button.mjs'
|
||||
|
@ -18,7 +19,7 @@ export const GithubSettings = () => {
|
|||
const { account, setAccount } = useAccount()
|
||||
const backend = useBackend()
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
// State
|
||||
const [githubUsername, setGithubUsername] = useState(account.data.githubUsername || '')
|
||||
|
@ -36,7 +37,6 @@ export const GithubSettings = () => {
|
|||
|
||||
return (
|
||||
<div className="max-w-xl">
|
||||
<LoadingStatus />
|
||||
<h2 className="text-4xl">{t('githubTitle')}</h2>
|
||||
<StringInput
|
||||
id="account-github-email"
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
import { useState } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { cloudflareImageUrl } from 'shared/utils.mjs'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import { Icons, welcomeSteps, BackToAccountButton } from './shared.mjs'
|
||||
import { ContinueButton } from 'shared/components/buttons/continue-button.mjs'
|
||||
|
@ -18,7 +19,7 @@ export const ns = ['account', 'status']
|
|||
export const ImgSettings = ({ welcome = false }) => {
|
||||
const { account, setAccount } = useAccount()
|
||||
const backend = useBackend()
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
|
||||
const [img, setImg] = useState('')
|
||||
|
@ -36,7 +37,6 @@ export const ImgSettings = ({ welcome = false }) => {
|
|||
|
||||
return (
|
||||
<div className="max-w-xl">
|
||||
<LoadingStatus />
|
||||
{!welcome || img !== false ? (
|
||||
<img
|
||||
alt="img"
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Dependencies
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import { Icons, welcomeSteps, BackToAccountButton, NumberBullet } from './shared.mjs'
|
||||
import { ContinueButton } from 'shared/components/buttons/continue-button.mjs'
|
||||
|
@ -16,7 +17,7 @@ export const ns = ['account', 'status']
|
|||
export const ImperialSettings = ({ welcome = false }) => {
|
||||
// Hooks
|
||||
const { account, setAccount } = useAccount()
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const backend = useBackend()
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
|
||||
|
@ -44,7 +45,6 @@ export const ImperialSettings = ({ welcome = false }) => {
|
|||
|
||||
return (
|
||||
<div className="max-w-xl">
|
||||
<LoadingStatus />
|
||||
<ListInput
|
||||
id="account-units"
|
||||
label={t('unitsTitle')}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Dependencies
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus, ns as statusNs } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import { BackToAccountButton, NumberBullet } from './shared.mjs'
|
||||
import { ListInput } from 'shared/components/inputs.mjs'
|
||||
|
@ -17,7 +18,7 @@ export const ns = ['account', 'locales', statusNs]
|
|||
export const LanguageSettings = () => {
|
||||
// Hooks
|
||||
const { account, setAccount } = useAccount()
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const backend = useBackend()
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
|
||||
|
@ -39,7 +40,6 @@ export const LanguageSettings = () => {
|
|||
|
||||
return (
|
||||
<div className="max-w-xl">
|
||||
<LoadingStatus />
|
||||
<ListInput
|
||||
id="account-language"
|
||||
label={t('languageTitle')}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Dependencies
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import { BackToAccountButton } from './shared.mjs'
|
||||
import { Popout } from 'shared/components/popout/index.mjs'
|
||||
|
@ -27,7 +28,7 @@ export const MfaSettings = ({ title = false, welcome = false }) => {
|
|||
const { account, setAccount } = useAccount()
|
||||
const backend = useBackend()
|
||||
const { t } = useTranslation(ns)
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
// State
|
||||
const [enable, setEnable] = useState(false)
|
||||
|
@ -87,7 +88,6 @@ export const MfaSettings = ({ title = false, welcome = false }) => {
|
|||
|
||||
return (
|
||||
<div className="max-w-xl">
|
||||
<LoadingStatus />
|
||||
{title ? <h2 className="text-4xl">{titleText}</h2> : null}
|
||||
{enable ? (
|
||||
<>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Dependencies
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import { BackToAccountButton, Icons, welcomeSteps } from './shared.mjs'
|
||||
import { ContinueButton } from 'shared/components/buttons/continue-button.mjs'
|
||||
|
@ -19,7 +20,7 @@ export const NewsletterSettings = ({ welcome = false }) => {
|
|||
const { account, setAccount } = useAccount()
|
||||
const backend = useBackend()
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
const { LoadingStatus, setLoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
// State
|
||||
const [selection, setSelection] = useState(account?.newsletter ? 'yes' : 'no')
|
||||
|
||||
|
@ -44,7 +45,6 @@ export const NewsletterSettings = ({ welcome = false }) => {
|
|||
|
||||
return (
|
||||
<div className="max-w-xl">
|
||||
<LoadingStatus />
|
||||
<ListInput
|
||||
id="account-newsletter"
|
||||
label={t('newsletterTitle')}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Dependencies
|
||||
import { useState } from 'react'
|
||||
import { useState, useContext } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import Link from 'next/link'
|
||||
import { BackToAccountButton } from './shared.mjs'
|
||||
|
@ -21,7 +22,7 @@ export const PasswordSettings = ({ welcome = false }) => {
|
|||
const { account, setAccount } = useAccount()
|
||||
const backend = useBackend()
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
// State
|
||||
const [password, setPassword] = useState('')
|
||||
|
@ -38,7 +39,6 @@ export const PasswordSettings = ({ welcome = false }) => {
|
|||
|
||||
return (
|
||||
<div className="max-w-xl">
|
||||
<LoadingStatus />
|
||||
<PasswordInput
|
||||
id="account-password"
|
||||
label={t('passwordTitle')}
|
||||
|
|
|
@ -3,11 +3,12 @@ import { useState, useEffect, useContext } from 'react'
|
|||
import { useTranslation } from 'next-i18next'
|
||||
import { capitalize, shortDate, cloudflareImageUrl, horFlexClasses } from 'shared/utils.mjs'
|
||||
import { freeSewingConfig as conf, controlLevels } from 'shared/config/freesewing.config.mjs'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Context
|
||||
import { ModalContext } from 'shared/context/modal-context.mjs'
|
||||
// Components
|
||||
|
@ -45,7 +46,7 @@ export const ns = ['account', 'patterns', 'status']
|
|||
export const Pattern = ({ id, publicOnly = false }) => {
|
||||
// Hooks
|
||||
const { account, control } = useAccount()
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const backend = useBackend()
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
// FIXME: implement a solution for loading docs dynamically
|
||||
|
@ -122,7 +123,6 @@ export const Pattern = ({ id, publicOnly = false }) => {
|
|||
|
||||
const heading = (
|
||||
<>
|
||||
<LoadingStatus />
|
||||
<div className="flex flex-wrap md:flex-nowrap flex-row gap-2 w-full">
|
||||
<div className="w-full md:w-96 shrink-0">
|
||||
<PatternCard pattern={pattern} size="md" />
|
||||
|
@ -428,7 +428,7 @@ export const Patterns = () => {
|
|||
// Hooks
|
||||
const backend = useBackend()
|
||||
const { t } = useTranslation(ns)
|
||||
const { setLoadingStatus, LoadingStatus, LoadingProgress } = useLoadingStatus()
|
||||
const { setLoadingStatus, LoadingProgress } = useContext(LoadingStatusContext)
|
||||
|
||||
// State
|
||||
const [patterns, setPatterns] = useState([])
|
||||
|
@ -483,7 +483,6 @@ export const Patterns = () => {
|
|||
|
||||
return (
|
||||
<div className="max-w-4xl xl:pl-4">
|
||||
<LoadingStatus />
|
||||
<p className="text-center md:text-right">
|
||||
<Link className="btn btn-primary capitalize w-full md:w-auto" href="/new/pattern">
|
||||
<PlusIcon />
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Dependencies
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import { BackToAccountButton } from './shared.mjs'
|
||||
import { SaveSettingsButton } from 'shared/components/buttons/save-settings-button.mjs'
|
||||
|
@ -18,7 +19,7 @@ export const PlatformSettings = ({ platform }) => {
|
|||
const { account, setAccount } = useAccount()
|
||||
const backend = useBackend()
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
// State
|
||||
const [platformId, setPlatformId] = useState(account.data[platform] || '')
|
||||
|
@ -37,7 +38,6 @@ export const PlatformSettings = ({ platform }) => {
|
|||
|
||||
return (
|
||||
<div className="max-w-xl">
|
||||
<LoadingStatus />
|
||||
<StringInput
|
||||
id={`account-${platform}`}
|
||||
label={t(platform === 'website' ? 'account:websiteTitle' : 'account:platformTitle', {
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
// Dependencies
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import { BackToAccountButton } from './shared.mjs'
|
||||
|
||||
|
@ -14,7 +15,7 @@ export const ReloadAccount = ({ title = false }) => {
|
|||
const { setAccount } = useAccount()
|
||||
const backend = useBackend()
|
||||
const { t } = useTranslation(ns)
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
// Helper method to reload account
|
||||
const reload = async () => {
|
||||
|
@ -28,7 +29,6 @@ export const ReloadAccount = ({ title = false }) => {
|
|||
|
||||
return (
|
||||
<div className="max-w-xl">
|
||||
<LoadingStatus />
|
||||
{title ? <h2>{t('reloadMsg1')}</h2> : null}
|
||||
<p>{t('reloadMsg2')}</p>
|
||||
<button className="btn btn-primary capitalize w-full my-2" onClick={reload}>
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
// Dependencies
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import { BackToAccountButton } from './shared.mjs'
|
||||
import { Popout } from 'shared/components/popout/index.mjs'
|
||||
|
@ -15,7 +16,7 @@ export const RemoveAccount = () => {
|
|||
const { signOut } = useAccount()
|
||||
const backend = useBackend()
|
||||
const { t } = useTranslation(ns)
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
// Helper method to export account
|
||||
const removeAccount = async () => {
|
||||
|
@ -29,7 +30,6 @@ export const RemoveAccount = () => {
|
|||
|
||||
return (
|
||||
<div className="max-w-xl">
|
||||
<LoadingStatus />
|
||||
<Popout warning>
|
||||
<h3>{t('noWayBack')}</h3>
|
||||
<button className="btn btn-error capitalize w-full my-2" onClick={removeAccount}>
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
// Dependencies
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import { BackToAccountButton } from './shared.mjs'
|
||||
import { Popout } from 'shared/components/popout/index.mjs'
|
||||
|
@ -15,7 +16,7 @@ export const RestrictAccount = () => {
|
|||
const { signOut } = useAccount()
|
||||
const backend = useBackend()
|
||||
const { t } = useTranslation(ns)
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
// Helper method to export account
|
||||
const restrictAccount = async () => {
|
||||
|
@ -29,7 +30,6 @@ export const RestrictAccount = () => {
|
|||
|
||||
return (
|
||||
<div className="max-w-xl">
|
||||
<LoadingStatus />
|
||||
<Popout warning>
|
||||
<h5>{t('proceedWithCaution')}</h5>
|
||||
<p className="text-lg">{t('restrictWarning')}</p>
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
// Dependencies
|
||||
import { useState, useEffect, useContext } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { measurements } from 'config/measurements.mjs'
|
||||
import { measurements as designMeasurements } from 'shared/prebuild/data/design-measurements.mjs'
|
||||
import { freeSewingConfig as conf, controlLevels } from 'shared/config/freesewing.config.mjs'
|
||||
import { siteConfig } from 'site/site.config.mjs'
|
||||
import { isDegreeMeasurement } from 'config/measurements.mjs'
|
||||
import {
|
||||
shortDate,
|
||||
cloudflareImageUrl,
|
||||
|
@ -15,11 +14,13 @@ import {
|
|||
} from 'shared/utils.mjs'
|
||||
import orderBy from 'lodash.orderby'
|
||||
// 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 { useRouter } from 'next/router'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
import { ModalContext } from 'shared/context/modal-context.mjs'
|
||||
// Components
|
||||
import { Popout } from 'shared/components/popout/index.mjs'
|
||||
|
@ -46,7 +47,6 @@ import { ModalWrapper } from 'shared/components/wrappers/modal.mjs'
|
|||
import Markdown from 'react-markdown'
|
||||
import Timeago from 'react-timeago'
|
||||
import { DisplayRow } from './shared.mjs'
|
||||
import { isDegreeMeasurement } from 'config/measurements.mjs'
|
||||
import { DynamicOrgDocs } from 'shared/components/dynamic-docs/org.mjs'
|
||||
import {
|
||||
StringInput,
|
||||
|
@ -62,7 +62,7 @@ export const ns = [inputNs, 'account', 'patterns', 'status', 'measurements', 'se
|
|||
|
||||
export const NewSet = () => {
|
||||
// Hooks
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const backend = useBackend()
|
||||
const { t } = useTranslation(ns)
|
||||
const router = useRouter()
|
||||
|
@ -82,7 +82,6 @@ export const NewSet = () => {
|
|||
|
||||
return (
|
||||
<div className="max-w-xl">
|
||||
<LoadingStatus />
|
||||
<h5>{t('name')}</h5>
|
||||
<p>{t('setNameDesc')}</p>
|
||||
<input
|
||||
|
@ -189,7 +188,7 @@ export const MsetCard = ({
|
|||
export const Mset = ({ id, publicOnly = false }) => {
|
||||
// Hooks
|
||||
const { account, control } = useAccount()
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const backend = useBackend()
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
// FIXME: implement a solution for loading docs dynamically the is simple and work as expected
|
||||
|
@ -295,7 +294,6 @@ export const Mset = ({ id, publicOnly = false }) => {
|
|||
|
||||
const heading = (
|
||||
<>
|
||||
<LoadingStatus />
|
||||
<div className="flex flex-wrap md:flex-nowrap flex-row gap-2 w-full">
|
||||
<div className="w-full md:w-96 shrink-0">
|
||||
<MsetCard set={mset} control={control} />
|
||||
|
@ -647,7 +645,7 @@ export const Sets = () => {
|
|||
const { control } = useAccount()
|
||||
const backend = useBackend()
|
||||
const { t } = useTranslation(ns)
|
||||
const { setLoadingStatus, LoadingStatus, LoadingProgress } = useLoadingStatus()
|
||||
const { setLoadingStatus, LoadingProgress } = useContext(LoadingStatusContext)
|
||||
|
||||
// State
|
||||
const [sets, setSets] = useState([])
|
||||
|
@ -702,7 +700,6 @@ export const Sets = () => {
|
|||
|
||||
return (
|
||||
<div className="max-w-7xl xl:pl-4">
|
||||
<LoadingStatus />
|
||||
<p className="text-center md:text-right">
|
||||
<Link
|
||||
className="btn btn-primary capitalize w-full md:w-auto"
|
||||
|
|
|
@ -133,44 +133,3 @@ export const DisplayRow = ({ title, children, keyWidth = 'w-24' }) => (
|
|||
<div className="grow">{children}</div>
|
||||
</div>
|
||||
)
|
||||
/*
|
||||
// Hooks
|
||||
import { useContext } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingContext } from 'shared/context/loading-context.mjs'
|
||||
// Components
|
||||
import { Spinner } from 'shared/components/spinner.mjs'
|
||||
import Link from 'next/link'
|
||||
|
||||
export const ContinueButton = ({ btnProps = {}, link = false }) => {
|
||||
// Hooks
|
||||
const { t } = useTranslation(['account'])
|
||||
|
||||
let classes = 'btn-primary btn mt-8 capitalize w-full'
|
||||
|
||||
const children = (
|
||||
<span className="flex flex-row items-center gap-2">
|
||||
{loading ? (
|
||||
<>
|
||||
<Spinner />
|
||||
<span>{t('processing')}</span>
|
||||
</>
|
||||
) : (
|
||||
<span>{t('continue')}</span>
|
||||
)}
|
||||
</span>
|
||||
)
|
||||
|
||||
return link ? (
|
||||
<Link className={classes} tabIndex="-1" {...btnProps}>
|
||||
{children}
|
||||
</Link>
|
||||
) : (
|
||||
<button className={classes} tabIndex="-1" role="button" {...btnProps}>
|
||||
{children}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
*/
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Dependencies
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import { Icons, welcomeSteps, BackToAccountButton } from './shared.mjs'
|
||||
import { OkIcon, NoIcon } from 'shared/components/icons.mjs'
|
||||
|
@ -12,13 +13,13 @@ import { ContinueButton } from 'shared/components/buttons/continue-button.mjs'
|
|||
import { StringInput } from 'shared/components/inputs.mjs'
|
||||
import { DynamicOrgDocs } from 'shared/components/dynamic-docs/org.mjs'
|
||||
|
||||
export const ns = ['account', 'toast']
|
||||
export const ns = ['account', 'status']
|
||||
|
||||
export const UsernameSettings = ({ welcome = false }) => {
|
||||
// Hooks
|
||||
const { account, setAccount } = useAccount()
|
||||
const backend = useBackend()
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
const [username, setUsername] = useState(account.username)
|
||||
const [available, setAvailable] = useState(true)
|
||||
|
@ -52,7 +53,6 @@ export const UsernameSettings = ({ welcome = false }) => {
|
|||
|
||||
return (
|
||||
<div className="max-w-xl">
|
||||
<LoadingStatus />
|
||||
<StringInput
|
||||
id="account-username"
|
||||
label={t('usernameTitle')}
|
||||
|
|
|
@ -1,33 +1,36 @@
|
|||
import { useState, useEffect } from 'react'
|
||||
// Depdendencies
|
||||
import { cloudflareConfig } from 'shared/config/cloudflare.mjs'
|
||||
import { freeSewingConfig } from 'shared/config/freesewing.config.mjs'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useState, useEffect, useContext } from 'react'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useToast } from 'shared/hooks/use-toast.mjs'
|
||||
// Components
|
||||
import Link from 'next/link'
|
||||
import Markdown from 'react-markdown'
|
||||
|
||||
import { Json } from 'shared/components/json.mjs'
|
||||
import Markdown from 'react-markdown'
|
||||
import { AccountRole } from 'shared/components/account/role.mjs'
|
||||
import { AccountStatus } from 'shared/components/account/status.mjs'
|
||||
import { Loading } from 'shared/components/spinner.mjs'
|
||||
|
||||
import { freeSewingConfig } from 'shared/config/freesewing.config.mjs'
|
||||
|
||||
const roles = ['user', 'curator', 'bughunter', 'support', 'admin']
|
||||
|
||||
export const ImpersonateButton = ({ userId }) => {
|
||||
const toast = useToast()
|
||||
const backend = useBackend()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const { impersonate } = useAccount()
|
||||
|
||||
if (!userId) return null
|
||||
|
||||
const impersonateUser = async () => {
|
||||
setLoadingStatus([true, 'status:contactingBackend'])
|
||||
const result = await backend.adminImpersonateUser(userId)
|
||||
if (result.success) {
|
||||
impersonate(result.data)
|
||||
toast.for.settingsSaved()
|
||||
} else toast.for.backendError()
|
||||
setLoadingStatus([true, 'status:settingsSaved', true, true])
|
||||
} else setLoadingStatus([true, 'status:backendError', true, false])
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -132,7 +135,7 @@ export const User = ({ user }) => (
|
|||
export const ManageUser = ({ userId }) => {
|
||||
// Hooks
|
||||
const backend = useBackend()
|
||||
const toast = useToast()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
// State
|
||||
const [user, setUser] = useState({})
|
||||
|
@ -147,11 +150,12 @@ export const ManageUser = ({ userId }) => {
|
|||
}, [userId])
|
||||
|
||||
const updateUser = async (data) => {
|
||||
setLoadingStatus([true, 'status:contactingBackend'])
|
||||
const result = await backend.adminUpdateUser({ id: userId, data })
|
||||
if (result.success) {
|
||||
toast.for.settingsSaved()
|
||||
setLoadingStatus([true, 'status:settingsSaved', true, true])
|
||||
setUser(result.data.user)
|
||||
} else toast.for.backendError()
|
||||
} else setLoadingStatus([true, 'status:backendError', true, false])
|
||||
}
|
||||
|
||||
return user.id ? (
|
||||
|
|
72
sites/shared/components/bookmarks.mjs
Normal file
72
sites/shared/components/bookmarks.mjs
Normal file
|
@ -0,0 +1,72 @@
|
|||
// Dependencies
|
||||
import { horFlexClasses, notEmpty } from 'shared/utils.mjs'
|
||||
// Hooks
|
||||
import { useContext, useState } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
// Context
|
||||
import { ModalContext } from 'shared/context/modal-context.mjs'
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Components
|
||||
import { ModalWrapper } from 'shared/components/wrappers/modal.mjs'
|
||||
import { BookmarkIcon } from 'shared/components/icons.mjs'
|
||||
import { StringInput } from 'shared/components/inputs.mjs'
|
||||
|
||||
export const ns = 'account'
|
||||
|
||||
export const CreateBookmark = ({ type, title, slug }) => {
|
||||
const backend = useBackend()
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
const [name, setName] = useState(title)
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const { setModal } = useContext(ModalContext)
|
||||
|
||||
const url = i18n.language === 'en' ? `/${slug}` : `/${lang}/${slug}`
|
||||
|
||||
const bookmark = async (evt) => {
|
||||
evt.stopPropagation()
|
||||
setLoadingStatus([true, 'status:contactingBackend'])
|
||||
const result = await backend.createBookmark({ type, title, url })
|
||||
if (result.success) {
|
||||
setLoadingStatus([true, 'status:nailedIt', true, true])
|
||||
setModal(false)
|
||||
} else setLoadingStatus([true, 'backendError', true, false])
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2>{t('account:bookmarkThisPage')}</h2>
|
||||
<StringInput
|
||||
label={t('account:title')}
|
||||
current={name}
|
||||
update={setName}
|
||||
valid={notEmpty}
|
||||
labelBL={url}
|
||||
/>
|
||||
<button className="btn btn-primary w-full mt-4" onClick={bookmark}>
|
||||
<span>{t('account:bookmarkThisPage')}</span>
|
||||
</button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export const BookmarkButton = ({ slug, type, title }) => {
|
||||
const { t } = useTranslation('account')
|
||||
const { setModal } = useContext(ModalContext)
|
||||
|
||||
return (
|
||||
<button
|
||||
className={`btn btn-secondary btn-outline ${horFlexClasses}`}
|
||||
onClick={() =>
|
||||
setModal(
|
||||
<ModalWrapper flex="col" justify="top lg:justify-center" slideFrom="right">
|
||||
<CreateBookmark {...{ type, title, slug }} />
|
||||
</ModalWrapper>
|
||||
)
|
||||
}
|
||||
>
|
||||
<BookmarkIcon />
|
||||
<span>{t('account:bookmarkThisPage')}</span>
|
||||
</button>
|
||||
)
|
||||
}
|
|
@ -2,14 +2,14 @@
|
|||
import { useContext } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingContext } from 'shared/context/loading-context.mjs'
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Components
|
||||
import { Spinner } from 'shared/components/spinner.mjs'
|
||||
import Link from 'next/link'
|
||||
|
||||
export const ContinueButton = ({ btnProps = {}, link = false }) => {
|
||||
// Context
|
||||
const { loading } = useContext(LoadingContext)
|
||||
const { loading } = useContext(LoadingStatusContext)
|
||||
|
||||
// Hooks
|
||||
const { t } = useTranslation(['account'])
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
import { useContext } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingContext } from 'shared/context/loading-context.mjs'
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Components
|
||||
import { Spinner } from 'shared/components/spinner.mjs'
|
||||
|
||||
export const SaveSettingsButton = ({ btnProps = {}, welcome = false, label = false }) => {
|
||||
const { loading } = useContext(LoadingContext)
|
||||
const { loading } = useContext(LoadingStatusContext)
|
||||
const { t } = useTranslation(['account'])
|
||||
let classes = 'btn mt-4 capitalize '
|
||||
if (welcome) {
|
||||
|
|
|
@ -7,9 +7,9 @@ import { shortDate, cloudflareImageUrl, capitalize } from 'shared/utils.mjs'
|
|||
// Hooks
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Context
|
||||
import { ModalContext } from 'shared/context/modal-context.mjs'
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Components
|
||||
import { DisplayRow } from './account/shared.mjs'
|
||||
import { ModalWrapper } from 'shared/components/wrappers/modal.mjs'
|
||||
|
@ -135,7 +135,7 @@ const ShowCuratedSet = ({ cset }) => {
|
|||
|
||||
export const CuratedSet = ({ id }) => {
|
||||
// Hooks
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const backend = useBackend()
|
||||
|
||||
// State
|
||||
|
@ -158,7 +158,6 @@ export const CuratedSet = ({ id }) => {
|
|||
|
||||
return (
|
||||
<div className="max-w-2xl">
|
||||
<LoadingStatus />
|
||||
<ShowCuratedSet cset={cset} />
|
||||
</div>
|
||||
)
|
||||
|
@ -168,7 +167,7 @@ export const CuratedSet = ({ id }) => {
|
|||
export const CuratedSets = () => {
|
||||
// Hooks
|
||||
const backend = useBackend()
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
// State
|
||||
const [sets, setSets] = useState([])
|
||||
|
@ -191,7 +190,6 @@ export const CuratedSets = () => {
|
|||
|
||||
return (
|
||||
<div className="max-w-7xl xl:pl-4">
|
||||
<LoadingStatus />
|
||||
<SetLineup sets={Object.values(sets)} onClick={setSelected} />
|
||||
{selected && <ShowCuratedSet cset={sets[selected]} />}
|
||||
</div>
|
||||
|
|
|
@ -3,12 +3,12 @@ import { cloudflareImageUrl } from 'shared/utils.mjs'
|
|||
import { collection } from 'shared/hooks/use-design.mjs'
|
||||
// Context
|
||||
import { ModalContext } from 'shared/context/modal-context.mjs'
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useState, useCallback, useContext } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { useDropzone } from 'react-dropzone'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import Markdown from 'react-markdown'
|
||||
import { ResetIcon, DocsIcon, UploadIcon } from 'shared/components/icons.mjs'
|
||||
|
@ -278,7 +278,7 @@ export const ImageInput = ({
|
|||
}) => {
|
||||
const { t } = useTranslation(ns)
|
||||
const backend = useBackend()
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const [url, setUrl] = useState(false)
|
||||
const [uploadedId, setUploadedId] = useState(false)
|
||||
|
||||
|
@ -316,7 +316,6 @@ export const ImageInput = ({
|
|||
if (current)
|
||||
return (
|
||||
<FormControl label={label} docs={docs}>
|
||||
<LoadingStatus />
|
||||
<div
|
||||
className="bg-base-100 w-full h-36 mb-2 mx-auto flex flex-col items-center text-center justify-center"
|
||||
style={{
|
||||
|
@ -340,7 +339,6 @@ export const ImageInput = ({
|
|||
|
||||
return (
|
||||
<FormControl label={label} docs={docs} forId={id}>
|
||||
<LoadingStatus />
|
||||
<div
|
||||
{...getRootProps()}
|
||||
className={`
|
||||
|
|
|
@ -1,13 +1,19 @@
|
|||
import { useState, useEffect } from 'react'
|
||||
import { siteConfig } from 'site/site.config.mjs'
|
||||
import { horFlexClasses } from 'shared/utils.mjs'
|
||||
// List of authors
|
||||
import { authors as allAuthors } from 'config/authors.mjs'
|
||||
import { docUpdates } from 'site/prebuild/doc-updates.mjs'
|
||||
// Components
|
||||
import { PageLink } from 'shared/components/link.mjs'
|
||||
import { TimeAgo } from 'shared/components/timeago/index.mjs'
|
||||
// Hooks
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { EditIcon } from 'shared/components/icons.mjs'
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
// Components
|
||||
import { PageLink } from 'shared/components/link.mjs'
|
||||
import { TimeAgo } from 'shared/components/timeago/index.mjs'
|
||||
import { BookmarkButton } from 'shared/components/bookmarks.mjs'
|
||||
|
||||
export const ns = 'account'
|
||||
|
||||
const PersonList = ({ list }) =>
|
||||
list ? (
|
||||
|
@ -54,11 +60,19 @@ const CreditsList = ({ updates, frontmatter, locale, t }) => (
|
|||
)
|
||||
|
||||
export const MdxMetaData = ({ frontmatter, locale, slug }) => {
|
||||
const { t } = useTranslation('docs')
|
||||
const { control } = useAccount()
|
||||
const { t, i18n } = useTranslation('docs')
|
||||
|
||||
const [localControl, setLocalControl] = useState(1)
|
||||
|
||||
// Prevent hydration issues
|
||||
useEffect(() => {
|
||||
setLocalControl(control)
|
||||
}, [])
|
||||
|
||||
const updates = docUpdates[slug] || {}
|
||||
frontmatter.maintainers = ['joostdecock']
|
||||
locale = 'fr'
|
||||
locale = i18n.language
|
||||
|
||||
/*
|
||||
* FIXME
|
||||
|
@ -70,13 +84,18 @@ export const MdxMetaData = ({ frontmatter, locale, slug }) => {
|
|||
|
||||
return (
|
||||
<div className="hidden xl:block mb-4">
|
||||
{localControl > 2 && (
|
||||
<div className="flex flex-col gap-2 max-w-xs">
|
||||
<a
|
||||
href={`https://github.dev/freesewing/freesewing/blob/develop/markdown/${siteConfig.tld}/${slug}/en.md`}
|
||||
className="btn btn-success flex flex-row justify-between items-center w-full px-4 bg-gradient-to-r from-primary to-accent mb-4 hover:from-accent hover:to-accent"
|
||||
className={`btn btn-secondary btn-outline ${horFlexClasses}`}
|
||||
>
|
||||
<EditIcon />
|
||||
<span>{t('editThisPage')}</span>
|
||||
</a>
|
||||
<BookmarkButton slug={slug} title={frontmatter.title} type="doc" />
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className={`
|
||||
mdx mdx-toc text-base-content text-base
|
||||
|
|
|
@ -4,8 +4,8 @@ import { useState, useContext, useEffect } 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'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
import { NavigationContext } from 'shared/context/navigation-context.mjs'
|
||||
// Components
|
||||
import Markdown from 'react-markdown'
|
||||
|
@ -27,11 +27,12 @@ import { Link, PageLink } from 'shared/components/link.mjs'
|
|||
import { Popout } from 'shared/components/popout/index.mjs'
|
||||
import { EditRow } from 'shared/components/account/patterns.mjs'
|
||||
|
||||
export const ns = [...ns404, 'toast']
|
||||
export const ns = ns404
|
||||
|
||||
export const ManagePattern = ({ id = false }) => {
|
||||
// Context
|
||||
const { addPages } = useContext(NavigationContext)
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
// State
|
||||
const [pattern, setPattern] = useState({})
|
||||
|
@ -42,7 +43,6 @@ export const ManagePattern = ({ id = false }) => {
|
|||
const backend = useBackend()
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
const { language } = i18n
|
||||
const toast = useToast()
|
||||
|
||||
// async effect helper
|
||||
const loadPattern = async () => {
|
||||
|
@ -82,7 +82,7 @@ export const ManagePattern = ({ id = false }) => {
|
|||
if (result.success) {
|
||||
if (result.data.pattern) {
|
||||
setPattern(result.data.pattern)
|
||||
toast.for.settingsSaved()
|
||||
setLoadingStatus([true, 'settingsSaved', true, true])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -125,17 +125,13 @@ export const ManagePattern = ({ id = false }) => {
|
|||
<>
|
||||
<h2>{t('update')}</h2>
|
||||
{/* Name is always shown */}
|
||||
<EditRow title={t('name')} field="name" {...{ pattern, backend, t, toast, refresh }}>
|
||||
<EditRow title={t('name')} field="name" {...{ pattern, backend, t, refresh }}>
|
||||
{pattern.name}
|
||||
</EditRow>
|
||||
|
||||
{/* img: Control level determines whether or not to show this */}
|
||||
{pattern.id && account.control >= conf.account.patterns.img ? (
|
||||
<EditRow
|
||||
title={t('image')}
|
||||
field="img"
|
||||
{...{ pattern, backend, t, toast, refresh }}
|
||||
>
|
||||
<EditRow title={t('image')} field="img" {...{ pattern, backend, t, refresh }}>
|
||||
<img
|
||||
src={pattern.img}
|
||||
className="w-10 mask mask-squircle bg-neutral aspect-square"
|
||||
|
@ -145,11 +141,7 @@ export const ManagePattern = ({ id = false }) => {
|
|||
|
||||
{/* notes: Control level determines whether or not to show this */}
|
||||
{account.control >= conf.account.patterns.notes ? (
|
||||
<EditRow
|
||||
title={t('notes')}
|
||||
field="notes"
|
||||
{...{ pattern, backend, t, toast, refresh }}
|
||||
>
|
||||
<EditRow title={t('notes')} field="notes" {...{ pattern, backend, t, refresh }}>
|
||||
<Markdown>{pattern.notes}</Markdown>
|
||||
</EditRow>
|
||||
) : null}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// Hooks
|
||||
import { useContext } from 'react'
|
||||
// Context
|
||||
import { LoadingContext } from 'shared/context/loading-context.mjs'
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
|
||||
export const Ribbon = () => {
|
||||
const { loading } = useContext(LoadingContext)
|
||||
const { loading } = useContext(LoadingStatusContext)
|
||||
|
||||
return (
|
||||
<div
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Dependencies
|
||||
import { cloudflareImageUrl, nsMerge } from 'shared/utils.mjs'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
import { useRouter } from 'next/router'
|
||||
// Components
|
||||
import { AuthWrapper } from 'shared/components/wrappers/auth/index.mjs'
|
||||
|
@ -20,7 +21,7 @@ export const CsetSubmission = ({ id }) => {
|
|||
// Hooks
|
||||
const { t } = useTranslation(ns)
|
||||
const backend = useBackend()
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const router = useRouter()
|
||||
|
||||
const [submission, setSubmission] = useState(false)
|
||||
|
@ -57,7 +58,6 @@ export const CsetSubmission = ({ id }) => {
|
|||
|
||||
return (
|
||||
<div className="max-w-2xl">
|
||||
<LoadingStatus />
|
||||
<DisplayRow title={t('account:name')} keyWidth="w-48">
|
||||
{submission.name}
|
||||
</DisplayRow>
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { freeSewingConfig as config } from 'shared/config/freesewing.config.mjs'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { useState, Fragment } from 'react'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
// Components
|
||||
|
@ -118,7 +119,7 @@ const SupportType = ({ type, active, t, update }) => (
|
|||
|
||||
export const SupportForm = () => {
|
||||
const { t } = useTranslation(ns)
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const { account } = useAccount()
|
||||
const backend = useBackend()
|
||||
|
||||
|
@ -212,7 +213,6 @@ export const SupportForm = () => {
|
|||
|
||||
return (
|
||||
<div className="w-full max-w-4xl mx-auto">
|
||||
<LoadingStatus />
|
||||
<SupportType type={type} active={true} update={() => setType(false)} t={t} />
|
||||
<StringInput
|
||||
id="support-title"
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useState } from 'react'
|
||||
import { useState, useContext } from 'react'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useRouter } from 'next/router'
|
||||
// Components
|
||||
|
@ -24,7 +25,7 @@ const DarkLink = ({ href, txt }) => (
|
|||
export const Migrate = () => {
|
||||
const backend = useBackend()
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
const { setLoadingStatus, LoadingStatus, loading } = useLoadingStatus()
|
||||
const { loading, setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const { setAccount, setSeenUser, setToken } = useAccount()
|
||||
const router = useRouter()
|
||||
|
||||
|
@ -61,14 +62,12 @@ export const Migrate = () => {
|
|||
if (result === 'success')
|
||||
return (
|
||||
<>
|
||||
<LoadingStatus />
|
||||
<FreeSewingAnimation />
|
||||
</>
|
||||
)
|
||||
if (result === 'exists')
|
||||
return (
|
||||
<>
|
||||
<LoadingStatus />
|
||||
<h2 className="text-inherit">{t('signup:v3UserAlreadyExists')}</h2>
|
||||
<Robot pose="shrug" className="m-auto w-56 text-inherit" embed />
|
||||
<Link href="/signin" className="btn btn-primary w-full my-4">
|
||||
|
@ -87,7 +86,6 @@ export const Migrate = () => {
|
|||
if (result === 'failed')
|
||||
return (
|
||||
<>
|
||||
<LoadingStatus />
|
||||
<h2 className="text-inherit">{t('signup:noWorkie')}</h2>
|
||||
<Robot pose="ohno" className="m-auto w-56 text-inherit" embed />
|
||||
<Link href="/signup" className="btn btn-primary w-full my-4">
|
||||
|
@ -106,7 +104,6 @@ export const Migrate = () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<LoadingStatus />
|
||||
<h2 className="text-inherit">{t('signup:migrateV2')}</h2>
|
||||
<p className="text-inherit">{t('migrateV2Desc')}</p>
|
||||
<div className="text-base-content">
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useState, useEffect } from 'react'
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
import { horFlexClasses, horFlexClassesNoSm, capitalize } from 'shared/utils.mjs'
|
||||
// Components
|
||||
import Link from 'next/link'
|
||||
|
@ -28,7 +29,7 @@ export const SignIn = () => {
|
|||
const { t, i18n } = useTranslation(ns)
|
||||
const backend = useBackend()
|
||||
const router = useRouter()
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
const [username, setUsername] = useState('')
|
||||
const [password, setPassword] = useState('')
|
||||
|
@ -117,7 +118,6 @@ export const SignIn = () => {
|
|||
if (magicLinkSent)
|
||||
return (
|
||||
<>
|
||||
<LoadingStatus />
|
||||
<h1 className="text-inherit text-3xl lg:text-5xl mb-4 pb-0 text-center">
|
||||
{t('susi:emailSent')}
|
||||
</h1>
|
||||
|
@ -138,7 +138,6 @@ export const SignIn = () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<LoadingStatus />
|
||||
<h2>{seenBefore ? t('susi:welcomeBackName', { name: seenUser }) : t('susi:welcome')}</h2>
|
||||
<p>{t('susi:signInToThing', { thing: 'FreeSewing' })}:</p>
|
||||
{!seenBefore && (
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
import { useState, useContext } from 'react'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
import { ModalContext } from 'shared/context/modal-context.mjs'
|
||||
// Dependencies
|
||||
import { validateEmail, validateTld, horFlexClasses, horFlexClassesNoSm } from 'shared/utils.mjs'
|
||||
|
@ -32,7 +32,7 @@ export const SignUp = () => {
|
|||
|
||||
const backend = useBackend()
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
const [email, setEmail] = useState('')
|
||||
const [emailValid, setEmailValid] = useState(false)
|
||||
|
@ -98,7 +98,6 @@ export const SignUp = () => {
|
|||
|
||||
return (
|
||||
<div className="w-full">
|
||||
<LoadingStatus />
|
||||
<h2 className="text-inherit">
|
||||
{result ? (
|
||||
result === 'success' ? (
|
||||
|
|
|
@ -1,22 +1,26 @@
|
|||
// Dependencies
|
||||
import yaml from 'js-yaml'
|
||||
import { validateSettings } from './settings-validator.mjs'
|
||||
import { capitalize } from 'shared/utils.mjs'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useEffect, useState, useRef, useMemo } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { useToast } from 'shared/hooks/use-toast.mjs'
|
||||
// Components
|
||||
import { CloseIcon } from 'shared/components/icons.mjs'
|
||||
import { capitalize } from 'shared/utils.mjs'
|
||||
import { V3Wip } from 'shared/components/v3-wip.mjs'
|
||||
|
||||
export const ns = ['wbedit']
|
||||
export const ns = []
|
||||
|
||||
/** a view for editing the gist as yaml */
|
||||
export const EditView = ({ settings, setSettings, design, Design }) => {
|
||||
const inputRef = useRef(null)
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const [error, setError] = useState(false)
|
||||
const [success, setSuccess] = useState(false)
|
||||
const { t } = useTranslation(ns)
|
||||
const patternConfig = useMemo(() => new Design().getConfig(), [Design])
|
||||
const toast = useToast()
|
||||
|
||||
// parse the settings to yaml and set them as the value on the textArea
|
||||
useEffect(() => {
|
||||
|
@ -29,6 +33,7 @@ export const EditView = ({ settings, setSettings, design, Design }) => {
|
|||
setSuccess(false)
|
||||
|
||||
try {
|
||||
setLoadingStatus([true, 'status:contactingBackend'])
|
||||
// parse back to json
|
||||
const editedAsJson = yaml.load(inputRef.current.value)
|
||||
|
||||
|
@ -43,7 +48,7 @@ export const EditView = ({ settings, setSettings, design, Design }) => {
|
|||
// save regardless
|
||||
setSettings(editedAsJson)
|
||||
setSuccess(true)
|
||||
if (validation.valid) toast.success(t('success'))
|
||||
if (validation.valid) setLoadingStatus([true, 'status:settingsSaved', true, true])
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
setError(e.message)
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
import { useState, useContext } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { Popout } from 'shared/components/popout/index.mjs'
|
||||
import { WebLink } from 'shared/components/link.mjs'
|
||||
import { LoadingContext } from 'shared/context/loading-context.mjs'
|
||||
import { useToast } from 'shared/hooks/use-toast.mjs'
|
||||
// Dependencies
|
||||
import {
|
||||
exportTypes,
|
||||
handleExport,
|
||||
ns as exportNs,
|
||||
} from 'shared/components/workbench/exporting/export-handler.mjs'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useState, useContext } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Components
|
||||
import { Popout } from 'shared/components/popout/index.mjs'
|
||||
import { WebLink } from 'shared/components/link.mjs'
|
||||
import { V3Wip } from 'shared/components/v3-wip.mjs'
|
||||
|
||||
export const ns = ['exporting', exportNs]
|
||||
|
@ -16,8 +19,10 @@ export const ns = ['exporting', exportNs]
|
|||
export const ExportView = ({ settings, ui, design, Design }) => {
|
||||
const [link, setLink] = useState(false)
|
||||
const [format, setFormat] = useState(false)
|
||||
const { startLoading, stopLoading } = useContext(LoadingContext)
|
||||
const toast = useToast()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
const startLoading = () => setLoadingStatus([true, 'exporting'])
|
||||
const stopLoading = () => setLoadingStatus([true, 'status:nailedIt', true, true])
|
||||
|
||||
const { t } = useTranslation(ns)
|
||||
const doExport = (format) => {
|
||||
|
@ -38,7 +43,7 @@ export const ExportView = ({ settings, ui, design, Design }) => {
|
|||
}
|
||||
},
|
||||
onError: (e) => {
|
||||
if (e.data?.error) toast.error(e.data.error.message)
|
||||
if (e.data?.error) setLoadingStatus([true, e.data.error.message, true, false])
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
|
@ -5,7 +5,8 @@ import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs'
|
|||
import { designMeasurements, horFlexClasses } from 'shared/utils.mjs'
|
||||
// Hooks
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Components
|
||||
import {
|
||||
UserSetPicker,
|
||||
|
@ -24,7 +25,7 @@ const iconClasses = { className: 'w-8 h-8 md:w-10 md:h-10 lg:w-12 lg:h-12 shrink
|
|||
|
||||
export const MeasiesView = ({ design, Design, settings, update, missingMeasurements, setView }) => {
|
||||
const { t } = useTranslation(['workbench'])
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
const loadMeasurements = (set) => {
|
||||
update.settings([
|
||||
|
@ -37,7 +38,6 @@ export const MeasiesView = ({ design, Design, settings, update, missingMeasureme
|
|||
|
||||
return (
|
||||
<div className="max-w-7xl mt-8 mx-auto px-4">
|
||||
<LoadingStatus />
|
||||
<h2>{t('account:measurements')}</h2>
|
||||
{missingMeasurements &&
|
||||
settings.measurements &&
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
import { useContext } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { pagesPlugin } from 'shared/plugins/plugin-layout-part.mjs'
|
||||
// Dependencies
|
||||
import { nsMerge } from 'shared/utils.mjs'
|
||||
import {
|
||||
handleExport,
|
||||
ns as exportNs,
|
||||
} from 'shared/components/workbench/exporting/export-handler.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
import { pagesPlugin } from 'shared/plugins/plugin-layout-part.mjs'
|
||||
import get from 'lodash.get'
|
||||
import { defaultPrintSettings, printSettingsPath } from './config.mjs'
|
||||
// Hooks
|
||||
import { useContext } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Components
|
||||
import { MovablePattern } from 'shared/components/workbench/pattern/movable/index.mjs'
|
||||
import { PrintMenu, ns as menuNs } from './menu.mjs'
|
||||
import { defaultPrintSettings, printSettingsPath } from './config.mjs'
|
||||
import { LoadingContext } from 'shared/context/loading-context.mjs'
|
||||
import { PatternWithMenu, ns as wrapperNs } from '../pattern-with-menu.mjs'
|
||||
import { nsMerge } from 'shared/utils.mjs'
|
||||
|
||||
export const ns = nsMerge(menuNs, wrapperNs, exportNs, 'print', 'status')
|
||||
|
||||
|
@ -30,8 +33,7 @@ export const PrintView = ({
|
|||
Design,
|
||||
}) => {
|
||||
const { t } = useTranslation(ns)
|
||||
const loading = useContext(LoadingContext)
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { loading, setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
const defaultSettings = defaultPrintSettings(settings.units)
|
||||
// add the pages plugin to the draft
|
||||
|
@ -74,7 +76,6 @@ export const PrintView = ({
|
|||
|
||||
return (
|
||||
<>
|
||||
<LoadingStatus />
|
||||
<PatternWithMenu
|
||||
noHeader
|
||||
{...{
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
// Dependencies
|
||||
import { capitalize, shortDate, notEmpty, horFlexClassesNoSm } from 'shared/utils.mjs'
|
||||
import yaml from 'js-yaml'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
// Components
|
||||
import { AuthWrapper } from 'shared/components/wrappers/auth/index.mjs'
|
||||
import { StringInput, MarkdownInput } from 'shared/components/inputs.mjs'
|
||||
|
@ -22,7 +23,7 @@ export const SaveView = ({ design, settings }) => {
|
|||
const { t } = useTranslation(ns)
|
||||
const backend = useBackend()
|
||||
const router = useRouter()
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
// State
|
||||
const [name, setName] = useState(`${capitalize(design)} / ${shortDate(router.locale)}`)
|
||||
|
@ -80,7 +81,6 @@ export const SaveView = ({ design, settings }) => {
|
|||
|
||||
return (
|
||||
<AuthWrapper>
|
||||
<LoadingStatus />
|
||||
<div className="m-auto mt-8 max-w-2xl px-4">
|
||||
<h2>{t('workbench:savePattern')}</h2>
|
||||
{savedId && (
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
// Dependencies
|
||||
import { capitalize, shortDate } from 'shared/utils.mjs'
|
||||
// Hooks
|
||||
import { useContext, useMemo } from 'react'
|
||||
import { PanZoomContext } from 'shared/components/workbench/pattern/pan-zoom-context.mjs'
|
||||
import { useMobileAction } from 'shared/context/mobile-menubar-context.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Components
|
||||
import { PanZoomContext } from 'shared/components/workbench/pattern/pan-zoom-context.mjs'
|
||||
import {
|
||||
PaperlessIcon,
|
||||
SaIcon,
|
||||
|
@ -17,8 +23,6 @@ import {
|
|||
ZoomOutIcon,
|
||||
} from 'shared/components/icons.mjs'
|
||||
import { shownHeaderSelector } from 'shared/components/wrappers/header.mjs'
|
||||
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
|
||||
import { capitalize, shortDate } from 'shared/utils.mjs'
|
||||
|
||||
export const ns = ['common', 'core-settings', 'ui-settings']
|
||||
|
||||
|
@ -73,7 +77,7 @@ export const ViewHeader = ({ update, settings, ui, control, account, design, set
|
|||
const { t, i18n } = useTranslation(ns)
|
||||
const { zoomFunctions, zoomed } = useContext(PanZoomContext)
|
||||
const backend = useBackend()
|
||||
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
// make the zoom buttons so we can pass them to the mobile menubar
|
||||
const headerZoomButtons = useMemo(
|
||||
|
@ -127,7 +131,6 @@ export const ViewHeader = ({ update, settings, ui, control, account, design, set
|
|||
'lg:top-24'
|
||||
)} transition-[top] duration-300 ease-in-out`}
|
||||
>
|
||||
<LoadingStatus />
|
||||
<div className="hidden lg:flex flex-row flex-wrap gap-4 py-4 pt-8 w-full bg-neutral text-neutral-content items-center justify-center">
|
||||
{headerZoomButtons}
|
||||
<Spacer />
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import { ModalContextProvider } from 'shared/context/modal-context.mjs'
|
||||
import { LoadingContextProvider } from 'shared/context/loading-context.mjs'
|
||||
import { LoadingStatusContextProvider } from 'shared/context/loading-status-context.mjs'
|
||||
import { NavigationContextProvider } from 'shared/context/navigation-context.mjs'
|
||||
import { MobileMenubarContextProvider } from 'shared/context/mobile-menubar-context.mjs'
|
||||
|
||||
export const ContextWrapper = ({ children }) => (
|
||||
<ModalContextProvider>
|
||||
<LoadingContextProvider>
|
||||
<LoadingStatusContextProvider>
|
||||
<NavigationContextProvider>
|
||||
<MobileMenubarContextProvider>{children}</MobileMenubarContextProvider>
|
||||
</NavigationContextProvider>
|
||||
</LoadingContextProvider>
|
||||
</LoadingStatusContextProvider>
|
||||
</ModalContextProvider>
|
||||
)
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useContext } from 'react'
|
||||
import { LoadingContext } from 'shared/context/loading-context.mjs'
|
||||
import { Ribbon } from 'shared/components/ribbon.mjs'
|
||||
|
||||
export const HeaderWrapper = ({ show, children }) => {
|
||||
const { loading } = useContext(LoadingContext)
|
||||
const { loading } = useContext(LoadingStatusContext)
|
||||
return (
|
||||
<header
|
||||
className={`
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Dependencies
|
||||
import React, { useState, useEffect, useContext } from 'react'
|
||||
import { nsMerge } from 'shared/utils.mjs'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
import { useTheme } from 'shared/hooks/use-theme.mjs'
|
||||
// Components
|
||||
|
@ -11,7 +13,7 @@ import { DefaultLayout, ns as defaultLayoutNs } from 'site/components/layouts/de
|
|||
import { Feeds } from 'site/components/feeds.mjs'
|
||||
import { ModalContext } from 'shared/context/modal-context.mjs'
|
||||
|
||||
export const ns = nsMerge(layoutNs, defaultLayoutNs, 'common')
|
||||
export const ns = nsMerge(layoutNs, defaultLayoutNs, 'status')
|
||||
|
||||
/* This component should wrap all page content */
|
||||
export const PageWrapper = (props) => {
|
||||
|
@ -32,6 +34,7 @@ export const PageWrapper = (props) => {
|
|||
* Contexts
|
||||
*/
|
||||
const { modalContent } = useContext(ModalContext)
|
||||
const { LoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
/*
|
||||
* This forces a re-render upon initial bootstrap of the app
|
||||
|
@ -59,6 +62,7 @@ export const PageWrapper = (props) => {
|
|||
data-theme={currentTheme} // This facilitates CSS selectors
|
||||
key={currentTheme} // This forces the data-theme update
|
||||
>
|
||||
<LoadingStatus />
|
||||
<Feeds />
|
||||
<LayoutWrapper {...childProps}>
|
||||
{Layout ? <Layout {...childProps}>{children}</Layout> : children}
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
import React, { useState } from 'react'
|
||||
|
||||
export const LoadingContext = React.createContext(false)
|
||||
|
||||
export const LoadingContextProvider = ({ children }) => {
|
||||
function stopLoading() {
|
||||
__setLoading({ ...__loading, loading: false })
|
||||
}
|
||||
function startLoading() {
|
||||
__setLoading({ ...__loading, loading: true })
|
||||
}
|
||||
function setLoading(loading) {
|
||||
__setLoading({ ...__loading, loading })
|
||||
}
|
||||
|
||||
const [__loading, __setLoading] = useState({
|
||||
setLoading,
|
||||
startLoading,
|
||||
stopLoading,
|
||||
loading: false,
|
||||
})
|
||||
|
||||
return <LoadingContext.Provider value={__loading}>{children}</LoadingContext.Provider>
|
||||
}
|
|
@ -1,10 +1,12 @@
|
|||
import { useState, useEffect } from 'react'
|
||||
import { useState, useEffect, createContext } from 'react'
|
||||
import { Spinner } from 'shared/components/spinner.mjs'
|
||||
import { OkIcon, WarningIcon } from 'shared/components/icons.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
|
||||
export const ns = ['status']
|
||||
|
||||
export const LoadingStatusContext = createContext([false])
|
||||
|
||||
/*
|
||||
* Timeout in seconds before the loading status dissapears
|
||||
*/
|
||||
|
@ -20,12 +22,9 @@ const LoadingStatus = ({ loadingStatus }) => {
|
|||
if (loadingStatus[2]) {
|
||||
if (timer) clearTimeout(timer)
|
||||
setTimer(
|
||||
window.setTimeout(
|
||||
() => {
|
||||
window.setTimeout(() => {
|
||||
setFade('opacity-0')
|
||||
},
|
||||
timeout * 1000 - 350
|
||||
)
|
||||
}, timeout * 1000 - 350)
|
||||
)
|
||||
}
|
||||
}, [loadingStatus[2]])
|
||||
|
@ -66,7 +65,7 @@ const LoadingProgress = ({ val = 0, max = 1, msg }) => (
|
|||
</div>
|
||||
)
|
||||
|
||||
export const useLoadingStatus = () => {
|
||||
export const LoadingStatusContextProvider = ({ children }) => {
|
||||
/*
|
||||
* LoadingStatus should hold an array with 1 to 4 elements:
|
||||
* 0 => Show loading status or not (true or false)
|
||||
|
@ -74,11 +73,18 @@ export const useLoadingStatus = () => {
|
|||
* 2 => Set this to true to make the loadingStatus dissapear after 2 seconds
|
||||
* 3 => Set this to true to show success, false to show error (only when 2 is true)
|
||||
*/
|
||||
const [loadingStatus, setLoadingStatus] = useState([false])
|
||||
const [timer, setTimer] = useState(false)
|
||||
|
||||
const [__loadingStatus, __setLoadingStatus] = useState({
|
||||
status: [false],
|
||||
setLoadingStatus,
|
||||
loading: false,
|
||||
LoadingStatus: () => <LoadingStatus loadingStatus={[false]} />,
|
||||
LoadingProgress,
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (loadingStatus[2]) {
|
||||
if (__loadingStatus.status[2]) {
|
||||
if (timer) clearTimeout(timer)
|
||||
setTimer(
|
||||
window.setTimeout(() => {
|
||||
|
@ -86,12 +92,20 @@ export const useLoadingStatus = () => {
|
|||
}, timeout * 1000)
|
||||
)
|
||||
}
|
||||
}, [loadingStatus[2]])
|
||||
}, [__loadingStatus.status[2]])
|
||||
|
||||
return {
|
||||
setLoadingStatus,
|
||||
loading: loadingStatus[0],
|
||||
LoadingStatus: () => <LoadingStatus loadingStatus={loadingStatus} />,
|
||||
LoadingProgress,
|
||||
function setLoadingStatus(newStatus) {
|
||||
__setLoadingStatus({
|
||||
...__loadingStatus,
|
||||
status: newStatus,
|
||||
loading: newStatus[0] || false,
|
||||
LoadingStatus: () => <LoadingStatus loadingStatus={newStatus} />,
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<LoadingStatusContext.Provider value={__loadingStatus}>
|
||||
{children}
|
||||
</LoadingStatusContext.Provider>
|
||||
)
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
import { useTranslation } from 'next-i18next'
|
||||
import toastMethod from 'react-hot-toast'
|
||||
import { OkIcon, NoIcon, TipIcon, WarningIcon, ChatIcon } from 'shared/components/icons.mjs'
|
||||
|
||||
const icons = {
|
||||
success: <OkIcon className="w-6 h-6 text-success" />,
|
||||
error: <NoIcon className="w-6 h-6 text-error" />,
|
||||
info: <TipIcon className="w-6 h-6 text-info" />,
|
||||
warning: <WarningIcon className="w-6 h-6 text-warning" />,
|
||||
accent: <ChatIcon className="w-6 h-6 text-accent" />,
|
||||
}
|
||||
|
||||
const Toast = ({ type = 'info', children }) => (
|
||||
<div className={`w-64 alert shadow bg-base-100 p-0`}>
|
||||
<div
|
||||
className={`w-full m-0 bg-${type} p-4 border bg-opacity-30 rounded-lg flex flex-row items-center`}
|
||||
>
|
||||
{icons[type]}
|
||||
<div>{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
/* Custom toast methods */
|
||||
const toastMethods = (t) => ({
|
||||
info: (children) => toastMethod.custom(<Toast type="info">{children}</Toast>),
|
||||
warning: (children) => toastMethod.custom(<Toast type="warning">{children}</Toast>),
|
||||
error: (children) => toastMethod.custom(<Toast type="error">{children}</Toast>),
|
||||
accent: (children) => toastMethod.custom(<Toast type="accent">{children}</Toast>),
|
||||
success: (children) => toastMethod.custom(<Toast type="success">{children}</Toast>),
|
||||
for: {
|
||||
settingsSaved: () =>
|
||||
toastMethod.custom(
|
||||
<Toast type="success">
|
||||
<span>{t('settingsSaved')}</span>
|
||||
</Toast>
|
||||
),
|
||||
backendError: () =>
|
||||
toastMethod.custom(
|
||||
<Toast type="error">
|
||||
<span>{t('backendError')} ¯\_(ツ)_/¯</span>
|
||||
</Toast>
|
||||
),
|
||||
},
|
||||
})
|
||||
|
||||
/*
|
||||
* The toast hook
|
||||
*/
|
||||
export function useToast() {
|
||||
const { t } = useTranslation(['toast'])
|
||||
|
||||
return toastMethods(t)
|
||||
}
|
|
@ -22,3 +22,4 @@ toc: Table of contents
|
|||
credits: Credits
|
||||
contentsBy: Contents by
|
||||
translators: Translators
|
||||
title: Title
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue