feat(credits): solde IA unique (option M), packs Stripe et polish billing
Un pot de crédits global (BASIC 100 / PRO 1 000 / BUSINESS 4 000) remplace les seaux par fonction côté débit. Packs one-shot S/M/L, admin sans seaux legacy, usage multi-features, hints de coût, anti-flash thème et hydratation admin. Inclut aussi le pipeline slides renforcé et la page publique polishée.
This commit is contained in:
@@ -35,13 +35,13 @@ export default async function MainLayout({
|
||||
initialTranslations={initialTranslations}
|
||||
initialAiProcessingConsent={aiSettings?.aiProcessingConsent === true}
|
||||
>
|
||||
{/* No top-bar header — sidebar-only navigation (architectural-grid design) */}
|
||||
<div className="flex h-screen overflow-hidden bg-memento-desk dark:bg-background">
|
||||
<Suspense fallback={<div className="hidden w-80 md:w-[26rem] 2xl:w-[30rem] shrink-0 md:block h-full self-stretch" />}>
|
||||
{/* Fond via --background (suit .dark) — évite le flash beige/clair au changement de route */}
|
||||
<div className="flex h-screen overflow-hidden bg-background">
|
||||
<Suspense fallback={<div className="hidden w-80 md:w-[26rem] 2xl:w-[30rem] shrink-0 md:block h-full self-stretch bg-sidebar" />}>
|
||||
<Sidebar user={session?.user} />
|
||||
</Suspense>
|
||||
|
||||
<main className="flex min-h-0 flex-1 flex-col overflow-y-auto scroll-smooth bg-memento-paper dark:bg-background" id="main-content">
|
||||
<main className="flex min-h-0 flex-1 flex-col overflow-y-auto scroll-smooth bg-background" id="main-content">
|
||||
<a href="#main-content" className="sr-only focus:not-sr-only focus:absolute focus:z-[9999] focus:top-2 focus:left-2 focus:bg-brand-accent focus:text-white focus:px-4 focus:py-2 focus:rounded-lg focus:text-sm focus:font-bold">
|
||||
Skip to content
|
||||
</a>
|
||||
|
||||
@@ -6,7 +6,7 @@ import { updateUserSettings } from '@/app/actions/user-settings'
|
||||
import { useLanguage } from '@/lib/i18n'
|
||||
import { toast } from 'sonner'
|
||||
import { Palette, Type, LayoutGrid, Maximize } from 'lucide-react'
|
||||
import { applyDocumentTheme, normalizeThemeId, type ThemeId } from '@/lib/apply-document-theme'
|
||||
import { persistThemePreference, normalizeThemeId, type ThemeId } from '@/lib/apply-document-theme'
|
||||
import {
|
||||
NOTES_LAYOUT_STORAGE_KEY,
|
||||
parseNotesLayoutMode,
|
||||
@@ -65,8 +65,7 @@ export function AppearanceSettingsClient({
|
||||
const handleThemeChange = async (value: string) => {
|
||||
const next = normalizeThemeId(value)
|
||||
setTheme(next)
|
||||
localStorage.setItem('theme-preference', next)
|
||||
applyDocumentTheme(next)
|
||||
persistThemePreference(next)
|
||||
await updateUserSettings({ theme: next })
|
||||
toast.success(t('settings.settingsSaved'))
|
||||
}
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
'use client'
|
||||
|
||||
import { motion } from 'motion/react'
|
||||
|
||||
/**
|
||||
* Plus d’animation d’entrée (opacity / translate) :
|
||||
* ça laissait voir le fond clair une fraction de seconde en mode sombre.
|
||||
* Conteneur neutre uniquement.
|
||||
*/
|
||||
export default function MainTemplate({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: 20 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
className="flex-1 flex flex-col min-h-0"
|
||||
>
|
||||
<div className="flex min-h-0 flex-1 flex-col bg-background text-foreground">
|
||||
{children}
|
||||
</motion.div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user