From 84490a1c70863d89ac22f1a48fcc074f69907c4c Mon Sep 17 00:00:00 2001 From: vergiLgood1 Date: Sat, 8 Mar 2025 20:31:40 +0700 Subject: [PATCH] small refactor --- .../admin/settings/import-data.tsx | 39 +++++++++++++++++-- .../admin/settings/notification-settings.tsx | 35 +++++++++++++++-- .../admin/settings/setting-dialog.tsx | 4 +- .../app/_components/ui/scroll-area.tsx | 28 ++++++------- 4 files changed, 86 insertions(+), 20 deletions(-) diff --git a/sigap-website/app/_components/admin/settings/import-data.tsx b/sigap-website/app/_components/admin/settings/import-data.tsx index 441941a..2b78351 100644 --- a/sigap-website/app/_components/admin/settings/import-data.tsx +++ b/sigap-website/app/_components/admin/settings/import-data.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useEffect, useRef, useState } from "react"; import { Button } from "@/app/_components/ui/button"; import { Card, CardContent } from "@/app/_components/ui/card"; import { ScrollArea } from "@/app/_components/ui/scroll-area"; @@ -33,9 +33,42 @@ const importOptions: ImportOption[] = [ ]; const ImportData = () => { + const contentRef = useRef(null); + const [isScrollable, setIsScrollable] = useState(false); + const scrollAreaHeight = "calc(100vh-140px)"; + + useEffect(() => { + const checkScrollable = () => { + if (contentRef.current) { + const contentHeight = contentRef.current.scrollHeight; + const containerHeight = parseInt( + scrollAreaHeight.replace("calc(100vh-", "").replace("px)", "") + ); + const viewportHeight = window.innerHeight - containerHeight; + + setIsScrollable(contentHeight > viewportHeight); + } + }; + + // Check initially + checkScrollable(); + + // Check on window resize + window.addEventListener("resize", checkScrollable); + + // Clean up event listener + return () => window.removeEventListener("resize", checkScrollable); + }, []); + return ( - -
+ +

Import data

diff --git a/sigap-website/app/_components/admin/settings/notification-settings.tsx b/sigap-website/app/_components/admin/settings/notification-settings.tsx index b326158..dd6f8f7 100644 --- a/sigap-website/app/_components/admin/settings/notification-settings.tsx +++ b/sigap-website/app/_components/admin/settings/notification-settings.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState, useEffect } from "react"; +import { useState, useEffect, useRef } from "react"; import { Switch } from "@/app/_components/ui/switch"; import { Separator } from "@/app/_components/ui/separator"; import { ScrollArea } from "@/app/_components/ui/scroll-area"; @@ -14,10 +14,33 @@ import { import { toast } from "sonner"; export default function NotificationsSetting() { + const contentRef = useRef(null); const [isLoading, setIsLoading] = useState(true); const [lastToastTime, setLastToastTime] = useState(0); const [notificationPreferences, setNotificationPreferences] = useState(null); + const [isScrollable, setIsScrollable] = useState(false); + const scrollAreaHeight = "calc(100vh - 140px)"; + + useEffect(() => { + const checkScrollable = () => { + if (contentRef.current) { + const contentHeight = contentRef.current.scrollHeight; + const viewportHeight = window.innerHeight - 140; + + setIsScrollable(contentHeight > viewportHeight); + } + }; + + // Check initially + checkScrollable(); + + // Check on window resize + window.addEventListener("resize", checkScrollable); + + // Clean up event listener + return () => window.removeEventListener("resize", checkScrollable); + }, []); // Show toast with debounce to prevent too many notifications const showSavedToast = () => { @@ -70,8 +93,14 @@ export default function NotificationsSetting() { }; return ( - -
+ +

Notifications

diff --git a/sigap-website/app/_components/admin/settings/setting-dialog.tsx b/sigap-website/app/_components/admin/settings/setting-dialog.tsx index 4ee403a..0571673 100644 --- a/sigap-website/app/_components/admin/settings/setting-dialog.tsx +++ b/sigap-website/app/_components/admin/settings/setting-dialog.tsx @@ -15,6 +15,8 @@ import { AvatarImage, } from "@/app/_components/ui/avatar"; import { + IconAdjustmentsHorizontal, + IconBaselineDensityLarge, IconBell, IconFileExport, IconFileImport, @@ -82,7 +84,7 @@ export function SettingsDialog({ }, { id: "preferences", - icon: IconSettings, + icon: IconAdjustmentsHorizontal, title: "Preferences", content: , }, diff --git a/sigap-website/app/_components/ui/scroll-area.tsx b/sigap-website/app/_components/ui/scroll-area.tsx index 0b4a48d..e3d4e8c 100644 --- a/sigap-website/app/_components/ui/scroll-area.tsx +++ b/sigap-website/app/_components/ui/scroll-area.tsx @@ -1,14 +1,16 @@ -"use client" +"use client"; -import * as React from "react" -import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area" +import * as React from "react"; +import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils"; const ScrollArea = React.forwardRef< React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, children, ...props }, ref) => ( + React.ComponentPropsWithoutRef & { + scrollable?: boolean; + } +>(({ className, children, scrollable = true, ...props }, ref) => ( {children} - - + {scrollable && } + {scrollable && } -)) -ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName +)); +ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName; const ScrollBar = React.forwardRef< React.ElementRef, @@ -42,7 +44,7 @@ const ScrollBar = React.forwardRef< > -)) -ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName +)); +ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName; -export { ScrollArea, ScrollBar } +export { ScrollArea, ScrollBar };