base commit

This commit is contained in:
@kirill.komarov
2026-05-03 19:57:12 +05:00
parent 9139a24093
commit fe10f25b8c
53 changed files with 2064 additions and 1071 deletions
-26
View File
@@ -1,26 +0,0 @@
const KEY = 'craftshop_admin_token'
const TOKEN_EVENT = 'craftshop_admin_token_change'
export function getAdminToken(): string | null {
return sessionStorage.getItem(KEY)
}
function notifyTokenListeners(): void {
window.dispatchEvent(new Event(TOKEN_EVENT))
}
/** Подписаться на смену токена (в т. ч. после setAdminToken). */
export function subscribeAdminTokenChange(cb: () => void): () => void {
window.addEventListener(TOKEN_EVENT, cb)
return () => window.removeEventListener(TOKEN_EVENT, cb)
}
export function setAdminToken(token: string): void {
sessionStorage.setItem(KEY, token)
notifyTokenListeners()
}
export function clearAdminToken(): void {
sessionStorage.removeItem(KEY)
notifyTokenListeners()
}
@@ -0,0 +1,4 @@
export function getErrorMessage(error: unknown, fallback = 'Произошла ошибка'): string {
if (error instanceof Error && error.message) return error.message
return fallback
}
@@ -0,0 +1,24 @@
type OrderLike = {
status: string
createdAt: string
}
export function groupOrdersByStatus<T extends OrderLike>(items: T[], statuses: readonly string[]) {
const byStatus = new Map<string, T[]>()
for (const status of statuses) byStatus.set(status, [])
for (const item of items) {
const list = byStatus.get(item.status) ?? []
list.push(item)
byStatus.set(item.status, list)
}
return statuses
.map((status) => ({
status,
items: (byStatus.get(status) ?? []).sort(
(a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),
),
}))
.filter((group) => group.items.length > 0)
}
@@ -0,0 +1,5 @@
import type { QueryClient, QueryKey } from '@tanstack/react-query'
export async function invalidateQueryKeys(queryClient: QueryClient, keys: QueryKey[]): Promise<void> {
await Promise.all(keys.map((queryKey) => queryClient.invalidateQueries({ queryKey })))
}
@@ -0,0 +1,28 @@
import { useCallback, useState } from 'react'
export function useEditDialogState<T>() {
const [dialogOpen, setDialogOpen] = useState(false)
const [editing, setEditing] = useState<T | null>(null)
const openCreateDialog = useCallback(() => {
setEditing(null)
setDialogOpen(true)
}, [])
const openEditDialog = useCallback((item: T) => {
setEditing(item)
setDialogOpen(true)
}, [])
const closeDialog = useCallback(() => {
setDialogOpen(false)
}, [])
return {
dialogOpen,
editing,
openCreateDialog,
openEditDialog,
closeDialog,
}
}