Start setting up Next js with the new app router
This commit is contained in:
parent
49c6281b74
commit
2adecd13f7
147 changed files with 2637 additions and 3667 deletions
|
|
@ -1,5 +0,0 @@
|
|||
export { default as useSettingsStore } from './settingsStore'
|
||||
export { default as useRecentsStore } from './recentsStore'
|
||||
export { default as useTWAStore } from './twaStore'
|
||||
export { default as useLocaleUpdateStore } from './localeUpdateStore'
|
||||
export { default as useTranslateStore } from './translateStore'
|
||||
22
frontend/src/stores/index.ts
Normal file
22
frontend/src/stores/index.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import { useEffect, useState } from 'react'
|
||||
|
||||
// export { default as useSettingsStore } from './settingsStore'
|
||||
export { default as useRecentsStore } from './recentsStore'
|
||||
// export { default as useTWAStore } from './twaStore'
|
||||
// export { default as useLocaleUpdateStore } from './localeUpdateStore'
|
||||
// export { default as useTranslateStore } from './translateStore'
|
||||
|
||||
/** Helper to use a persisted store in zustand with Next js without causing a hydration error */
|
||||
export const useStore = <T, F>(
|
||||
store: (callback?: (state: T) => unknown) => unknown,
|
||||
callback?: (state: T) => F
|
||||
) => {
|
||||
const result = store(callback) as F
|
||||
const [data, setData] = useState<F>()
|
||||
|
||||
useEffect(() => {
|
||||
setData(result)
|
||||
}, [result])
|
||||
|
||||
return data
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
import create from 'zustand'
|
||||
|
||||
const useLocaleUpdateStore = create(set => ({
|
||||
locale: 'en',
|
||||
setLocale: locale => set({ locale }),
|
||||
}))
|
||||
|
||||
export default useLocaleUpdateStore
|
||||
13
frontend/src/stores/localeUpdateStore.ts
Normal file
13
frontend/src/stores/localeUpdateStore.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { create } from 'zustand'
|
||||
|
||||
interface LocaleUpdateStore {
|
||||
locale: string
|
||||
setLocale: (locale: string) => void
|
||||
}
|
||||
|
||||
const useLocaleUpdateStore = create<LocaleUpdateStore>()(set => ({
|
||||
locale: 'en',
|
||||
setLocale: locale => set({ locale }),
|
||||
}))
|
||||
|
||||
export default useLocaleUpdateStore
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
import create from 'zustand'
|
||||
import { persist } from 'zustand/middleware'
|
||||
|
||||
const useRecentsStore = create(persist(
|
||||
set => ({
|
||||
recents: [],
|
||||
|
||||
addRecent: event => set(state => {
|
||||
const recents = state.recents.filter(e => e.id !== event.id)
|
||||
recents.unshift(event)
|
||||
recents.length = Math.min(recents.length, 5)
|
||||
return { recents }
|
||||
}),
|
||||
removeRecent: id => set(state => {
|
||||
const recents = state.recents.filter(e => e.id !== id)
|
||||
return { recents }
|
||||
}),
|
||||
clearRecents: () => set({ recents: [] }),
|
||||
}),
|
||||
{ name: 'crabfit-recent' },
|
||||
))
|
||||
|
||||
export default useRecentsStore
|
||||
53
frontend/src/stores/recentsStore.ts
Normal file
53
frontend/src/stores/recentsStore.ts
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import { create } from 'zustand'
|
||||
import { persist } from 'zustand/middleware'
|
||||
|
||||
interface RecentEvent {
|
||||
id: string
|
||||
name: string
|
||||
created_at: number
|
||||
}
|
||||
|
||||
interface RecentsStore {
|
||||
recents: RecentEvent[]
|
||||
|
||||
addRecent: (event: RecentEvent) => void
|
||||
removeRecent: (id: string) => void
|
||||
clearRecents: () => void
|
||||
}
|
||||
|
||||
const useRecentsStore = create<RecentsStore>()(persist(
|
||||
set => ({
|
||||
recents: [],
|
||||
|
||||
addRecent: event => set(state => {
|
||||
const recents = state.recents.filter(e => e.id !== event.id)
|
||||
recents.unshift(event)
|
||||
recents.length = Math.min(recents.length, 5)
|
||||
return { recents }
|
||||
}),
|
||||
removeRecent: id => set(state => {
|
||||
const recents = state.recents.filter(e => e.id !== id)
|
||||
return { recents }
|
||||
}),
|
||||
clearRecents: () => set({ recents: [] }),
|
||||
}),
|
||||
{
|
||||
name: 'crabfit-recent',
|
||||
version: 1,
|
||||
migrate: (persistedState, version) => {
|
||||
if (version === 0) {
|
||||
return {
|
||||
...persistedState as RecentsStore,
|
||||
recents: (persistedState as { recents: {id: string, name: string, created: number }[] }).recents.map(ev => ({
|
||||
id: ev.id,
|
||||
name: ev.name,
|
||||
created_at: ev.created, // Field renamed
|
||||
})),
|
||||
}
|
||||
}
|
||||
return persistedState as RecentsStore
|
||||
},
|
||||
},
|
||||
))
|
||||
|
||||
export default useRecentsStore
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
import create from 'zustand'
|
||||
import { persist } from 'zustand/middleware'
|
||||
|
||||
const useSettingsStore = create(persist(
|
||||
set => ({
|
||||
weekStart: 0,
|
||||
timeFormat: '12h',
|
||||
theme: 'System',
|
||||
highlight: false,
|
||||
colormap: 'crabfit',
|
||||
|
||||
setWeekStart: weekStart => set({ weekStart }),
|
||||
setTimeFormat: timeFormat => set({ timeFormat }),
|
||||
setTheme: theme => set({ theme }),
|
||||
setHighlight: highlight => set({ highlight }),
|
||||
setColormap: colormap => set({ colormap }),
|
||||
}),
|
||||
{ name: 'crabfit-settings' },
|
||||
))
|
||||
|
||||
export default useSettingsStore
|
||||
38
frontend/src/stores/settingsStore.ts
Normal file
38
frontend/src/stores/settingsStore.ts
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import { create } from 'zustand'
|
||||
import { persist } from 'zustand/middleware'
|
||||
|
||||
type TimeFormat = '12h' | '24h'
|
||||
type Theme = 'System' | 'Light' | 'Dark'
|
||||
|
||||
interface SettingsStore {
|
||||
weekStart: number
|
||||
timeFormat: TimeFormat
|
||||
theme: Theme
|
||||
highlight: boolean
|
||||
colormap: string
|
||||
|
||||
setWeekStart: (weekStart: number) => void
|
||||
setTimeFormat: (timeFormat: TimeFormat) => void
|
||||
setTheme: (theme: Theme) => void
|
||||
setHighlight: (highlight: boolean) => void
|
||||
setColormap: (colormap: string) => void
|
||||
}
|
||||
|
||||
const useSettingsStore = create<SettingsStore>()(persist(
|
||||
set => ({
|
||||
weekStart: 0,
|
||||
timeFormat: '12h',
|
||||
theme: 'System',
|
||||
highlight: false,
|
||||
colormap: 'crabfit',
|
||||
|
||||
setWeekStart: weekStart => set({ weekStart }),
|
||||
setTimeFormat: timeFormat => set({ timeFormat }),
|
||||
setTheme: theme => set({ theme }),
|
||||
setHighlight: highlight => set({ highlight }),
|
||||
setColormap: colormap => set({ colormap }),
|
||||
}),
|
||||
{ name: 'crabfit-settings' },
|
||||
))
|
||||
|
||||
export default useSettingsStore
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
import create from 'zustand'
|
||||
import { persist } from 'zustand/middleware'
|
||||
|
||||
import locales from '/src/i18n/locales'
|
||||
|
||||
const useTranslateStore = create(persist(
|
||||
set => ({
|
||||
navigatorLang: navigator.language,
|
||||
navigatorSupported: Object.keys(locales).includes(navigator.language.substring(0, 2)),
|
||||
translateDialogDismissed: false,
|
||||
|
||||
setDialogDismissed: value => set({ translateDialogDismissed: value }),
|
||||
}),
|
||||
{
|
||||
name: 'crabfit-translate',
|
||||
blacklist: [
|
||||
'navigatorLang',
|
||||
'navigatorSupported',
|
||||
],
|
||||
},
|
||||
))
|
||||
|
||||
export default useTranslateStore
|
||||
28
frontend/src/stores/translateStore.ts
Normal file
28
frontend/src/stores/translateStore.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { create } from 'zustand'
|
||||
import { persist } from 'zustand/middleware'
|
||||
|
||||
import locales from '/src/i18n/locales'
|
||||
|
||||
interface TranslateStore {
|
||||
navigatorLang: string
|
||||
navigatorSupported: boolean
|
||||
translateDialogDismissed: boolean
|
||||
|
||||
setDialogDismissed: (isDismissed: boolean) => void
|
||||
}
|
||||
|
||||
const useTranslateStore = create<TranslateStore>()(persist(
|
||||
set => ({
|
||||
navigatorLang: navigator.language,
|
||||
navigatorSupported: Object.keys(locales).includes(navigator.language.substring(0, 2)),
|
||||
translateDialogDismissed: false,
|
||||
|
||||
setDialogDismissed: isDismissed => set({ translateDialogDismissed: isDismissed }),
|
||||
}),
|
||||
{
|
||||
name: 'crabfit-translate',
|
||||
partialize: state => ({ translateDialogDismissed: state.translateDialogDismissed }),
|
||||
},
|
||||
))
|
||||
|
||||
export default useTranslateStore
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
import create from 'zustand'
|
||||
|
||||
const useTWAStore = create(set => ({
|
||||
TWA: undefined,
|
||||
setTWA: TWA => set({ TWA }),
|
||||
}))
|
||||
|
||||
export default useTWAStore
|
||||
14
frontend/src/stores/twaStore.ts
Normal file
14
frontend/src/stores/twaStore.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { create } from 'zustand'
|
||||
|
||||
interface TWAStore {
|
||||
/** Is the site running in a trusted web activity? */
|
||||
isTWA: boolean | undefined
|
||||
setIsTWA: (isTWA: boolean | undefined) => void
|
||||
}
|
||||
|
||||
const useTWAStore = create<TWAStore>()(set => ({
|
||||
isTWA: undefined,
|
||||
setIsTWA: isTWA => set({ isTWA }),
|
||||
}))
|
||||
|
||||
export default useTWAStore
|
||||
Loading…
Add table
Add a link
Reference in a new issue