Initial commit: WrestleDesk full project
- Django backend with DRF (clubs, wrestlers, trainers, exercises, templates, trainings, homework, locations, leistungstest) - Next.js 16 frontend with React, Shadcn UI, Tailwind - JWT authentication - Full CRUD for all entities - Calendar view for trainings - Homework management system - Leistungstest tracking
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
"use client"
|
||||
|
||||
import { useState, useCallback } from "react"
|
||||
import { useAuth } from "@/lib/auth"
|
||||
import { apiFetch } from "@/lib/api"
|
||||
|
||||
export interface FilterState {
|
||||
[key: string]: string
|
||||
}
|
||||
|
||||
export function useFilterPreferences(pageKey: string, defaultFilters: FilterState) {
|
||||
const { token } = useAuth()
|
||||
const [filters, setFilters] = useState<FilterState>(defaultFilters)
|
||||
|
||||
const fetchPreferences = useCallback(async () => {
|
||||
if (!token) return
|
||||
try {
|
||||
const prefs = await apiFetch<Record<string, FilterState>>(`/auth/preferences/`, { token })
|
||||
const key = `${pageKey}_filters`
|
||||
const savedFilters = prefs[key] || {}
|
||||
const mergedFilters = { ...defaultFilters, ...savedFilters }
|
||||
setFilters(mergedFilters)
|
||||
return mergedFilters
|
||||
} catch (err) {
|
||||
console.error(`Failed to fetch ${pageKey} preferences:`, err)
|
||||
return defaultFilters
|
||||
}
|
||||
}, [token, pageKey, defaultFilters])
|
||||
|
||||
const savePreferences = useCallback(async (newFilters: FilterState) => {
|
||||
if (!token) return
|
||||
try {
|
||||
const payload: Record<string, FilterState> = {}
|
||||
payload[`${pageKey}_filters`] = newFilters
|
||||
await apiFetch(`/auth/preferences/`, {
|
||||
method: "PATCH",
|
||||
token,
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
} catch (err) {
|
||||
console.error(`Failed to save ${pageKey} preferences:`, err)
|
||||
}
|
||||
}, [token, pageKey])
|
||||
|
||||
const updateFilter = useCallback((key: string, value: string, onUpdate?: () => void) => {
|
||||
const newFilters = { ...filters, [key]: value }
|
||||
setFilters(newFilters)
|
||||
savePreferences(newFilters)
|
||||
onUpdate?.()
|
||||
}, [filters, savePreferences])
|
||||
|
||||
const resetFilters = useCallback((onReset?: () => void) => {
|
||||
setFilters(defaultFilters)
|
||||
savePreferences(defaultFilters)
|
||||
onReset?.()
|
||||
}, [defaultFilters, savePreferences])
|
||||
|
||||
return {
|
||||
filters,
|
||||
setFilters,
|
||||
fetchPreferences,
|
||||
savePreferences,
|
||||
updateFilter,
|
||||
resetFilters,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
"use client"
|
||||
|
||||
import { useSearchParams } from "next/navigation"
|
||||
import { useCallback, useMemo } from "react"
|
||||
|
||||
export function useFilters() {
|
||||
const searchParams = useSearchParams()
|
||||
|
||||
const getParam = useCallback((key: string): string => {
|
||||
return searchParams.get(key) || ""
|
||||
}, [searchParams])
|
||||
|
||||
const getParamArray = useCallback((key: string): string[] => {
|
||||
const val = searchParams.get(key)
|
||||
return val ? val.split(",") : []
|
||||
}, [searchParams])
|
||||
|
||||
const hasActiveFilters = useMemo(() => {
|
||||
return Array.from(searchParams.keys()).some(
|
||||
key => key !== "page" && searchParams.get(key)
|
||||
)
|
||||
}, [searchParams])
|
||||
|
||||
return {
|
||||
getParam,
|
||||
getParamArray,
|
||||
hasActiveFilters,
|
||||
allParams: searchParams,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user