feat: implement admin panel functionality in Mini App
- Added new API endpoints for admin features: `GET /api/admin/me`, `GET /api/admin/users`, and `PATCH /api/admin/duties/:id` to manage user duties. - Introduced `UserForAdmin` and `AdminDutyReassignBody` schemas for handling admin-related data. - Updated documentation to include Mini App design guidelines and admin panel functionalities. - Enhanced tests for admin API to ensure proper access control and functionality. - Improved error handling and localization for admin actions.
This commit is contained in:
@@ -6,12 +6,14 @@
|
||||
"use client";
|
||||
|
||||
import { useRef, useState, useEffect, useCallback } from "react";
|
||||
import Link from "next/link";
|
||||
import { useAppStore } from "@/store/app-store";
|
||||
import { useShallow } from "zustand/react/shallow";
|
||||
import { useMonthData } from "@/hooks/use-month-data";
|
||||
import { useSwipe } from "@/hooks/use-swipe";
|
||||
import { useStickyScroll } from "@/hooks/use-sticky-scroll";
|
||||
import { useAutoRefresh } from "@/hooks/use-auto-refresh";
|
||||
import { useTranslation } from "@/i18n/use-translation";
|
||||
import { CalendarHeader } from "@/components/calendar/CalendarHeader";
|
||||
import { CalendarGrid } from "@/components/calendar/CalendarGrid";
|
||||
import { DutyList } from "@/components/duty/DutyList";
|
||||
@@ -53,6 +55,7 @@ export function CalendarPage({ isAllowed, initDataRaw }: CalendarPageProps) {
|
||||
duties,
|
||||
calendarEvents,
|
||||
selectedDay,
|
||||
isAdmin,
|
||||
nextMonth,
|
||||
prevMonth,
|
||||
setCurrentMonth,
|
||||
@@ -68,6 +71,7 @@ export function CalendarPage({ isAllowed, initDataRaw }: CalendarPageProps) {
|
||||
duties: s.duties,
|
||||
calendarEvents: s.calendarEvents,
|
||||
selectedDay: s.selectedDay,
|
||||
isAdmin: s.isAdmin,
|
||||
nextMonth: s.nextMonth,
|
||||
prevMonth: s.prevMonth,
|
||||
setCurrentMonth: s.setCurrentMonth,
|
||||
@@ -76,6 +80,8 @@ export function CalendarPage({ isAllowed, initDataRaw }: CalendarPageProps) {
|
||||
}))
|
||||
);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { retry } = useMonthData({
|
||||
initDataRaw,
|
||||
enabled: isAllowed,
|
||||
@@ -133,7 +139,7 @@ export function CalendarPage({ isAllowed, initDataRaw }: CalendarPageProps) {
|
||||
}, [loading, accessDenied, setAppContentReady]);
|
||||
|
||||
return (
|
||||
<div className="content-safe mx-auto flex min-h-screen w-full max-w-[var(--max-width-app)] flex-col bg-background px-3 pb-6">
|
||||
<div className="content-safe mx-auto flex min-h-[var(--tg-viewport-stable-height,100vh)] w-full max-w-[var(--max-width-app)] flex-col bg-background px-3 pb-6">
|
||||
<div
|
||||
ref={calendarStickyRef}
|
||||
className="sticky top-0 z-10 min-h-[var(--calendar-block-min-height)] bg-background pb-2"
|
||||
@@ -143,6 +149,16 @@ export function CalendarPage({ isAllowed, initDataRaw }: CalendarPageProps) {
|
||||
disabled={navDisabled}
|
||||
onPrevMonth={handlePrevMonth}
|
||||
onNextMonth={handleNextMonth}
|
||||
trailingContent={
|
||||
isAdmin ? (
|
||||
<Link
|
||||
href="/admin"
|
||||
className="text-sm text-accent hover:underline focus-visible:outline-accent rounded"
|
||||
>
|
||||
{t("admin.link")}
|
||||
</Link>
|
||||
) : undefined
|
||||
}
|
||||
/>
|
||||
<CalendarGrid
|
||||
currentMonth={currentMonth}
|
||||
|
||||
Reference in New Issue
Block a user