refactor: improve code formatting and readability in settings component by adjusting indentation and line breaks
This commit is contained in:
parent
96ad0de44c
commit
c07f1bd3bb
@ -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',
|
||||
}
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user