Start setting up Next js with the new app router

This commit is contained in:
Ben Grant 2023-05-19 23:59:44 +10:00
parent 49c6281b74
commit 2adecd13f7
147 changed files with 2637 additions and 3667 deletions

View file

@ -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'

View 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
}

View file

@ -1,8 +0,0 @@
import create from 'zustand'
const useLocaleUpdateStore = create(set => ({
locale: 'en',
setLocale: locale => set({ locale }),
}))
export default useLocaleUpdateStore

View 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

View file

@ -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

View 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

View file

@ -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

View 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

View file

@ -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

View 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

View file

@ -1,8 +0,0 @@
import create from 'zustand'
const useTWAStore = create(set => ({
TWA: undefined,
setTWA: TWA => set({ TWA }),
}))
export default useTWAStore

View 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