Utenti MS @polinetwork.org
Utenti MS @polinetwork.org
Your profile is incomplete, please enter the missing information.
diff --git a/src/app/dashboard/(active)/layout.tsx b/src/app/dashboard/(active)/layout.tsx new file mode 100644 index 0000000..016881d --- /dev/null +++ b/src/app/dashboard/(active)/layout.tsx @@ -0,0 +1,50 @@ +import { cookies } from "next/headers" +import { DashboardSidebar } from "@/components/dashboard-sidebar" +import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar" +import { COOKIES } from "@/constants" +import { Breadcrumb } from "./breadcrumb" + +function parseCookie(cookie: string) { + try { + const parsed = JSON.parse(cookie) + return parsed + } catch (_e) { + return {} + } +} + +export default async function AdminLayout({ children }: { children: React.ReactNode }) { + const sidebarCookies = await getSidebarCookies() + + return ( ++ The resource you're looking for doesn't exist or has been moved. +
+{format(r.grant.validSince, "yyyy/MM/dd HH:mm")}
{format(r.grant.validUntil, "yyyy/MM/dd HH:mm")}
-Telegram Grants
Telegram ID
Username
Start Date
diff --git a/src/app/dashboard/(active)/telegram/grants/page.tsx b/src/app/dashboard/(active)/telegram/grants/page.tsx index 737f356..0ca8cb4 100644 --- a/src/app/dashboard/(active)/telegram/grants/page.tsx +++ b/src/app/dashboard/(active)/telegram/grants/page.tsx @@ -8,13 +8,13 @@ export default async function GrantsPage() { const { grants: scheduled } = await trpc.tg.grants.getScheduled.query() return ( -Telegram Grants
{r.hide ? (
Count: telegram ID Telegram ID Title Tag Invite Link Actions Actions
+
Count: {rows.length}
telegram ID Telegram ID Title Tag Invite Link Actions Actions Admin in groups:
- This user is not group admin in any group.
- Last messages (max 12):
- No recent messages sent by this user
- Audit log:
- No audit log found for this user
-
- Count: {data.users?.length}
- Telegram ID Username Name {r.id} {r.username ? `@${r.username}` : `
- {r.firstName ?? ""} {r.lastName ?? ""}
- End: {format(grant.validUntil, "yyyy/MM/dd HH:mm")} Admin in groups: Last messages (max 12): Audit log: Admin in groups:
+ This user is not group admin in any group.
+ Last messages (max 15):
+ No recent messages sent by this user
+ Audit log:
+ No audit log found for this user
+ Count: Telegram ID Username Name Actions
+ Count: {users?.length}
+ Telegram ID Username Name Actions {r.id} {r.username ? `@${r.username}` : `
+ {r.firstName ?? ""} {r.lastName ?? ""}
+
-
-
-
- {data && (
- <>
-
+ )
+}
+
+function SidebarMenuItem({ className, ...props }: React.ComponentProps<"li">) {
+ return (
+
+ )
+}
+
+const sidebarMenuButtonVariants = cva(
+ "peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:font-medium data-active:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate",
+ {
+ variants: {
+ variant: {
+ default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
+ outline:
+ "bg-background shadow-[0_0_0_1px_var(--sidebar-border)] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_var(--sidebar-accent)]",
+ },
+ size: {
+ default: "h-8 text-sm",
+ sm: "h-7 text-xs",
+ lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "default",
+ },
+ }
+)
+
+function SidebarMenuButton({
+ render,
+ isActive = false,
+ variant = "default",
+ size = "default",
+ tooltip,
+ className,
+ ...props
+}: useRender.ComponentProps<"button"> &
+ React.ComponentProps<"button"> & {
+ isActive?: boolean
+ tooltip?: string | React.ComponentProps
+ )
+}
+
+function SidebarMenuSubItem({
+ className,
+ ...props
+}: React.ComponentProps<"li">) {
+ return (
+
+ )
+}
+
+function SidebarMenuSubButton({
+ render,
+ size = "md",
+ isActive = false,
+ className,
+ ...props
+}: useRender.ComponentProps<"a"> &
+ React.ComponentProps<"a"> & {
+ size?: "sm" | "md"
+ isActive?: boolean
+ }) {
+ return useRender({
+ defaultTagName: "a",
+ props: mergeProps<"a">(
+ {
+ className: cn(
+ "flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground ring-sidebar-ring outline-hidden group-data-[collapsible=icon]:hidden hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[size=md]:text-sm data-[size=sm]:text-xs data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground",
+ className
+ ),
+ },
+ props
+ ),
+ render,
+ state: {
+ slot: "sidebar-menu-sub-button",
+ sidebar: "menu-sub-button",
+ size,
+ active: isActive,
+ },
+ })
+}
+
+export {
+ Sidebar,
+ SidebarContent,
+ SidebarFooter,
+ SidebarGroup,
+ SidebarGroupAction,
+ SidebarGroupContent,
+ SidebarGroupLabel,
+ SidebarHeader,
+ SidebarInput,
+ SidebarInset,
+ SidebarMenu,
+ SidebarMenuAction,
+ SidebarMenuBadge,
+ SidebarMenuButton,
+ SidebarMenuItem,
+ SidebarMenuSkeleton,
+ SidebarMenuSub,
+ SidebarMenuSubButton,
+ SidebarMenuSubItem,
+ SidebarProvider,
+ SidebarRail,
+ SidebarSeparator,
+ SidebarTrigger,
+ useSidebar,
+}
diff --git a/src/constants.ts b/src/constants.ts
index 80aa13a..b0d438f 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -1,39 +1,4 @@
-export const USER_ROLE = {
- ADMIN_ORG: "owner",
- MEMBER: "member",
- INACTIVE: "inactive",
- DISABLED: "disabled",
+export const COOKIES = {
+ SIDEBAR_OPEN: "sidebar_open",
+ SIDEBAR_CATEGORY_STATE: "sidebar_category_state",
} as const
-export type TUserRole = (typeof USER_ROLE)[keyof typeof USER_ROLE]
-
-export const DEPARTMENT_ID = {
- IT: "it",
- SOCIAL: "social",
- HR: "hr",
- INST_RELATIONS: "institutional_relations",
- EVENTS: "events",
-} as const
-export type TDepartmentId = (typeof DEPARTMENT_ID)[keyof typeof DEPARTMENT_ID]
-
-// department roles
-export const DEP_ROLE = {
- HEAD: "head",
- DEPUTY_HEAD: "deputy_head",
- MEMBER: "member",
-} as const
-export type TDepRole = (typeof DEP_ROLE)[keyof typeof DEP_ROLE]
-
-export const BOARD_ROLE = {
- PRESIDENT: "president",
- VICE_PRESIDENT: "vice_president",
- SECRETARY: "secretary",
- TREASURER: "treasurer",
- MEMBER: "member",
-} as const
-export type TBoardRole = (typeof BOARD_ROLE)[keyof typeof BOARD_ROLE]
-
-export const INCOMPATIBLE_BOARD_ROLES: TBoardRole[] = [
- BOARD_ROLE.PRESIDENT,
- BOARD_ROLE.VICE_PRESIDENT,
- BOARD_ROLE.SECRETARY,
-] as const
diff --git a/src/hooks/use-cookie-storage.tsx b/src/hooks/use-cookie-storage.tsx
new file mode 100644
index 0000000..a6339cc
--- /dev/null
+++ b/src/hooks/use-cookie-storage.tsx
@@ -0,0 +1,49 @@
+import { type Dispatch, type SetStateAction, useCallback, useMemo, useState } from "react"
+import { type CookieOptions, deleteCookie, getCookie, getDefaultCookieOptions, setCookie } from "@/utils/cookies"
+
+export function useCookieStorage