refactor: improve code formatting and readability in settings component by adjusting indentation and line breaks

This commit is contained in:
Yoga Pangestu 2026-04-29 20:09:37 +07:00
parent 96ad0de44c
commit c07f1bd3bb

View File

@ -1,8 +1,8 @@
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Field, FieldError } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Field, FieldError } from '@/components/ui/field';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import systemRoutes from '@/routes/system';
import type { GeneralSetting } from '@/types';
@ -11,7 +11,11 @@ import { ImagePlus, Loader, Save, X } from 'lucide-react';
import React, { useRef, useState } from 'react';
import { toast } from 'sonner';
export default function SettingIndex({ setting }: { setting: GeneralSetting | null }) {
export default function SettingIndex({
setting,
}: {
setting: GeneralSetting | null;
}) {
const { data, setData, post, processing, errors } = useForm({
name: setting?.name || '',
description: setting?.description || '',
@ -24,8 +28,12 @@ export default function SettingIndex({ setting }: { setting: GeneralSetting | nu
const logoInputRef = useRef<HTMLInputElement>(null);
const iconInputRef = useRef<HTMLInputElement>(null);
const [logoPreview, setLogoPreview] = useState<string | null>(setting?.logo_url || null);
const [iconPreview, setIconPreview] = useState<string | null>(setting?.icon_url || null);
const [logoPreview, setLogoPreview] = useState<string | null>(
setting?.logo_url || null,
);
const [iconPreview, setIconPreview] = useState<string | null>(
setting?.icon_url || null,
);
const handleLogoChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
@ -87,74 +95,111 @@ export default function SettingIndex({ setting }: { setting: GeneralSetting | nu
<div className="flex items-center justify-between">
<div>
<h1 className="text-3xl font-bold tracking-tight">Pengaturan Umum</h1>
<h1 className="text-3xl font-bold tracking-tight">
Pengaturan Umum
</h1>
</div>
</div>
<form onSubmit={onSubmit} className="space-y-6">
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div className="lg:col-span-2 space-y-6">
<Card className="overflow-hidden border-none shadow-lg bg-card/50 backdrop-blur-sm">
<div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
<div className="space-y-6 lg:col-span-2">
<Card className="overflow-hidden border-none bg-card/50 shadow-lg backdrop-blur-sm">
<CardHeader className="border-b">
<CardTitle>Informasi Aplikasi</CardTitle>
</CardHeader>
<CardContent className="space-y-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
<Field>
<Label htmlFor="phone" required>No. Telepon</Label>
<Label htmlFor="phone" required>
No. Telepon
</Label>
<Input
id="phone"
value={data.phone || ''}
onChange={(e) => setData('phone', e.target.value)}
onChange={(e) =>
setData('phone', e.target.value)
}
placeholder="0812xxxx"
/>
<FieldError error={errors.phone} label="No. Telepon" className="text-xs" />
<FieldError
error={errors.phone}
label="No. Telepon"
className="text-xs"
/>
</Field>
<Field>
<Label htmlFor="name" required>Nama Aplikasi</Label>
<Label htmlFor="name" required>
Nama Aplikasi
</Label>
<Input
id="name"
name="name"
value={data.name}
onChange={e => setData('name', e.target.value)}
autoComplete='off'
placeholder='Contoh: VN Grup Dress'
onChange={(e) =>
setData('name', e.target.value)
}
autoComplete="off"
placeholder="Contoh: VN Grup Dress"
maxLength={100}
/>
<FieldError error={errors.name} label="Nama Aplikasi" className="text-xs" />
<FieldError
error={errors.name}
label="Nama Aplikasi"
className="text-xs"
/>
</Field>
</div>
<Field>
<Label htmlFor="description" required>Deskripsi</Label>
<Label htmlFor="description" required>
Deskripsi
</Label>
<Textarea
id="description"
value={data.description || ''}
onChange={(e) => setData('description', e.target.value)}
onChange={(e) =>
setData(
'description',
e.target.value,
)
}
placeholder="Deskripsi singkat aplikasi"
rows={4}
/>
<FieldError error={errors.description} label="Deskripsi" className="text-xs mt-1" />
<FieldError
error={errors.description}
label="Deskripsi"
className="mt-1 text-xs"
/>
</Field>
<Field>
<Label htmlFor="address" required>Alamat</Label>
<Label htmlFor="address" required>
Alamat
</Label>
<Textarea
id="address"
value={data.address || ''}
onChange={(e) => setData('address', e.target.value)}
onChange={(e) =>
setData('address', e.target.value)
}
placeholder="Alamat lengkap toko"
rows={3}
/>
<FieldError error={errors.address} label="Alamat" className="text-xs mt-1" />
<FieldError
error={errors.address}
label="Alamat"
className="mt-1 text-xs"
/>
</Field>
</CardContent>
</Card>
</div>
<div className="space-y-6">
<Card className="overflow-hidden border-none shadow-lg bg-card/50 backdrop-blur-sm">
<Card className="overflow-hidden border-none bg-card/50 shadow-lg backdrop-blur-sm">
<CardHeader className="border-b">
<CardTitle>Logo Aplikasi</CardTitle>
</CardHeader>
@ -164,25 +209,31 @@ export default function SettingIndex({ setting }: { setting: GeneralSetting | nu
<img
src={logoPreview}
alt="Logo preview"
className="w-full object-cover rounded-xl border shadow"
className="w-full rounded-xl border object-cover shadow"
/>
<button
type="button"
onClick={removeLogo}
className="absolute -top-2 -right-2 bg-red-500 hover:bg-red-600 text-white rounded-full w-6 h-6 flex items-center justify-center shadow-md transition-colors"
className="absolute -top-2 -right-2 flex h-6 w-6 items-center justify-center rounded-full bg-red-500 text-white shadow-md transition-colors hover:bg-red-600"
>
<X className="w-3.5 h-3.5" />
<X className="h-3.5 w-3.5" />
</button>
</div>
) : (
<button
type="button"
onClick={() => logoInputRef.current?.click()}
className="flex flex-col items-center justify-center w-full h-40 border-2 border-dashed border-border rounded-xl hover:border-primary hover:bg-primary/5 transition-all cursor-pointer group"
onClick={() =>
logoInputRef.current?.click()
}
className="group flex h-40 w-full cursor-pointer flex-col items-center justify-center rounded-xl border-2 border-dashed border-border transition-all hover:border-primary hover:bg-primary/5"
>
<ImagePlus className="w-10 h-10 text-muted-foreground group-hover:text-primary transition-colors mb-2" />
<span className="text-sm text-muted-foreground group-hover:text-primary transition-colors font-medium">Klik untuk upload logo</span>
<span className="text-xs text-muted-foreground mt-1">PNG, JPG, WEBP maks. 2MB</span>
<ImagePlus className="mb-2 h-10 w-10 text-muted-foreground transition-colors group-hover:text-primary" />
<span className="text-sm font-medium text-muted-foreground transition-colors group-hover:text-primary">
Klik untuk upload logo
</span>
<span className="mt-1 text-xs text-muted-foreground">
PNG, JPG, WEBP maks. 2MB
</span>
</button>
)}
<input
@ -192,41 +243,51 @@ export default function SettingIndex({ setting }: { setting: GeneralSetting | nu
className="hidden"
onChange={handleLogoChange}
/>
<FieldError error={errors.logo} label="Logo Aplikasi" className="text-xs mt-2" />
<FieldError
error={errors.logo}
label="Logo Aplikasi"
className="mt-2 text-xs"
/>
</CardContent>
</Card>
<Card className="overflow-hidden border-none shadow-lg bg-card/50 backdrop-blur-sm">
<Card className="overflow-hidden border-none bg-card/50 shadow-lg backdrop-blur-sm">
<CardHeader className="border-b">
<CardTitle>Favicon / Icon</CardTitle>
</CardHeader>
<CardContent>
{iconPreview ? (
<div className="relative inline-block w-full flex justify-center">
<div className="relative flex inline-block w-full justify-center">
<div className="relative">
<img
src={iconPreview}
alt="Icon preview"
className="size-24 object-contain rounded-xl border shadow p-2"
className="size-24 rounded-xl border object-contain p-2 shadow"
/>
<button
type="button"
onClick={removeIcon}
className="absolute -top-2 -right-2 bg-red-500 hover:bg-red-600 text-white rounded-full w-6 h-6 flex items-center justify-center shadow-md transition-colors"
className="absolute -top-2 -right-2 flex h-6 w-6 items-center justify-center rounded-full bg-red-500 text-white shadow-md transition-colors hover:bg-red-600"
>
<X className="w-3.5 h-3.5" />
<X className="h-3.5 w-3.5" />
</button>
</div>
</div>
) : (
<button
type="button"
onClick={() => iconInputRef.current?.click()}
className="flex flex-col items-center justify-center w-full h-32 border-2 border-dashed border-border rounded-xl hover:border-primary hover:bg-primary/5 transition-all cursor-pointer group"
onClick={() =>
iconInputRef.current?.click()
}
className="group flex h-32 w-full cursor-pointer flex-col items-center justify-center rounded-xl border-2 border-dashed border-border transition-all hover:border-primary hover:bg-primary/5"
>
<ImagePlus className="w-8 h-8 text-muted-foreground group-hover:text-primary transition-colors mb-2" />
<span className="text-sm text-muted-foreground group-hover:text-primary transition-colors font-medium">Klik untuk upload icon</span>
<span className="text-xs text-muted-foreground mt-1">ICO, PNG maks. 1MB</span>
<ImagePlus className="mb-2 h-8 w-8 text-muted-foreground transition-colors group-hover:text-primary" />
<span className="text-sm font-medium text-muted-foreground transition-colors group-hover:text-primary">
Klik untuk upload icon
</span>
<span className="mt-1 text-xs text-muted-foreground">
ICO, PNG maks. 1MB
</span>
</button>
)}
<input
@ -236,18 +297,24 @@ export default function SettingIndex({ setting }: { setting: GeneralSetting | nu
className="hidden"
onChange={handleIconChange}
/>
<FieldError error={errors.icon} label="Favicon / Icon" className="text-xs mt-2" />
<FieldError
error={errors.icon}
label="Favicon / Icon"
className="mt-2 text-xs"
/>
</CardContent>
</Card>
<div className="flex flex-col gap-4 p-4 rounded-xl bg-primary/5 border border-primary/10 shadow-sm">
<Button type="submit" className="w-full gap-2" disabled={processing}>
{processing ? <Loader className="size-4 animate-spin" /> : <Save className="size-4" />}
{processing ? 'Menyimpan...' : 'Simpan'}
</Button>
</div>
</div>
</div>
<Button type="submit" disabled={processing}>
{processing ? (
<Loader className="size-4 animate-spin" />
) : (
<Save className="size-4" />
)}
{processing ? 'Menyimpan...' : 'Simpan'}
</Button>
</form>
</div>
);
@ -257,6 +324,6 @@ SettingIndex.layout = {
breadcrumbs: [
{
title: 'Sistem',
}
},
],
};