From 9c1b1fc1db296bbe239b939ccda49bf990178199 Mon Sep 17 00:00:00 2001 From: efrilm Date: Thu, 11 Sep 2025 14:47:57 +0700 Subject: [PATCH] Fixed Asset Add --- .../(private)/apps/fixed-assets/add/page.tsx | 18 + .../apps/fixed-assets/FixedAssetTable.tsx | 2 +- .../fixed-assets/add/FixedAssetAddForm.tsx | 561 ++++++++++++++++++ .../fixed-assets/add/FixedAssetAddHeader.tsx | 19 + 4 files changed, 599 insertions(+), 1 deletion(-) create mode 100644 src/app/[lang]/(dashboard)/(private)/apps/fixed-assets/add/page.tsx create mode 100644 src/views/apps/fixed-assets/add/FixedAssetAddForm.tsx create mode 100644 src/views/apps/fixed-assets/add/FixedAssetAddHeader.tsx diff --git a/src/app/[lang]/(dashboard)/(private)/apps/fixed-assets/add/page.tsx b/src/app/[lang]/(dashboard)/(private)/apps/fixed-assets/add/page.tsx new file mode 100644 index 0000000..adbad6a --- /dev/null +++ b/src/app/[lang]/(dashboard)/(private)/apps/fixed-assets/add/page.tsx @@ -0,0 +1,18 @@ +import FixedAssetAddForm from '@/views/apps/fixed-assets/add/FixedAssetAddForm' +import FixedAssetAddHeader from '@/views/apps/fixed-assets/add/FixedAssetAddHeader' +import Grid from '@mui/material/Grid2' + +const FixedAssetPage = () => { + return ( + + + + + + + + + ) +} + +export default FixedAssetPage diff --git a/src/views/apps/fixed-assets/FixedAssetTable.tsx b/src/views/apps/fixed-assets/FixedAssetTable.tsx index f8226ba..3f5bb1b 100644 --- a/src/views/apps/fixed-assets/FixedAssetTable.tsx +++ b/src/views/apps/fixed-assets/FixedAssetTable.tsx @@ -409,7 +409,7 @@ const FixedAssetTable = () => { component={Link} className='max-sm:is-full is-auto' startIcon={} - href={getLocalizedUrl('/apps/fixed-asset/add', locale as Locale)} + href={getLocalizedUrl('/apps/fixed-assets/add', locale as Locale)} > Tambah Aset diff --git a/src/views/apps/fixed-assets/add/FixedAssetAddForm.tsx b/src/views/apps/fixed-assets/add/FixedAssetAddForm.tsx new file mode 100644 index 0000000..e83c855 --- /dev/null +++ b/src/views/apps/fixed-assets/add/FixedAssetAddForm.tsx @@ -0,0 +1,561 @@ +'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) => { + const files = Array.from(e.target.files || []) + if (files[0]) { + handleFileSelect(files[0]) + } + } + + return ( + { + e.preventDefault() + setDragOver(true) + }} + onDragLeave={() => setDragOver(false)} + > + + {dragDropText} + + + + + ) +} + +const FixedAssetAddForm = () => { + const [formData, setFormData] = useState({ + 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 ( + + + + Detil + + + + + + + {/* Image Upload Section */} + {formData.showImageUpload && ( + + + {formData.uploadedImage && ( + + Uploaded asset + + )} + + )} + + + {/* Left Column */} + + ) => handleInputChange('namaAset', e.target.value)} + required + sx={{ mb: 3 }} + /> + + ) => + handleInputChange('tanggalPembelian', e.target.value) + } + InputLabelProps={{ + shrink: true + }} + required + sx={{ mb: 3 }} + /> + + handleInputChange('akunAsetTetap', newValue)} + renderInput={params => ( + + )} + sx={{ mb: 3 }} + /> + + ) => handleInputChange('deskripsi', e.target.value)} + sx={{ mb: 3 }} + /> + + ) => handleInputChange('referensi', e.target.value)} + /> + + + {/* Right Column */} + + ) => handleInputChange('nomor', e.target.value)} + sx={{ mb: 3 }} + /> + + ) => handleInputChange('hargaBeli', e.target.value)} + sx={{ mb: 3 }} + /> + + handleInputChange('dikreditkanDariAkun', newValue)} + renderInput={params => ( + + )} + sx={{ mb: 3 }} + /> + + + + {/* Penyusutan Section */} + + + Penyusutan + + + handleInputChange('tanpaPenyusutan', e.target.checked)} + color='primary' + /> + } + label='Tanpa penyusutan' + /> + + {/* Show depreciation fields when switch is OFF (false) */} + {!formData.tanpaPenyusutan && ( + + + handleInputChange('akunAkumulasiPenyusutan', newValue)} + renderInput={params => ( + + )} + sx={{ mb: 3 }} + /> + + + + handleInputChange('akunPenyusutan', newValue)} + renderInput={params => ( + + )} + sx={{ mb: 3 }} + /> + + + + + + Nilai penyusutan per tahun * + + + handleInputChange('depreciationType', 'percentage')} + value='percentage' + name='depreciation-method' + color='primary' + size='small' + /> + + ) => + handleInputChange('nilaiPenyusuanPerTahun', e.target.value) + } + disabled={formData.depreciationType !== 'percentage'} + sx={{ + flex: 1, + '& .MuiOutlinedInput-root': { + border: 'none', + '& fieldset': { + border: 'none' + } + } + }} + /> + + + + + + + + + Masa Manfaat * + + + handleInputChange('depreciationType', 'useful-life')} + value='useful-life' + name='depreciation-method' + color='primary' + size='small' + /> + + ) => + handleInputChange('masaManfaatTahun', e.target.value) + } + disabled={formData.depreciationType !== 'useful-life'} + sx={{ + flex: 1, + '& .MuiOutlinedInput-root': { + borderRadius: 0, + borderRight: '1px solid #e0e0e0', + '& fieldset': { + border: 'none' + } + } + }} + /> + ) => + handleInputChange('masaManfaatBulan', e.target.value) + } + disabled={formData.depreciationType !== 'useful-life'} + sx={{ + flex: 1, + '& .MuiOutlinedInput-root': { + borderRadius: 0, + '& fieldset': { + border: 'none' + } + } + }} + /> + + + + + + + + + + {/* Additional Options */} + {formData.showAdditionalOptions && ( + <> + + + Metode Penyusutan * + + handleInputChange('metodePenyusutan', newValue)} + renderInput={params => ( + + )} + sx={{ mb: 3 }} + /> + + + + + Tanggal Mulai Penyusutan + + ) => + handleInputChange('tanggalMulaiPenyusutan', e.target.value) + } + InputLabelProps={{ + shrink: true + }} + sx={{ mb: 3 }} + /> + + + + + Akumulasi Penyusutan + + ) => + handleInputChange('akumulasiPenyusutan', e.target.value) + } + sx={{ mb: 3 }} + /> + + + + + Batas Biaya + + ) => + handleInputChange('batasBiaya', e.target.value) + } + sx={{ mb: 3 }} + /> + + + + + Nilai Residu + + ) => + handleInputChange('nilaiResidu', e.target.value) + } + sx={{ mb: 3 }} + /> + + + )} + + )} + + + {/* Submit Button */} + + + + + + ) +} + +export default FixedAssetAddForm diff --git a/src/views/apps/fixed-assets/add/FixedAssetAddHeader.tsx b/src/views/apps/fixed-assets/add/FixedAssetAddHeader.tsx new file mode 100644 index 0000000..c38957c --- /dev/null +++ b/src/views/apps/fixed-assets/add/FixedAssetAddHeader.tsx @@ -0,0 +1,19 @@ +'use client' + +// MUI Imports +import Button from '@mui/material/Button' +import Typography from '@mui/material/Typography' + +const FixedAssetAddHeader = () => { + return ( +
+
+ + Tambah Asset Tetap + +
+
+ ) +} + +export default FixedAssetAddHeader