Files
accounted/components/modules/ModuleToggle.tsx
T
Emil f1733e2174 Add module detail page with toggle for enabling/disabling modules
- Delete scaffolded static sector route files that conflicted with dynamic routing
- Add Supabase migration for module_toggles table with RLS policies
- Extend modules-data.ts with longDesc field and getModuleBySlug helper
- Create ModuleToggle client component with optimistic upsert to Supabase
- Create [sector]/[module] detail page with description, badges, and toggle

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 09:33:30 +01:00

88 lines
2.4 KiB
TypeScript

'use client'
import { useEffect, useState, useTransition } from 'react'
import { createClient } from '@/lib/supabase/client'
import { Switch } from '@/components/ui/switch'
import { Loader2 } from 'lucide-react'
interface ModuleToggleProps {
sectorSlug: string
moduleSlug: string
}
export function ModuleToggle({ sectorSlug, moduleSlug }: ModuleToggleProps) {
const [enabled, setEnabled] = useState(false)
const [loading, setLoading] = useState(true)
const [isPending, startTransition] = useTransition()
const supabase = createClient()
useEffect(() => {
async function fetchToggle() {
const { data: { user } } = await supabase.auth.getUser()
if (!user) {
setLoading(false)
return
}
const { data } = await supabase
.from('module_toggles')
.select('enabled')
.eq('user_id', user.id)
.eq('sector_slug', sectorSlug)
.eq('module_slug', moduleSlug)
.maybeSingle()
setEnabled(data?.enabled ?? false)
setLoading(false)
}
fetchToggle()
}, [sectorSlug, moduleSlug, supabase])
function handleToggle(checked: boolean) {
setEnabled(checked)
startTransition(async () => {
const { data: { user } } = await supabase.auth.getUser()
if (!user) return
await supabase
.from('module_toggles')
.upsert(
{
user_id: user.id,
sector_slug: sectorSlug,
module_slug: moduleSlug,
enabled: checked,
},
{ onConflict: 'user_id,sector_slug,module_slug' }
)
})
}
if (loading) {
return (
<div className="flex items-center gap-3 rounded-xl border border-border bg-card px-5 py-4">
<Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
<span className="text-sm text-muted-foreground">Laddar</span>
</div>
)
}
return (
<label className="flex items-center justify-between gap-4 rounded-xl border border-border bg-card px-5 py-4 cursor-pointer transition-colors hover:border-primary/20">
<div>
<p className="text-sm font-medium text-foreground">Aktivera modul</p>
<p className="text-xs text-muted-foreground mt-0.5">
{enabled ? 'Modulen är aktiverad för ditt konto' : 'Aktivera för att använda modulen'}
</p>
</div>
<Switch
checked={enabled}
onCheckedChange={handleToggle}
disabled={isPending}
/>
</label>
)
}