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