Merge remote-tracking branch 'origin/main' into efril

This commit is contained in:
efrilm
2025-08-14 00:11:27 +07:00
29 changed files with 440 additions and 209 deletions
@@ -352,7 +352,7 @@ const CreateOrganization = () => {
required
label='Organization Name'
placeholder='My Company Ltd.'
value={formData.organization_name}
value={formData.organization_name || ''}
onChange={handleInputChange('organization_name')}
error={!!errors.organization_name}
helperText={errors.organization_name}
@@ -395,7 +395,7 @@ const CreateOrganization = () => {
required
label='Admin Name'
placeholder='John Doe'
value={formData.admin_name}
value={formData.admin_name || ''}
onChange={handleInputChange('admin_name')}
error={!!errors.admin_name}
helperText={errors.admin_name}
@@ -408,7 +408,7 @@ const CreateOrganization = () => {
label='Admin Email'
placeholder='admin@mycompany.com'
type='email'
value={formData.admin_email}
value={formData.admin_email || ''}
onChange={handleInputChange('admin_email')}
error={!!errors.admin_email}
helperText={errors.admin_email}
@@ -421,7 +421,7 @@ const CreateOrganization = () => {
type='password'
label='Admin Password'
placeholder='Minimum 6 characters'
value={formData.admin_password}
value={formData.admin_password || ''}
onChange={handleInputChange('admin_password')}
error={!!errors.admin_password}
helperText={errors.admin_password}
@@ -443,7 +443,7 @@ const CreateOrganization = () => {
required
label='Outlet Name'
placeholder='Main Store'
value={formData.outlet_name}
value={formData.outlet_name || ''}
onChange={handleInputChange('outlet_name')}
error={!!errors.outlet_name}
helperText={errors.outlet_name}
@@ -3,12 +3,11 @@ import Grid from '@mui/material/Grid2'
// Component Imports
import ProductAddHeader from '@views/apps/ecommerce/products/add/ProductAddHeader'
import ProductInformation from '@views/apps/ecommerce/products/add/ProductInformation'
import ProductImage from '@views/apps/ecommerce/products/add/ProductImage'
import ProductVariants from '@views/apps/ecommerce/products/add/ProductVariants'
import ProductInventory from '@views/apps/ecommerce/products/add/ProductInventory'
import ProductPricing from '@views/apps/ecommerce/products/add/ProductPricing'
import ProductInformation from '@views/apps/ecommerce/products/add/ProductInformation'
import ProductOrganize from '@views/apps/ecommerce/products/add/ProductOrganize'
import ProductPricing from '@views/apps/ecommerce/products/add/ProductPricing'
import ProductVariants from '@views/apps/ecommerce/products/add/ProductVariants'
const eCommerceProductsEdit = () => {
return (
@@ -27,9 +26,6 @@ const eCommerceProductsEdit = () => {
<Grid size={{ xs: 12 }}>
<ProductVariants />
</Grid>
<Grid size={{ xs: 12 }}>
<ProductInventory />
</Grid>
</Grid>
</Grid>
<Grid size={{ xs: 12, md: 4 }}>
@@ -14,12 +14,12 @@ const DashboardOverview = () => {
if (isLoading) return <Loading />
const MetricCard = ({ iconClass, title, value, subtitle, bgColor = 'bg-blue-500' }: any) => (
const MetricCard = ({ iconClass, title, value, subtitle, bgColor = 'bg-blue-500', isCurrency = false }: any) => (
<div className='bg-white rounded-lg shadow-md hover:shadow-xl transition-shadow duration-300 p-6'>
<div className='flex items-center justify-between'>
<div className='flex-1'>
<h3 className='text-sm font-medium text-gray-600 mb-2'>{title}</h3>
<p className='text-2xl font-bold text-gray-900 mb-1'>{value}</p>
<p className='text-2xl font-bold text-gray-900 mb-1'>{isCurrency ? 'Rp ' + value : value}</p>
{subtitle && <p className='text-sm text-gray-500'>{subtitle}</p>}
</div>
<div className={`px-4 py-3 rounded-full ${bgColor} bg-opacity-10`}>
@@ -52,12 +52,6 @@ const DashboardOverview = () => {
{/* Overview Metrics */}
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8'>
<MetricCard
iconClass='tabler-cash'
title='Total Sales'
value={formatShortCurrency(salesData.overview.total_sales)}
bgColor='bg-green-500'
/>
<MetricCard
iconClass='tabler-shopping-cart'
title='Total Orders'
@@ -65,11 +59,19 @@ const DashboardOverview = () => {
subtitle={`${salesData.overview.voided_orders} voided, ${salesData.overview.refunded_orders} refunded`}
bgColor='bg-blue-500'
/>
<MetricCard
iconClass='tabler-cash'
title='Total Sales'
value={formatShortCurrency(salesData.overview.total_sales)}
bgColor='bg-green-500'
isCurrency={true}
/>
<MetricCard
iconClass='tabler-trending-up'
title='Average Order Value'
value={formatShortCurrency(salesData.overview.average_order_value)}
bgColor='bg-purple-500'
isCurrency={true}
/>
<MetricCard
iconClass='tabler-users'
@@ -39,7 +39,7 @@ const DashboardProfitloss = () => {
function formatMetricName(metric: string): string {
const nameMap: { [key: string]: string } = {
revenue: 'Revenue',
net_profit: 'Net Profit',
net_profit: 'Net Profit'
}
return nameMap[metric] || metric.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase())
@@ -61,15 +61,25 @@ const DashboardProfitloss = () => {
]
}
const MetricCard = ({ iconClass, title, value, subtitle, bgColor = 'bg-blue-500', isNegative = false }: any) => (
const MetricCard = ({
iconClass,
title,
value,
subtitle,
bgColor = 'bg-blue-500',
isNegative = false,
isCurrency = false
}: any) => (
<div className='bg-white rounded-lg shadow-md hover:shadow-xl transition-shadow duration-300 p-6'>
<div className='flex items-center justify-between'>
<div className='flex-1'>
<h3 className='text-sm font-medium text-gray-600 mb-2'>{title}</h3>
<p className={`text-2xl font-bold mb-1 ${isNegative ? 'text-red-600' : 'text-gray-900'}`}>{value}</p>
<p className={`text-2xl font-bold mb-1 ${isNegative ? 'text-red-600' : 'text-gray-900'}`}>
{isCurrency ? 'Rp ' + value : value}
</p>
{subtitle && <p className='text-sm text-gray-500'>{subtitle}</p>}
</div>
<div className={`p-3 rounded-full ${bgColor} bg-opacity-10`}>
<div className={`px-4 py-3 rounded-full ${bgColor} bg-opacity-10`}>
<i className={`${iconClass} text-[32px] ${bgColor.replace('bg-', 'text-')}`}></i>
</div>
</div>
@@ -95,12 +105,14 @@ const DashboardProfitloss = () => {
title='Total Revenue'
value={formatShortCurrency(profitData.summary.total_revenue)}
bgColor='bg-green-500'
isCurrency={true}
/>
<MetricCard
iconClass='tabler-receipt'
title='Total Cost'
value={formatShortCurrency(profitData.summary.total_cost)}
bgColor='bg-red-500'
isCurrency={true}
/>
<MetricCard
iconClass='tabler-trending-up'
@@ -109,6 +121,7 @@ const DashboardProfitloss = () => {
subtitle={`Margin: ${formatPercentage(profitData.summary.gross_profit_margin)}`}
bgColor='bg-blue-500'
isNegative={profitData.summary.gross_profit < 0}
isCurrency={true}
/>
<MetricCard
iconClass='tabler-percentage'
@@ -127,7 +140,7 @@ const DashboardProfitloss = () => {
<h3 className='text-lg font-semibold text-gray-900'>Net Profit</h3>
</div>
<p className='text-3xl font-bold text-green-600 mb-2'>
{formatShortCurrency(profitData.summary.net_profit)}
Rp {formatShortCurrency(profitData.summary.net_profit)}
</p>
<p className='text-sm text-gray-600'>Margin: {formatPercentage(profitData.summary.net_profit_margin)}</p>
</div>
@@ -144,7 +157,7 @@ const DashboardProfitloss = () => {
<h3 className='text-lg font-semibold text-gray-900'>Tax & Discount</h3>
</div>
<p className='text-xl font-bold text-orange-600 mb-1'>
{formatShortCurrency(profitData.summary.total_tax + profitData.summary.total_discount)}
Rp {formatShortCurrency(profitData.summary.total_tax + profitData.summary.total_discount)}
</p>
<p className='text-sm text-gray-600'>
Tax: {formatShortCurrency(profitData.summary.total_tax)} | Discount:{' '}