This commit is contained in:
2026-04-18 01:23:37 +03:30
parent d43bd74a06
commit 80ba238713
16 changed files with 98 additions and 70 deletions
@@ -1,8 +0,0 @@
// Components Imports
import PlantPestDetection from '@views/dashboards/farm/pestDetection/PlantPestDetection'
const PestDetectionPage = async () => {
return <PlantPestDetection />
}
export default PestDetectionPage
@@ -1,7 +1,7 @@
import PestRiskPageWrapper from '@views/dashboards/farm/PestRiskPageWrapper'
import PestManagementPage from '@views/dashboards/farm/PestManagementPage'
const PestRiskPage = async () => {
return <PestRiskPageWrapper />
const PestRiskPage = () => {
return <PestManagementPage />
}
export default PestRiskPage
@@ -1,7 +0,0 @@
import PlantSimulator from '@views/dashboards/farm/plantSimulator/PlantSimulator'
const PlantSimulatorPage = () => {
return <PlantSimulator />
}
export default PlantSimulatorPage
@@ -1,7 +1,7 @@
import YieldHarvestPageWrapper from '@views/dashboards/farm/YieldHarvestPageWrapper'
import PlantProductionPage from '@views/dashboards/farm/PlantProductionPage'
const YieldHarvestPage = async () => {
return <YieldHarvestPageWrapper />
const YieldHarvestPage = () => {
return <PlantProductionPage />
}
export default YieldHarvestPage
+3 -3
View File
@@ -19,8 +19,8 @@ const CardStatsVertical = (props: CardStatsVerticalProps) => {
props
return (
<Card>
<CardContent className='flex flex-col gap-y-3 items-start'>
<Card sx={{ height: '100%', display: 'flex', width: '100%' }}>
<CardContent className='flex flex-col gap-y-3 items-start' sx={{ flex: 1 }}>
<CustomAvatar variant='rounded' skin={avatarSkin} size={avatarSize} color={avatarColor}>
<i className={classnames(avatarIcon, 'text-[28px]')} />
</CustomAvatar>
@@ -29,7 +29,7 @@ const CardStatsVertical = (props: CardStatsVerticalProps) => {
<Typography color='text.disabled'>{subtitle}</Typography>
<Typography color='text.primary'>{stats}</Typography>
</div>
<Chip label={chipText} color={chipColor} variant={chipVariant} size='small' />
<Chip label={chipText} color={chipColor} variant={chipVariant} size='small' sx={{ marginTop: 'auto' }} />
</CardContent>
</Card>
)
@@ -128,11 +128,6 @@ const VerticalMenu = ({ scrollMenu }: Props) => {
</MenuItem>
</MenuSection>
<MenuSection label={t('simulator')}>
<MenuItem href="/plant-simulator" icon={<i className="tabler-flower" />}>
{t('plantSimulator')}
</MenuItem>
</MenuSection>
<MenuSection label={t('recommendation')}>
<MenuItem href="/irrigation-recommendation" icon={<i className="tabler-droplet-half-2" />}>
{t('irrigationRecommendation')}
@@ -145,9 +140,6 @@ const VerticalMenu = ({ scrollMenu }: Props) => {
<MenuItem href="/farm-ai-assistant" icon={<i className="tabler-robot" />}>
{t('farmAiAssistant')}
</MenuItem>
<MenuItem href="/pest-detection" icon={<i className="tabler-bug" />}>
{t('pestDetection')}
</MenuItem>
</MenuSection>
</Menu>
@@ -65,11 +65,6 @@ const horizontalMenuData = (): HorizontalMenuDataType[] => [
icon: 'tabler-chart-line',
href: '/yield-harvest'
},
{
label: 'plantSimulator',
icon: 'tabler-seeding',
href: '/plant-simulator'
},
{
label: 'farmAlerts',
icon: 'tabler-alert-triangle',
@@ -126,11 +121,6 @@ const horizontalMenuData = (): HorizontalMenuDataType[] => [
icon: 'tabler-chart-line',
href: '/yield-harvest'
},
{
label: 'plantSimulator',
icon: 'tabler-seeding',
href: '/plant-simulator'
},
{
label: 'farmAlerts',
icon: 'tabler-alert-triangle',
-5
View File
@@ -69,11 +69,6 @@ const verticalMenuData = (): VerticalMenuDataType[] => [
icon: 'tabler-chart-line',
href: '/yield-harvest'
},
{
label: 'plantSimulator',
icon: 'tabler-seeding',
href: '/plant-simulator'
},
{
label: 'farmAlerts',
icon: 'tabler-alert-triangle',
+12 -3
View File
@@ -25,12 +25,21 @@ const FarmOverviewKPIs = ({ data }: FarmOverviewKPIsProps) => {
const kpis = (data?.kpis as KpiItem[] | undefined) ?? []
if (kpis.length === 0) return null
const getGridSize = (count) => {
if (count === 1) return { xs: 12 };
if (count === 2) return { xs: 12, md: 6 };
if (count === 3) return { xs: 12, sm: 6, md: 4 };
if (count === 4) return { xs: 12, sm: 6, md: 3 };
return { xs: 12, sm: 6, md: 4, lg: 2 };
};
return (
<>
{kpis.map((kpi) => (
<Grid key={kpi.id} size={{ xs: 12, sm: 6, md: 4, lg: 2 }}>
<CardStatsVertical
<Grid
key={kpi.id}
size={getGridSize(kpis.length)}
sx={{ display: "flex" }}
> <CardStatsVertical
title={kpi.title}
subtitle={kpi.subtitle}
stats={kpi.stats}
@@ -26,7 +26,7 @@ const HarvestPredictionCard = ({ data }: HarvestPredictionCardProps) => {
const description = (data?.description as string) ?? ''
return (
<Card>
<Card sx={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
<CardHeader
avatar={
<CustomAvatar skin='light' color='success' size={44}>
@@ -37,18 +37,16 @@ const HarvestPredictionCard = ({ data }: HarvestPredictionCardProps) => {
subheader={t('subheaders.aiEstimatedDate')}
action={<OptionMenu options={[t('optionMenu.details'), t('optionMenu.adjust'), t('optionMenu.export')]} />}
/>
<CardContent className='flex flex-col gap-4'>
<CardContent className='flex flex-col gap-4' sx={{ flex: 1, justifyContent: 'space-between' }}>
<div className='flex items-center gap-4'>
<Typography variant='h3'>{harvestDate}</Typography>
{daysLeftFormatted && (
<Chip label={daysLeftFormatted} color='info' size='small' variant='tonal' />
)}
</div>
{description && (
<Typography variant='body2' color='text.secondary'>
{description}
</Typography>
)}
<Typography variant='body2' color='text.secondary'>
{description}
</Typography>
</CardContent>
</Card>
)
@@ -0,0 +1,24 @@
'use client'
import Grid from '@mui/material/Grid2'
import PestRiskPageWrapper from '@views/dashboards/farm/PestRiskPageWrapper'
import PlantPestDetection from '@views/dashboards/farm/pestDetection/PlantPestDetection'
const PestManagementPage = () => {
return (
<Grid container sx={{
width:"100%"
}} spacing={6} alignItems='stretch'>
<Grid size={{ xs: 12, xl: 12 }}>
<PestRiskPageWrapper />
</Grid>
<Grid size={{ xs: 12, xl: 12 }}>
<PlantPestDetection />
</Grid>
</Grid>
)
}
export default PestManagementPage
@@ -6,12 +6,20 @@ import { useFarmHub } from '@/hooks/useFarmHub'
import Grid from '@mui/material/Grid2'
import Box from '@mui/material/Box'
import CircularProgress from '@mui/material/CircularProgress'
import Typography from '@mui/material/Typography'
import FarmOverviewKPIs from '@views/dashboards/farm/FarmOverviewKPIs'
import { pestDetectionDomainService } from '@/libs/api/services/pestDetectionDomainService'
import type { PestRiskSummary } from '@/libs/api/services/pestDetectionDomainService'
const sectionSx = {
display: 'flex',
flexDirection: 'column',
gap: 3,
minHeight: '100%'
}
const PestRiskPageWrapper = () => {
const { farmHub } = useFarmHub()
const farmUuid = farmHub?.farm_uuid
@@ -42,16 +50,21 @@ const PestRiskPageWrapper = () => {
}
return (
<Box position='relative'>
<Grid container spacing={6}>
<Box position='relative' sx={{ width: '100%' }}>
<Grid container spacing={6} alignItems='stretch'>
{data.disease_risk && (
<Grid size={12} container spacing={6}>
<FarmOverviewKPIs data={data.disease_risk as Record<string, unknown>} />
<Grid size={{ xs: 12, md: 6 }} sx={sectionSx}>
<Grid container spacing={6} alignItems='stretch'>
<FarmOverviewKPIs data={data.disease_risk as Record<string, unknown>} />
</Grid>
</Grid>
)}
{data.pest_risk && (
<Grid size={12} container spacing={6}>
<FarmOverviewKPIs data={data.pest_risk as Record<string, unknown>} />
<Grid size={{ xs: 12, md: 6 }} sx={sectionSx}>
<Grid container spacing={6} alignItems='stretch'>
<FarmOverviewKPIs data={data.pest_risk as Record<string, unknown>} />
</Grid>
</Grid>
)}
</Grid>
@@ -0,0 +1,22 @@
'use client'
import Grid from '@mui/material/Grid2'
import YieldHarvestPageWrapper from '@views/dashboards/farm/YieldHarvestPageWrapper'
import PlantSimulator from '@views/dashboards/farm/plantSimulator/PlantSimulator'
const PlantProductionPage = () => {
return (
<Grid container spacing={6} alignItems='stretch'>
<Grid size={{ xs: 12, xl: 12 }} sx={{ display: 'flex' }}>
<PlantSimulator />
</Grid>
<Grid size={{ xs: 12, xl: 12 }} sx={{ display: 'flex' }}>
<YieldHarvestPageWrapper />
</Grid>
</Grid>
)
}
export default PlantProductionPage
@@ -51,10 +51,10 @@ const YieldHarvestPageWrapper = () => {
}
return (
<Box position='relative'>
<Grid container spacing={6}>
<Box position='relative' sx={{ width: '100%' }}>
<Grid container spacing={6} alignItems='stretch'>
{data.yield_prediction && (
<Grid size={12} container spacing={6}>
<Grid size={12} container spacing={6} alignItems='stretch'>
<FarmOverviewKPIs data={data.yield_prediction as Record<string, unknown>} />
</Grid>
)}
@@ -90,16 +90,16 @@ const YieldPredictionChart = ({ data }: YieldPredictionChartProps) => {
}
return (
<Card>
<Card sx={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
<CardHeader
title={t('cards.yieldPredictionChart')}
subheader={t('subheaders.thisYearVsLastYear')}
action={<OptionMenu options={[t('optionMenu.export'), t('optionMenu.compare'), t('optionMenu.details')]} />}
/>
<CardContent className='flex flex-col gap-4'>
<CardContent className='flex flex-col gap-4' sx={{ flex: 1 }}>
<AppReactApexCharts type='line' height={280} width='100%' series={series} options={options} />
{summary.length > 0 && (
<div className='flex flex-col gap-4'>
<div className='flex flex-col gap-4' style={{ marginTop: 'auto' }}>
{summary.map((item, index) => (
<div key={index} className='flex items-center gap-4'>
<CustomAvatar skin='light' variant='rounded' color={item.avatarColor as 'primary'} size={38}>
@@ -75,7 +75,7 @@ export default function PlantPestDetection() {
return (
<Box
className={classnames(commonLayoutClasses.contentHeightFixed, 'flex flex-col is-full overflow-hidden rounded')}
sx={{ minHeight: '100%' }}
sx={{ minHeight: '100%', width: '100%' }}
>
<Box className="is-full py-6 sm:py-8 flex flex-col">
{/* Header */}