refactor(settings): reorganize imports and improve code readability

Restructured imports across multiple files to follow a consistent order and improve readability. Also, adjusted some code formatting for better maintainability.
This commit is contained in:
Daniel Luiz Alves
2025-04-11 16:43:51 -03:00
parent 5cd7acc158
commit 6a933891c8
9 changed files with 58 additions and 63 deletions

View File

@@ -1,13 +1,14 @@
"use client";
import { useAppInfo } from "@/contexts/app-info-context";
import { removeLogo, uploadLogo } from "@/http/endpoints";
import { Button } from "@/components/ui/button";
import { useTranslations } from "next-intl";
import { useEffect, useRef, useState } from "react";
import { IconCloudUpload, IconTrash } from "@tabler/icons-react";
import { useTranslations } from "next-intl";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { useAppInfo } from "@/contexts/app-info-context";
import { removeLogo, uploadLogo } from "@/http/endpoints";
interface LogoInputProps {
value?: string;
onChange: (value: string) => void;
@@ -15,7 +16,7 @@ interface LogoInputProps {
}
export function LogoInput({ value, onChange, isDisabled }: LogoInputProps) {
const t = useTranslations();
const t = useTranslations();
const [isUploading, setIsUploading] = useState(false);
const [currentLogo, setCurrentLogo] = useState(value);
const fileInputRef = useRef<HTMLInputElement>(null);
@@ -80,19 +81,9 @@ export function LogoInput({ value, onChange, isDisabled }: LogoInputProps) {
{currentLogo ? (
<div className="flex flex-col items-center gap-4">
<div className="relative max-w-[200px] max-h-[200px] flex">
<img
alt={t("logo.labels.appLogo")}
className="rounded-lg"
src={currentLogo}
sizes="200px"
/>
<img alt={t("logo.labels.appLogo")} className="rounded-lg" src={currentLogo} sizes="200px" />
</div>
<Button
variant="destructive"
disabled={isDisabled}
onClick={handleRemoveLogo}
>
<Button variant="destructive" disabled={isDisabled} onClick={handleRemoveLogo}>
{!isUploading && <IconTrash className="mr-2 h-4 w-4" />}
{t("logo.buttons.remove")}
</Button>

View File

@@ -1,5 +1,4 @@
import { ValidGroup } from "../types";
import { SettingsFormProps } from "../types";
import { SettingsFormProps, ValidGroup } from "../types";
import { SettingsGroup } from "./settings-group";
const GROUP_ORDER: ValidGroup[] = ["general", "email", "security", "storage"];

View File

@@ -1,12 +1,13 @@
import { createGroupMetadata, createFieldDescriptions } from "../constants";
import { SettingsGroupProps } from "../types";
import { SettingsInput } from "./settings-input";
import React from "react";
import { IconChevronDown, IconChevronUp, IconDeviceFloppy } from "@tabler/icons-react";
import { useTranslations } from "next-intl";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { Separator } from "@/components/ui/separator";
import { useTranslations } from "next-intl";
import React from "react";
import { IconChevronDown, IconChevronUp, IconDeviceFloppy } from "@tabler/icons-react";
import { createFieldDescriptions, createGroupMetadata } from "../constants";
import { SettingsGroupProps } from "../types";
import { SettingsInput } from "./settings-input";
export function SettingsGroup({ group, configs, form, isCollapsed, onToggleCollapse, onSubmit }: SettingsGroupProps) {
const t = useTranslations();
@@ -21,7 +22,10 @@ export function SettingsGroup({ group, configs, form, isCollapsed, onToggleColla
return (
<form onSubmit={form.handleSubmit(onSubmit)}>
<Card className="p-6 gap-0">
<CardHeader className="flex flex-row items-center justify-between cursor-pointer p-0" onClick={onToggleCollapse}>
<CardHeader
className="flex flex-row items-center justify-between cursor-pointer p-0"
onClick={onToggleCollapse}
>
<div className="flex flex-row items-center gap-8">
{metadata.icon && React.createElement(metadata.icon, { className: "text-xl text-muted-foreground" })}
<div className="flex flex-col gap-1">
@@ -33,7 +37,11 @@ export function SettingsGroup({ group, configs, form, isCollapsed, onToggleColla
</p>
</div>
</div>
{isCollapsed ? <IconChevronDown className="text-muted-foreground" /> : <IconChevronUp className="text-muted-foreground" />}
{isCollapsed ? (
<IconChevronDown className="text-muted-foreground" />
) : (
<IconChevronUp className="text-muted-foreground" />
)}
</CardHeader>
<CardContent className={`${isCollapsed ? "hidden" : "block"} px-0`}>
<Separator className="my-6" />

View File

@@ -1,15 +1,15 @@
import {
Breadcrumb,
BreadcrumbItem,
import Link from "next/link";
import { IconLayoutDashboard, IconSettings } from "@tabler/icons-react";
import { useTranslations } from "next-intl";
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbSeparator
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb";
import { Separator } from "@/components/ui/separator";
import { useTranslations } from "next-intl";
import { IconSettings } from "@tabler/icons-react";
import { IconLayoutDashboard } from "@tabler/icons-react";
import Link from "next/link";
export function SettingsHeader() {
const t = useTranslations();

View File

@@ -1,10 +1,10 @@
import { useTranslations } from "next-intl";
import { UseFormRegister, UseFormWatch } from "react-hook-form";
import { Input } from "@/components/ui/input";
import { createFieldTitles } from "../constants";
import { Config } from "../types";
import { LogoInput } from "./logo-input";
import { Input } from "@/components/ui/input";
import { UseFormRegister, UseFormWatch } from "react-hook-form";
export interface ConfigInputProps {
config: Config;

View File

@@ -1,25 +1,25 @@
import { createTranslator } from 'next-intl';
import { IconMail, IconSettings, IconShield, IconDatabase } from '@tabler/icons-react';
import { IconDatabase, IconMail, IconSettings, IconShield } from "@tabler/icons-react";
import { createTranslator } from "next-intl";
export const createGroupMetadata = (t: ReturnType<typeof createTranslator>) => ({
email: {
title: t('settings.groups.email.title'),
description: t('settings.groups.email.description'),
title: t("settings.groups.email.title"),
description: t("settings.groups.email.description"),
icon: IconMail,
},
general: {
title: t('settings.groups.general.title'),
description: t('settings.groups.general.description'),
title: t("settings.groups.general.title"),
description: t("settings.groups.general.description"),
icon: IconSettings,
},
security: {
title: t('settings.groups.security.title'),
description: t('settings.groups.security.description'),
title: t("settings.groups.security.title"),
description: t("settings.groups.security.description"),
icon: IconShield,
},
storage: {
title: t('settings.groups.storage.title'),
description: t('settings.groups.storage.description'),
title: t("settings.groups.storage.title"),
description: t("settings.groups.storage.description"),
icon: IconDatabase,
},
});

View File

@@ -1,28 +1,25 @@
"use client";
import { ConfigType, GroupFormData } from "../types";
import { Config } from "../types";
import { useShareContext } from "@/contexts/share-context";
import { useAppInfo } from "@/contexts/app-info-context";
import { getAllConfigs, bulkUpdateConfigs } from "@/http/endpoints";
import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect, useState } from "react";
import { zodResolver } from "@hookform/resolvers/zod";
import { useTranslations } from "next-intl";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import { useTranslations } from "next-intl";
import { useAppInfo } from "@/contexts/app-info-context";
import { useShareContext } from "@/contexts/share-context";
import { bulkUpdateConfigs, getAllConfigs } from "@/http/endpoints";
import { Config, ConfigType, GroupFormData } from "../types";
const createSchemas = () => ({
settingsSchema: z.object({
configs: z.record(
z.union([z.string(), z.number()]).transform((val) => String(val))
),
configs: z.record(z.union([z.string(), z.number()]).transform((val) => String(val))),
}),
});
export function useSettings() {
const t = useTranslations();
const t = useTranslations();
const { settingsSchema } = createSchemas();
const [isLoading, setIsLoading] = useState(true);
const [configs, setConfigs] = useState<Record<string, string>>({});

View File

@@ -1,4 +1,4 @@
"use client"
"use client";
import { ProtectedRoute } from "@/components/auth/protected-route";
import { LoadingScreen } from "@/components/layout/loading-screen";
@@ -16,7 +16,7 @@ export default function SettingsPage() {
}
return (
<ProtectedRoute>
<ProtectedRoute requireAdmin>
<div className="w-full h-screen flex flex-col">
<Navbar />
<div className="flex-1 max-w-7xl mx-auto w-full px-6 py-8">

View File

@@ -5,7 +5,7 @@ import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
"inline-flex items-center cursor-pointer justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
{
variants: {
variant: {