pos-dashboard-v2/src/views/apps/fixed-assets/add/FixedAssetAddForm.tsx
2025-09-11 14:47:57 +07:00

562 lines
19 KiB
TypeScript

'use client'
import React, { useState } from 'react'
import { Card, CardContent, Typography, Button, Switch, FormControlLabel, Box, Radio } from '@mui/material'
import Grid from '@mui/material/Grid2'
import CustomTextField from '@/@core/components/mui/TextField'
import CustomAutocomplete from '@/@core/components/mui/Autocomplete'
interface FormData {
namaAset: string
nomor: string
tanggalPembelian: string
hargaBeli: string
akunAsetTetap: any
dikreditkanDariAkun: any
deskripsi: string
referensi: string
tanpaPenyusutan: boolean
akunAkumulasiPenyusutan: any
akunPenyusutan: any
nilaiPenyusuanPerTahun: string
masaManfaatTahun: string
masaManfaatBulan: string
depreciationType: 'percentage' | 'useful-life'
showAdditionalOptions: boolean
metodePenyusutan: any
tanggalMulaiPenyusutan: string
akumulasiPenyusutan: string
batasBiaya: string
nilaiResidu: string
showImageUpload: boolean
uploadedImage: string | null
}
// Simple ImageUpload component
const ImageUpload = ({ onUpload, maxFileSize, showUrlOption, dragDropText, browseButtonText }: any) => {
const [dragOver, setDragOver] = useState(false)
const handleFileSelect = (file: File) => {
if (file.size > maxFileSize) {
alert(`File size exceeds ${maxFileSize / (1024 * 1024)}MB limit`)
return
}
const url = URL.createObjectURL(file)
onUpload(file, url)
}
const handleDrop = (e: React.DragEvent) => {
e.preventDefault()
setDragOver(false)
const files = Array.from(e.dataTransfer.files)
if (files[0]) {
handleFileSelect(files[0])
}
}
const handleFileInput = (e: React.ChangeEvent<HTMLInputElement>) => {
const files = Array.from(e.target.files || [])
if (files[0]) {
handleFileSelect(files[0])
}
}
return (
<Box
sx={{
border: dragOver ? '2px dashed #1976d2' : '2px dashed #ccc',
borderRadius: 2,
p: 3,
textAlign: 'center',
backgroundColor: dragOver ? '#f5f5f5' : 'transparent',
transition: 'all 0.3s ease'
}}
onDrop={handleDrop}
onDragOver={e => {
e.preventDefault()
setDragOver(true)
}}
onDragLeave={() => setDragOver(false)}
>
<Typography variant='body1' sx={{ mb: 2 }}>
{dragDropText}
</Typography>
<input
type='file'
accept='image/*'
style={{ display: 'none' }}
id='image-upload-input'
onChange={handleFileInput}
/>
<label htmlFor='image-upload-input'>
<Button variant='outlined' component='span'>
{browseButtonText}
</Button>
</label>
</Box>
)
}
const FixedAssetAddForm = () => {
const [formData, setFormData] = useState<FormData>({
namaAset: '',
nomor: 'FA/00003',
tanggalPembelian: '11/09/2025',
hargaBeli: '0',
akunAsetTetap: null,
dikreditkanDariAkun: null,
deskripsi: '',
referensi: '',
tanpaPenyusutan: true,
akunAkumulasiPenyusutan: null,
akunPenyusutan: null,
nilaiPenyusuanPerTahun: '',
masaManfaatTahun: '',
masaManfaatBulan: '',
depreciationType: 'percentage',
showAdditionalOptions: false,
metodePenyusutan: null,
tanggalMulaiPenyusutan: '11/09/2025',
akumulasiPenyusutan: '0',
batasBiaya: '0',
nilaiResidu: '0',
showImageUpload: false,
uploadedImage: null
})
const handleInputChange = (field: keyof FormData, value: any) => {
setFormData(prev => ({
...prev,
[field]: value
}))
}
// Sample options - replace with your actual data
const akunAsetTetapOptions = [{ label: '1-10705 Aset Tetap - Perlengkapan Kantor', value: '1-10705' }]
const dikreditkanDariAkunOptions = [{ label: 'Silakan pilih dikreditkan dari akun', value: '' }]
const akunAkumulasiPenyusutanOptions = [{ label: 'Silakan pilih akun akumulasi penyusutan', value: '' }]
const akunPenyusutanOptions = [{ label: 'Silakan pilih akbun penyusutan', value: '' }]
const metodePenyusutanOptions = [
{ label: 'Straight Line', value: 'straight-line' },
{ label: 'Declining Balance', value: 'declining-balance' },
{ label: 'Sum of Years Digits', value: 'sum-of-years' }
]
const handleUpload = (file: File, url: string) => {
handleInputChange('uploadedImage', url)
console.log('Image uploaded:', { file, url })
}
const handleSubmit = () => {
console.log('Form Data:', formData)
// Handle form submission here
}
return (
<Card>
<CardContent>
<Typography variant='h6' gutterBottom>
Detil
</Typography>
<Box sx={{ mb: 2 }}>
<Button
variant='text'
color='primary'
sx={{ textTransform: 'none', p: 0, minWidth: 'auto' }}
onClick={() => handleInputChange('showImageUpload', !formData.showImageUpload)}
>
{formData.showImageUpload ? '- Sembunyikan gambar aset tetap' : '+ Tampilkan gambar aset tetap'}
</Button>
</Box>
{/* Image Upload Section */}
{formData.showImageUpload && (
<Box sx={{ mb: 3 }}>
<ImageUpload
onUpload={handleUpload}
maxFileSize={1 * 1024 * 1024} // 1MB
showUrlOption={false}
dragDropText='Drop your image here'
browseButtonText='Choose Image'
/>
{formData.uploadedImage && (
<Box sx={{ mt: 2, textAlign: 'center' }}>
<img
src={formData.uploadedImage}
alt='Uploaded asset'
style={{ maxWidth: '200px', maxHeight: '200px', borderRadius: '8px' }}
/>
</Box>
)}
</Box>
)}
<Grid container spacing={3}>
{/* Left Column */}
<Grid size={{ xs: 12, md: 6 }}>
<CustomTextField
fullWidth
label='Nama Aset'
placeholder='Nama Aset'
value={formData.namaAset}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => handleInputChange('namaAset', e.target.value)}
required
sx={{ mb: 3 }}
/>
<CustomTextField
fullWidth
label='Tanggal Pembelian'
type='date'
value={formData.tanggalPembelian}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
handleInputChange('tanggalPembelian', e.target.value)
}
InputLabelProps={{
shrink: true
}}
required
sx={{ mb: 3 }}
/>
<CustomAutocomplete
fullWidth
options={akunAsetTetapOptions}
value={formData.akunAsetTetap}
onChange={(event, newValue) => handleInputChange('akunAsetTetap', newValue)}
renderInput={params => (
<CustomTextField
{...params}
label='Akun Aset Tetap'
placeholder='1-10705 Aset Tetap - Perlengkapan Kantor'
fullWidth
required
/>
)}
sx={{ mb: 3 }}
/>
<CustomTextField
fullWidth
label='Deskripsi'
placeholder='Deskripsi'
multiline
rows={4}
value={formData.deskripsi}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => handleInputChange('deskripsi', e.target.value)}
sx={{ mb: 3 }}
/>
<CustomTextField
fullWidth
label='Referensi'
placeholder='Referensi'
value={formData.referensi}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => handleInputChange('referensi', e.target.value)}
/>
</Grid>
{/* Right Column */}
<Grid size={{ xs: 12, md: 6 }}>
<CustomTextField
fullWidth
label='Nomor'
value={formData.nomor}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => handleInputChange('nomor', e.target.value)}
sx={{ mb: 3 }}
/>
<CustomTextField
fullWidth
label='Harga Beli'
type='number'
value={formData.hargaBeli}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => handleInputChange('hargaBeli', e.target.value)}
sx={{ mb: 3 }}
/>
<CustomAutocomplete
fullWidth
options={dikreditkanDariAkunOptions}
value={formData.dikreditkanDariAkun}
onChange={(event, newValue) => handleInputChange('dikreditkanDariAkun', newValue)}
renderInput={params => (
<CustomTextField
{...params}
label='Dikreditkan Dari Akun'
placeholder='Silakan pilih dikreditkan dari akun'
fullWidth
required
/>
)}
sx={{ mb: 3 }}
/>
</Grid>
</Grid>
{/* Penyusutan Section */}
<Box sx={{ mt: 4 }}>
<Typography variant='h6' gutterBottom>
Penyusutan
</Typography>
<FormControlLabel
control={
<Switch
checked={formData.tanpaPenyusutan}
onChange={e => handleInputChange('tanpaPenyusutan', e.target.checked)}
color='primary'
/>
}
label='Tanpa penyusutan'
/>
{/* Show depreciation fields when switch is OFF (false) */}
{!formData.tanpaPenyusutan && (
<Grid container spacing={3} sx={{ mt: 2 }}>
<Grid size={{ xs: 12, md: 6 }}>
<CustomAutocomplete
fullWidth
options={akunAkumulasiPenyusutanOptions}
value={formData.akunAkumulasiPenyusutan}
onChange={(event, newValue) => handleInputChange('akunAkumulasiPenyusutan', newValue)}
renderInput={params => (
<CustomTextField
{...params}
label='Akun Akumulasi Penyusutan'
placeholder='Silakan pilih akun akumulasi penyusutan'
fullWidth
required
/>
)}
sx={{ mb: 3 }}
/>
</Grid>
<Grid size={{ xs: 12, md: 6 }}>
<CustomAutocomplete
fullWidth
options={akunPenyusutanOptions}
value={formData.akunPenyusutan}
onChange={(event, newValue) => handleInputChange('akunPenyusutan', newValue)}
renderInput={params => (
<CustomTextField
{...params}
label='Akun penyusutan'
placeholder='Silakan pilih akbun penyusutan'
fullWidth
required
/>
)}
sx={{ mb: 3 }}
/>
</Grid>
<Grid size={{ xs: 12, md: 6 }}>
<Box sx={{ mb: 3 }}>
<Typography variant='body2' sx={{ mb: 1, fontWeight: 500 }}>
Nilai penyusutan per tahun *
</Typography>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<Radio
checked={formData.depreciationType === 'percentage'}
onChange={() => handleInputChange('depreciationType', 'percentage')}
value='percentage'
name='depreciation-method'
color='primary'
size='small'
/>
<Box>
<CustomTextField
value={formData.nilaiPenyusuanPerTahun}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
handleInputChange('nilaiPenyusuanPerTahun', e.target.value)
}
disabled={formData.depreciationType !== 'percentage'}
sx={{
flex: 1,
'& .MuiOutlinedInput-root': {
border: 'none',
'& fieldset': {
border: 'none'
}
}
}}
/>
</Box>
</Box>
</Box>
</Grid>
<Grid size={{ xs: 12, md: 6 }}>
<Box sx={{ mb: 3 }}>
<Typography variant='body2' sx={{ mb: 1, fontWeight: 500 }}>
Masa Manfaat *
</Typography>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<Radio
checked={formData.depreciationType === 'useful-life'}
onChange={() => handleInputChange('depreciationType', 'useful-life')}
value='useful-life'
name='depreciation-method'
color='primary'
size='small'
/>
<Box>
<CustomTextField
placeholder='Tahun'
value={formData.masaManfaatTahun}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
handleInputChange('masaManfaatTahun', e.target.value)
}
disabled={formData.depreciationType !== 'useful-life'}
sx={{
flex: 1,
'& .MuiOutlinedInput-root': {
borderRadius: 0,
borderRight: '1px solid #e0e0e0',
'& fieldset': {
border: 'none'
}
}
}}
/>
<CustomTextField
placeholder='Bulan'
value={formData.masaManfaatBulan}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
handleInputChange('masaManfaatBulan', e.target.value)
}
disabled={formData.depreciationType !== 'useful-life'}
sx={{
flex: 1,
'& .MuiOutlinedInput-root': {
borderRadius: 0,
'& fieldset': {
border: 'none'
}
}
}}
/>
</Box>
</Box>
</Box>
</Grid>
<Grid size={12}>
<Button
variant='text'
color='primary'
sx={{ textTransform: 'none', p: 0, minWidth: 'auto' }}
onClick={() => handleInputChange('showAdditionalOptions', !formData.showAdditionalOptions)}
>
{formData.showAdditionalOptions ? '- Sembunyikan opsi lainnya' : '+ Tampilkan opsi lainnya'}
</Button>
</Grid>
{/* Additional Options */}
{formData.showAdditionalOptions && (
<>
<Grid size={{ xs: 12, md: 6 }}>
<Typography variant='body2' sx={{ mb: 1, fontWeight: 500, color: 'error.main' }}>
Metode Penyusutan *
</Typography>
<CustomAutocomplete
fullWidth
options={metodePenyusutanOptions}
value={formData.metodePenyusutan}
onChange={(event, newValue) => handleInputChange('metodePenyusutan', newValue)}
renderInput={params => (
<CustomTextField {...params} placeholder='Straight Line' fullWidth required />
)}
sx={{ mb: 3 }}
/>
</Grid>
<Grid size={{ xs: 12, md: 6 }}>
<Typography variant='body2' sx={{ mb: 1, fontWeight: 500 }}>
Tanggal Mulai Penyusutan
</Typography>
<CustomTextField
fullWidth
type='date'
value={formData.tanggalMulaiPenyusutan}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
handleInputChange('tanggalMulaiPenyusutan', e.target.value)
}
InputLabelProps={{
shrink: true
}}
sx={{ mb: 3 }}
/>
</Grid>
<Grid size={{ xs: 12, md: 4 }}>
<Typography variant='body2' sx={{ mb: 1, fontWeight: 500 }}>
Akumulasi Penyusutan
</Typography>
<CustomTextField
fullWidth
type='number'
value={formData.akumulasiPenyusutan}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
handleInputChange('akumulasiPenyusutan', e.target.value)
}
sx={{ mb: 3 }}
/>
</Grid>
<Grid size={{ xs: 12, md: 4 }}>
<Typography variant='body2' sx={{ mb: 1, fontWeight: 500 }}>
Batas Biaya
</Typography>
<CustomTextField
fullWidth
type='number'
value={formData.batasBiaya}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
handleInputChange('batasBiaya', e.target.value)
}
sx={{ mb: 3 }}
/>
</Grid>
<Grid size={{ xs: 12, md: 4 }}>
<Typography variant='body2' sx={{ mb: 1, fontWeight: 500 }}>
Nilai Residu
</Typography>
<CustomTextField
fullWidth
type='number'
value={formData.nilaiResidu}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
handleInputChange('nilaiResidu', e.target.value)
}
sx={{ mb: 3 }}
/>
</Grid>
</>
)}
</Grid>
)}
</Box>
{/* Submit Button */}
<Box sx={{ mt: 4, display: 'flex', justifyContent: 'flex-end' }}>
<Button variant='contained' color='primary' onClick={handleSubmit} sx={{ minWidth: 120 }}>
Simpan
</Button>
</Box>
</CardContent>
</Card>
)
}
export default FixedAssetAddForm