stylize darkmode
This commit is contained in:
parent
4ba953f44c
commit
b22ddecdf5
@ -19,7 +19,7 @@ const DashboardLayout = ({ children }: { children: React.ReactNode }) => {
|
||||
|
||||
<div className="main-content">
|
||||
{/* This is where your page content will be injected */}
|
||||
<div className="p-6 space-y-4 min-h-screen">
|
||||
<div className="p-6 space-y-4 min-h-screen dark:bg-rtgray-900">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -167,7 +167,7 @@ const AdminDashboard = () => {
|
||||
return (
|
||||
<DashboardLayout>
|
||||
<div className="px-6 space-y-6">
|
||||
<h1 className="text-lg font-semibold">Admin Dashboard</h1>
|
||||
<h1 className="text-lg font-semibold dark:text-white">Admin Dashboard</h1>
|
||||
|
||||
<div className="grid md:grid-cols-2 gap-6">
|
||||
<div className="space-y-4">
|
||||
|
@ -14,6 +14,10 @@ import {
|
||||
endOfYear,
|
||||
} from 'date-fns';
|
||||
import { fetchPowerTimeseries, fetchForecast } from '@/app/utils/api';
|
||||
import { color } from 'html2canvas/dist/types/css/types/color';
|
||||
import DatePicker from 'react-datepicker';
|
||||
import 'react-datepicker/dist/react-datepicker.css';
|
||||
import './datepicker-dark.css'; // custom dark mode styles
|
||||
|
||||
ChartJS.register(zoomPlugin);
|
||||
|
||||
@ -81,6 +85,22 @@ const EnergyLineChart = ({ siteId }: EnergyLineChartProps) => {
|
||||
const [selectedDate, setSelectedDate] = useState(new Date());
|
||||
const [forecast, setForecast] = useState<TimeSeriesEntry[]>([]);
|
||||
|
||||
function useIsDarkMode() {
|
||||
const [isDark, setIsDark] = useState(() =>
|
||||
typeof document !== 'undefined'
|
||||
? document.body.classList.contains('dark')
|
||||
: false
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const check = () => setIsDark(document.body.classList.contains('dark'));
|
||||
const observer = new MutationObserver(check);
|
||||
observer.observe(document.body, { attributes: true, attributeFilter: ['class'] });
|
||||
return () => observer.disconnect();
|
||||
}, []);
|
||||
|
||||
return isDark;
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const now = new Date();
|
||||
@ -200,6 +220,11 @@ const EnergyLineChart = ({ siteId }: EnergyLineChartProps) => {
|
||||
const maxValue = allValues.length > 0 ? Math.max(...allValues) : 0;
|
||||
const yAxisSuggestedMax = maxValue * 1.15;
|
||||
|
||||
const isDark = useIsDarkMode();
|
||||
|
||||
const axisColor = isDark ? '#fff' : '#222';
|
||||
|
||||
|
||||
const data = {
|
||||
labels: filteredLabels.map(formatLabel),
|
||||
datasets: [
|
||||
@ -235,7 +260,12 @@ const EnergyLineChart = ({ siteId }: EnergyLineChartProps) => {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
legend: { position: 'top' as const },
|
||||
legend: {
|
||||
position: 'top',
|
||||
labels: {
|
||||
color: axisColor, // legend text color
|
||||
},
|
||||
},
|
||||
zoom: {
|
||||
zoom: {
|
||||
wheel: { enabled: true },
|
||||
@ -244,12 +274,22 @@ const EnergyLineChart = ({ siteId }: EnergyLineChartProps) => {
|
||||
},
|
||||
pan: { enabled: true, mode: 'x' as const },
|
||||
},
|
||||
tooltip: { enabled: true, mode: 'index' as const, intersect: false },
|
||||
tooltip: {
|
||||
enabled: true,
|
||||
mode: 'index',
|
||||
intersect: false,
|
||||
backgroundColor: isDark ? '#232b3e' : '#fff',
|
||||
titleColor: axisColor,
|
||||
bodyColor: axisColor,
|
||||
borderColor: isDark ? '#444' : '#ccc',
|
||||
borderWidth: 1,
|
||||
},
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
title: {
|
||||
display: true,
|
||||
color: axisColor,
|
||||
text:
|
||||
viewMode === 'day'
|
||||
? 'Time (HH:MM)'
|
||||
@ -260,7 +300,10 @@ const EnergyLineChart = ({ siteId }: EnergyLineChartProps) => {
|
||||
: viewMode === 'monthly'
|
||||
? 'Month'
|
||||
: 'Year',
|
||||
font: { weight: 'bold' as const },
|
||||
font: { weight: 'normal' as const },
|
||||
},
|
||||
ticks: {
|
||||
color: axisColor,
|
||||
},
|
||||
},
|
||||
y: {
|
||||
@ -269,9 +312,14 @@ const EnergyLineChart = ({ siteId }: EnergyLineChartProps) => {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Power (kW)',
|
||||
font: { weight: 'bold' as const },
|
||||
color: axisColor,
|
||||
font: { weight: 'normal' as const },
|
||||
},
|
||||
ticks: {
|
||||
color: axisColor,
|
||||
},
|
||||
},
|
||||
|
||||
},
|
||||
} as const;
|
||||
|
||||
@ -280,7 +328,7 @@ const EnergyLineChart = ({ siteId }: EnergyLineChartProps) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-white p-4 rounded-lg shadow-md dark:bg-gray-800 dark:text-white-light">
|
||||
<div className="bg-white p-4 rounded-lg shadow-md dark:bg-rtgray-800 dark:text-white-light">
|
||||
<div className="h-98 w-full">
|
||||
<div className="flex justify-between items-center mb-2">
|
||||
<h2 className="text-lg font-bold dark:text-white-light">Energy Consumption & Generation</h2>
|
||||
@ -289,15 +337,15 @@ const EnergyLineChart = ({ siteId }: EnergyLineChartProps) => {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="mb-4 flex gap-4 items-center">
|
||||
<div className="mb-4 flex gap-4 items-center dark:text-white">
|
||||
{viewMode === 'day' && (
|
||||
<label className="font-medium">
|
||||
Date:{' '}
|
||||
<input
|
||||
type="date"
|
||||
value={selectedDate.toISOString().split('T')[0]}
|
||||
onChange={(e) => setSelectedDate(new Date(e.target.value))}
|
||||
className="border rounded p-1"
|
||||
<DatePicker
|
||||
selected={selectedDate}
|
||||
onChange={(date) => setSelectedDate(date!)}
|
||||
dateFormat="dd/MM/yyyy" // ✅ sets correct format
|
||||
className="dark:bg-rtgray-700 dark:text-white bg-white border border-rounded text-black p-1 rounded"
|
||||
/>
|
||||
</label>
|
||||
)}
|
||||
@ -310,7 +358,7 @@ const EnergyLineChart = ({ siteId }: EnergyLineChartProps) => {
|
||||
const val = Number(e.target.value);
|
||||
setStartIndex(val <= endIndex ? val : endIndex);
|
||||
}}
|
||||
className="border rounded p-1"
|
||||
className="dark:bg-rtgray-700 border dark:border-rtgray-700 rounded p-1"
|
||||
>
|
||||
{allTimes.map((label, idx) => (
|
||||
<option key={idx} value={idx}>{formatLabel(label)}</option>
|
||||
@ -325,7 +373,7 @@ const EnergyLineChart = ({ siteId }: EnergyLineChartProps) => {
|
||||
const val = Number(e.target.value);
|
||||
setEndIndex(val >= startIndex ? val : startIndex);
|
||||
}}
|
||||
className="border rounded p-1"
|
||||
className="dark:bg-rtgray-700 border dark:border-rtgray-700 rounded p-1"
|
||||
>
|
||||
{allTimes.map((label, idx) => (
|
||||
<option key={idx} value={idx}>{formatLabel(label)}</option>
|
||||
@ -337,7 +385,7 @@ const EnergyLineChart = ({ siteId }: EnergyLineChartProps) => {
|
||||
<select
|
||||
value={viewMode}
|
||||
onChange={(e) => setViewMode(e.target.value as typeof viewMode)}
|
||||
className="border rounded p-1"
|
||||
className="dark:bg-rtgray-700 border dark:border-rtgray-700 rounded p-1"
|
||||
>
|
||||
<option value="day">Day</option>
|
||||
<option value="daily">Daily</option>
|
||||
|
@ -17,7 +17,6 @@ interface MonthlyKPI {
|
||||
load_factor: number | null;
|
||||
}
|
||||
|
||||
|
||||
const KPI_Table: React.FC<KPI_TableProps> = ({ siteId, month }) => {
|
||||
const [kpiData, setKpiData] = useState<MonthlyKPI | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
@ -81,22 +80,21 @@ const data = [
|
||||
{ kpi: 'Load Factor', value: `${load_factor.toFixed(2)} kW` }, // ✅ added
|
||||
];
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2 className="text-lg font-bold mb-2">Monthly KPI</h2>
|
||||
<table className="min-h-[275px] w-full border-collapse border border-gray-700 text-black bg-white">
|
||||
<h2 className="text-lg font-bold mb-2 dark:text-white">Monthly KPI</h2>
|
||||
<table className="min-h-[275px] w-full border-collapse border border-gray-300 dark:border-rtgray-700 text-black dark:text-white bg-white dark:bg-rtgray-700">
|
||||
<thead>
|
||||
<tr className="bg-gray-800 text-black">
|
||||
<th className="border border-gray-700 p-3 text-left">KPI</th>
|
||||
<th className="border border-gray-700 p-3 text-left">Value</th>
|
||||
<tr className="bg-rtgray-100 dark:bg-rtgray-800 text-black dark:text-white">
|
||||
<th className="border border-rtgray-300 dark:border-rtgray-700 p-3 text-left dark:bg-rtgray-900">KPI</th>
|
||||
<th className="border border-rtgray-300 dark:border-rtgray-700 p-3 text-left dark:bg-rtgray-900">Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{data.map((row) => (
|
||||
<tr key={row.kpi}>
|
||||
<td className="border border-gray-700 p-2.5">{row.kpi}</td>
|
||||
<td className="border border-gray-700 p-2.5">{row.value}</td>
|
||||
<tr key={row.kpi} className="even:bg-rtgray-50 dark:even:bg-rtgray-800">
|
||||
<td className="border border-rtgray-300 dark:border-rtgray-700 p-2.5">{row.kpi}</td>
|
||||
<td className="border border-rtgray-300 dark:border-rtgray-700 p-2.5">{row.value}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
|
@ -11,6 +11,7 @@ import {
|
||||
import { format } from 'date-fns';
|
||||
import { fetchPowerTimeseries } from '@/app/utils/api';
|
||||
|
||||
|
||||
interface MonthlyBarChartProps {
|
||||
siteId: string;
|
||||
}
|
||||
@ -39,8 +40,7 @@ const groupTimeSeries = (
|
||||
}));
|
||||
};
|
||||
|
||||
const consumptionColor = '#003049';
|
||||
const generationColor = '#669bbc';
|
||||
|
||||
|
||||
const MonthlyBarChart: React.FC<MonthlyBarChartProps> = ({ siteId }) => {
|
||||
const [chartData, setChartData] = useState<
|
||||
@ -48,6 +48,32 @@ const MonthlyBarChart: React.FC<MonthlyBarChartProps> = ({ siteId }) => {
|
||||
>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
function useIsDarkMode() {
|
||||
const [isDark, setIsDark] = useState(() =>
|
||||
typeof document !== 'undefined'
|
||||
? document.body.classList.contains('dark')
|
||||
: false
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const check = () => setIsDark(document.body.classList.contains('dark'));
|
||||
check();
|
||||
|
||||
// Listen for class changes on <body>
|
||||
const observer = new MutationObserver(check);
|
||||
observer.observe(document.body, { attributes: true, attributeFilter: ['class'] });
|
||||
|
||||
return () => observer.disconnect();
|
||||
}, []);
|
||||
|
||||
return isDark;
|
||||
}
|
||||
|
||||
const isDark = useIsDarkMode();
|
||||
|
||||
const consumptionColor = isDark ? '#ba8e23' : '#003049';
|
||||
const generationColor = isDark ? '#fcd913' : '#669bbc';
|
||||
|
||||
useEffect(() => {
|
||||
if (!siteId) return;
|
||||
|
||||
@ -100,7 +126,7 @@ const MonthlyBarChart: React.FC<MonthlyBarChartProps> = ({ siteId }) => {
|
||||
|
||||
if (loading || !siteId || chartData.length === 0) {
|
||||
return (
|
||||
<div className="bg-white p-4 rounded-lg shadow-md dark:bg-gray-800 dark:text-white-light">
|
||||
<div className="bg-white p-4 rounded-lg shadow-md dark:bg-rtgray-800 dark:text-white-light">
|
||||
<div className="flex justify-between items-center mb-2">
|
||||
<h2 className="text-lg font-bold pb-3">Monthly Energy Yield</h2>
|
||||
</div>
|
||||
@ -114,7 +140,7 @@ const MonthlyBarChart: React.FC<MonthlyBarChartProps> = ({ siteId }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="bg-white p-4 rounded-lg shadow-md dark:bg-gray-800 dark:text-white-light">
|
||||
<div className="bg-white p-4 rounded-lg shadow-md dark:bg-rtgray-800 dark:text-white-light">
|
||||
<div className="flex justify-between items-center mb-2">
|
||||
<h2 className="text-lg font-bold pb-3">Monthly Energy Yield</h2>
|
||||
</div>
|
||||
@ -122,13 +148,38 @@ const MonthlyBarChart: React.FC<MonthlyBarChartProps> = ({ siteId }) => {
|
||||
<div className="lg:h-[22.6vw] h-[290px] w-full pt-10">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<BarChart data={chartData}>
|
||||
<XAxis dataKey="month" tick={{ fontSize: 10 }} />
|
||||
<YAxis tick={{ fontSize: 10 }} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tick={{ fontSize: 10, fill: isDark ? '#fff' : '#222' }}
|
||||
axisLine={{ stroke: isDark ? '#fff' : '#222' }}
|
||||
tickLine={{ stroke: isDark ? '#fff' : '#222' }}
|
||||
/>
|
||||
<YAxis
|
||||
tick={{ fontSize: 10, fill: isDark ? '#fff' : '#222' }}
|
||||
axisLine={{ stroke: isDark ? '#fff' : '#222' }}
|
||||
tickLine={{ stroke: isDark ? '#fff' : '#222' }}
|
||||
/>
|
||||
<Tooltip
|
||||
formatter={(value: number) => [`${value.toFixed(2)} kWh`]}
|
||||
labelFormatter={(label) => `${label}`}
|
||||
contentStyle={{
|
||||
background: isDark ? '#232b3e' : '#fff',
|
||||
color: isDark ? '#fff' : '#222',
|
||||
border: isDark ? '1px solid #444' : '1px solid #ccc',
|
||||
}}
|
||||
labelStyle={{
|
||||
color: isDark ? '#fff' : '#222',
|
||||
}}
|
||||
cursor={{
|
||||
fill: isDark ? '#808080' : '#e0e7ef', // dark mode bg, light mode bg
|
||||
fillOpacity: isDark ? 0.6 : 0.3, // adjust opacity as you like
|
||||
}}
|
||||
/>
|
||||
<Legend
|
||||
wrapperStyle={{
|
||||
color: isDark ? '#fff' : '#222',
|
||||
}}
|
||||
/>
|
||||
<Legend />
|
||||
<Bar dataKey="consumption" fill={consumptionColor} name="Consumption (kWh)" />
|
||||
<Bar dataKey="generation" fill={generationColor} name="Generation (kWh)" />
|
||||
</BarChart>
|
||||
|
@ -8,10 +8,10 @@ type SiteSelectorProps = {
|
||||
const SiteSelector = ({ selectedSite, setSelectedSite }: SiteSelectorProps) => {
|
||||
return (
|
||||
<div className="flex flex-col ">
|
||||
<label htmlFor="site" className="font-semibold text-lg">Select Site:</label>
|
||||
<label htmlFor="site" className="font-semibold text-lg dark:text-white">Select Site:</label>
|
||||
<select
|
||||
id="site"
|
||||
className="border p-2 rounded"
|
||||
className="border p-2 rounded dark:text-white dark:bg-rtgray-800 dark:border-rtgray-700"
|
||||
value={selectedSite}
|
||||
onChange={(e) => setSelectedSite(e.target.value as SiteName)}
|
||||
>
|
||||
|
@ -105,12 +105,12 @@ const SiteStatus = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-white p-4 rounded-lg shadow-md space-y-2 dark:bg-gray-800 dark:text-white-light">
|
||||
<div className="bg-white p-4 rounded-lg shadow-md space-y-2 dark:bg-rtgray-800 dark:text-white-light">
|
||||
<h2 className="text-xl font-semibold mb-3">Site Details</h2>
|
||||
|
||||
{/* Status */}
|
||||
<div className="flex justify-between items-center text-base">
|
||||
<p className="text-gray-600 dark:text-gray-400 font-medium">Status:</p>
|
||||
<p className="text-gray-600 dark:text-white/85 font-medium">Status:</p>
|
||||
<p className={`font-semibold ${
|
||||
statusMap[selectedSite] === 'Active' ? 'text-green-500' :
|
||||
statusMap[selectedSite] === 'Inactive' ? 'text-orange-500' :
|
||||
@ -122,31 +122,31 @@ const SiteStatus = ({
|
||||
|
||||
{/* Site ID */}
|
||||
<div className="flex justify-between items-center text-base">
|
||||
<p className="text-gray-600 dark:text-gray-400 font-medium">Site ID:</p>
|
||||
<p className="text-gray-600 dark:text-white/85 font-medium">Site ID:</p>
|
||||
<p className="font-medium">{siteId}</p>
|
||||
</div>
|
||||
|
||||
{/* Location */}
|
||||
<div className="flex justify-between items-center text-base">
|
||||
<p className="text-gray-600 dark:text-gray-400 font-medium">Location:</p>
|
||||
<p className="text-gray-600 dark:text-white/85 font-medium">Location:</p>
|
||||
<p className="font-medium">{location}</p>
|
||||
</div>
|
||||
|
||||
{/* Inverter Provider */}
|
||||
<div className="flex justify-between items-center text-base">
|
||||
<p className="text-gray-600 dark:text-gray-400 font-medium">Inverter Provider:</p>
|
||||
<p className="text-gray-600 dark:text-white/85 font-medium">Inverter Provider:</p>
|
||||
<p className="font-medium">{inverterProvider}</p>
|
||||
</div>
|
||||
|
||||
{/* Emergency Contact */}
|
||||
<div className="flex justify-between items-center text-base">
|
||||
<p className="text-gray-600 dark:text-gray-400 font-medium">Emergency Contact:</p>
|
||||
<p className="text-gray-600 dark:text-white/85 font-medium">Emergency Contact:</p>
|
||||
<p className="font-medium">{emergencyContact}</p>
|
||||
</div>
|
||||
|
||||
{/* Last Sync */}
|
||||
<div className="flex justify-between items-center text-base">
|
||||
<p className="text-gray-600 dark:text-gray-400 font-medium">Last Sync:</p>
|
||||
<p className="text-gray-600 dark:text-white/85 font-medium">Last Sync:</p>
|
||||
<p className="font-medium">{lastSyncTimestamp}</p>
|
||||
</div>
|
||||
|
||||
|
77
components/dashboards/datepicker-dark.css
Normal file
77
components/dashboards/datepicker-dark.css
Normal file
@ -0,0 +1,77 @@
|
||||
/* ========== LIGHT MODE (Default) ========== */
|
||||
.react-datepicker {
|
||||
background-color: #ffffff; /* white bg */
|
||||
color: #111827; /* dark gray text */
|
||||
border: 1px solid #d1d5db; /* light gray border */
|
||||
}
|
||||
|
||||
.react-datepicker__header {
|
||||
background-color: #f3f4f6;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.react-datepicker__day,
|
||||
.react-datepicker__day-name,
|
||||
.react-datepicker__current-month {
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.react-datepicker__navigation-icon::before {
|
||||
border-color: #111827;
|
||||
}
|
||||
|
||||
.react-datepicker__day--selected,
|
||||
.react-datepicker__day--keyboard-selected {
|
||||
background-color: #3b82f6; /* blue highlight */
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.react-datepicker__day:hover {
|
||||
background-color: #e5e7eb;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.react-datepicker__day--disabled {
|
||||
color: #9ca3af;
|
||||
}
|
||||
|
||||
/* ========== DARK MODE (Wrap in `.dark`) ========== */
|
||||
.dark .react-datepicker {
|
||||
background-color: #141624;
|
||||
color: #ffffff;
|
||||
border: 1px solid #374151;
|
||||
}
|
||||
|
||||
.dark .react-datepicker__header {
|
||||
background-color: #080912;
|
||||
border-bottom: 1px solid #4b5563;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.dark .react-datepicker__day,
|
||||
.dark .react-datepicker__day-name,
|
||||
.dark .react-datepicker__current-month {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.dark .react-datepicker__navigation-icon::before {
|
||||
border-color: #ffffff;
|
||||
}
|
||||
|
||||
.dark .react-datepicker__day--selected,
|
||||
.dark .react-datepicker__day--keyboard-selected {
|
||||
background-color: #fcd913;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.dark .react-datepicker__day:hover {
|
||||
background-color: #374151;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.dark .react-datepicker__day--disabled {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ const Sidebar = () => {
|
||||
</div>
|
||||
<PerfectScrollbar className="relative h-[calc(100vh-80px)] ">
|
||||
<ul className="relative space-y-0.5 p-4 py-0 font-md">
|
||||
<h2 className="-mx-4 mb-1 flex items-center bg-white-light/30 px-7 py-3 font-extrabold uppercase dark:bg-dark dark:bg-opacity-[0.08]">
|
||||
<h2 className="-mx-4 mb-1 flex items-center bg-white-light/30 px-7 py-3 font-extrabold uppercase dark:bg-dark dark:bg-opacity-[0.08] dark:text-white dark:active:text-white">
|
||||
<IconMinus className="hidden h-5 w-4 flex-none" />
|
||||
<span>Customer</span>
|
||||
</h2>
|
||||
@ -92,7 +92,7 @@ const Sidebar = () => {
|
||||
<Link href="#" className="nav-link group">
|
||||
<div className="flex items-center">
|
||||
<IconMenuComponents className="shrink-0 group-hover:!text-primary" />
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-[#506690] dark:group-hover:text-white-dark">Dashboard</span>
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-white dark:group-hover:text-white dark:active:text-white">Dashboard</span>
|
||||
</div>
|
||||
</Link>
|
||||
</li>
|
||||
@ -100,7 +100,7 @@ const Sidebar = () => {
|
||||
<Link href="#" className="nav-link group">
|
||||
<div className="flex items-center">
|
||||
<IconMenuComponents className="shrink-0 group-hover:!text-primary" />
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-[#506690] dark:group-hover:text-white-dark">Sites</span>
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-white dark:group-hover:text-white dark:active:text-white">Sites</span>
|
||||
</div>
|
||||
</Link>
|
||||
</li>
|
||||
@ -108,7 +108,7 @@ const Sidebar = () => {
|
||||
<button type="button" className={`nav-link group w-full`} onClick={() => toggleMenu('setting')}>
|
||||
<div className="flex items-center">
|
||||
<IconMenuComponents className="shrink-0 group-hover:!text-primary" />
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-[#506690] dark:group-hover:text-white-dark">Setting</span>
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-white dark:group-hover:text-white dark:active:text-white">Setting</span>
|
||||
</div>
|
||||
|
||||
<div className={currentMenu !== 'setting' ? '-rotate-90 rtl:rotate-90' : ''}>
|
||||
@ -128,7 +128,7 @@ const Sidebar = () => {
|
||||
|
||||
|
||||
|
||||
<h2 className="-mx-4 mb-1 flex items-center bg-white-light/30 px-7 py-3 font-extrabold uppercase dark:bg-dark dark:bg-opacity-[0.08]">
|
||||
<h2 className="-mx-4 mb-1 flex items-center bg-white-light/30 px-7 py-3 font-extrabold uppercase dark:bg-dark dark:text-white dark:bg-opacity-[0.08] dark:active:text-white">
|
||||
<IconMinus className="hidden h-5 w-4 flex-none" />
|
||||
<span>Admin</span>
|
||||
</h2>
|
||||
@ -136,7 +136,7 @@ const Sidebar = () => {
|
||||
<Link href="/adminDashboard" className="nav-link group">
|
||||
<div className="flex items-center">
|
||||
<IconMenuComponents className="shrink-0 group-hover:!text-primary" />
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-[#506690] dark:group-hover:text-white-dark">Dashboard</span>
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-white dark:group-hover:text-white dark:active:text-white">Dashboard</span>
|
||||
</div>
|
||||
</Link>
|
||||
</li>
|
||||
@ -144,7 +144,7 @@ const Sidebar = () => {
|
||||
<Link href="/sites" className="nav-link group">
|
||||
<div className="flex items-center">
|
||||
<IconMenuComponents className="shrink-0 group-hover:!text-primary" />
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-[#506690] dark:group-hover:text-white-dark">Sites</span>
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-white dark:group-hover:text-white">Sites</span>
|
||||
</div>
|
||||
</Link>
|
||||
</li>
|
||||
@ -152,11 +152,11 @@ const Sidebar = () => {
|
||||
<Link href="#" className="nav-link group">
|
||||
<div className="flex items-center">
|
||||
<IconMenuComponents className="shrink-0 group-hover:!text-primary" />
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-[#506690] dark:group-hover:text-white-dark">Devices</span>
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-white dark:group-hover:text-white">Devices</span>
|
||||
</div>
|
||||
</Link>
|
||||
</li>
|
||||
<h2 className="-mx-4 mb-1 flex items-center px-7 py-3 font-extrabold uppercase dark:bg-opacity-[0.08]">
|
||||
<h2 className="-mx-4 mb-1 flex items-center px-7 py-3 font-extrabold uppercase dark:bg-opacity-[0.08] dark:group-hover:text-white dark:text-white">
|
||||
<IconMinus className="hidden h-5 w-4 flex-none" />
|
||||
<span>Providers</span>
|
||||
</h2>
|
||||
@ -164,7 +164,7 @@ const Sidebar = () => {
|
||||
<Link href="#" className="nav-link group">
|
||||
<div className="flex items-center">
|
||||
<IconMenuComponents className="shrink-0 group-hover:!text-primary" />
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-[#506690] dark:group-hover:text-white-dark">Solis</span>
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-white dark:group-hover:text-white">Solis</span>
|
||||
</div>
|
||||
</Link>
|
||||
</li>
|
||||
@ -172,7 +172,7 @@ const Sidebar = () => {
|
||||
<Link href="#" className="nav-link group">
|
||||
<div className="flex items-center">
|
||||
<IconMenuComponents className="shrink-0 group-hover:!text-primary" />
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-[#506690] dark:group-hover:text-white-dark">Huawei</span>
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-white dark:group-hover:text-white">Huawei</span>
|
||||
</div>
|
||||
</Link>
|
||||
</li>
|
||||
@ -181,7 +181,7 @@ const Sidebar = () => {
|
||||
<button type="button" className={`${currentMenu === 'sungrow' ? 'active' : ''} nav-link group w-full`} onClick={() => toggleMenu('sungrow')}>
|
||||
<div className="flex items-center">
|
||||
<IconMenuComponents className="shrink-0 group-hover:!text-primary" />
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-[#506690] dark:group-hover:text-white-dark">Sungrow</span>
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-white dark:group-hover:text-white">Sungrow</span>
|
||||
</div>
|
||||
|
||||
<div className={currentMenu !== 'component' ? '-rotate-90 rtl:rotate-90' : ''}>
|
||||
@ -190,7 +190,7 @@ const Sidebar = () => {
|
||||
</button>
|
||||
|
||||
<AnimateHeight duration={300} height={currentMenu === 'sungrow' ? 'auto' : 0}>
|
||||
<ul className="sub-menu text-gray-500">
|
||||
<ul className="sub-menu text-gray-500 dark:text-white/90">
|
||||
<li>
|
||||
<Link href="/sungrow/plant">Plant</Link>
|
||||
</li>
|
||||
@ -208,7 +208,7 @@ const Sidebar = () => {
|
||||
<Link href="#" className="nav-link group">
|
||||
<div className="flex items-center">
|
||||
<IconMenuComponents className="shrink-0 group-hover:!text-primary" />
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-[#506690] dark:group-hover:text-white-dark">CSI</span>
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-white dark:group-hover:text-white">CSI</span>
|
||||
</div>
|
||||
</Link>
|
||||
</li>
|
||||
@ -217,7 +217,7 @@ const Sidebar = () => {
|
||||
<button type="button" className={`${currentMenu === 'chint' ? 'active' : ''} nav-link group w-full`} onClick={() => toggleMenu('chint')}>
|
||||
<div className="flex items-center">
|
||||
<IconMenuComponents className="shrink-0 group-hover:!text-primary" />
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-[#506690] dark:group-hover:text-white-dark">Chint</span>
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-white dark:group-hover:text-white">Chint</span>
|
||||
</div>
|
||||
|
||||
<div className={currentMenu !== 'component' ? '-rotate-90 rtl:rotate-90' : ''}>
|
||||
@ -226,7 +226,7 @@ const Sidebar = () => {
|
||||
</button>
|
||||
|
||||
<AnimateHeight duration={300} height={currentMenu === 'chint' ? 'auto' : 0}>
|
||||
<ul className="sub-menu text-gray-500">
|
||||
<ul className="sub-menu text-gray-500 dark:text-white/90">
|
||||
<li>
|
||||
<Link href="/chint/sites">Sites</Link>
|
||||
</li>
|
||||
|
130
package-lock.json
generated
130
package-lock.json
generated
@ -36,6 +36,7 @@
|
||||
"react-animate-height": "^3.1.0",
|
||||
"react-apexcharts": "^1.7.0",
|
||||
"react-chartjs-2": "^5.3.0",
|
||||
"react-datepicker": "^8.4.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-hot-toast": "^2.5.2",
|
||||
"react-i18next": "^12.1.5",
|
||||
@ -334,6 +335,59 @@
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/core": {
|
||||
"version": "1.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz",
|
||||
"integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@floating-ui/utils": "^0.2.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/dom": {
|
||||
"version": "1.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.3.tgz",
|
||||
"integrity": "sha512-uZA413QEpNuhtb3/iIKoYMSK07keHPYeXF02Zhd6e213j+d1NamLix/mCLxBUDW/Gx52sPH2m+chlUsyaBs/Ag==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@floating-ui/core": "^1.7.3",
|
||||
"@floating-ui/utils": "^0.2.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/react": {
|
||||
"version": "0.27.15",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.27.15.tgz",
|
||||
"integrity": "sha512-0LGxhBi3BB1DwuSNQAmuaSuertFzNAerlMdPbotjTVnvPtdOs7CkrHLaev5NIXemhzDXNC0tFzuseut7cWA5mw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@floating-ui/react-dom": "^2.1.5",
|
||||
"@floating-ui/utils": "^0.2.10",
|
||||
"tabbable": "^6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=17.0.0",
|
||||
"react-dom": ">=17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/react-dom": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.5.tgz",
|
||||
"integrity": "sha512-HDO/1/1oH9fjj4eLgegrlH3dklZpHtUYYFiVwMUwfGvk9jWDRWqkklA2/NFScknrcNSspbV868WjXORvreDX+Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@floating-ui/dom": "^1.7.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/utils": {
|
||||
"version": "0.2.10",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz",
|
||||
"integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@headlessui/react": {
|
||||
"version": "1.7.8",
|
||||
"resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.8.tgz",
|
||||
@ -5005,6 +5059,21 @@
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-datepicker": {
|
||||
"version": "8.4.0",
|
||||
"resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-8.4.0.tgz",
|
||||
"integrity": "sha512-6nPDnj8vektWCIOy9ArS3avus9Ndsyz5XgFCJ7nBxXASSpBdSL6lG9jzNNmViPOAOPh6T5oJyGaXuMirBLECag==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@floating-ui/react": "^0.27.3",
|
||||
"clsx": "^2.1.1",
|
||||
"date-fns": "^4.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc",
|
||||
"react-dom": "^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
|
||||
@ -5750,6 +5819,12 @@
|
||||
"url": "https://opencollective.com/unts"
|
||||
}
|
||||
},
|
||||
"node_modules/tabbable": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
|
||||
"integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tailwindcss": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz",
|
||||
@ -6535,6 +6610,46 @@
|
||||
"strip-json-comments": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"@floating-ui/core": {
|
||||
"version": "1.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz",
|
||||
"integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==",
|
||||
"requires": {
|
||||
"@floating-ui/utils": "^0.2.10"
|
||||
}
|
||||
},
|
||||
"@floating-ui/dom": {
|
||||
"version": "1.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.3.tgz",
|
||||
"integrity": "sha512-uZA413QEpNuhtb3/iIKoYMSK07keHPYeXF02Zhd6e213j+d1NamLix/mCLxBUDW/Gx52sPH2m+chlUsyaBs/Ag==",
|
||||
"requires": {
|
||||
"@floating-ui/core": "^1.7.3",
|
||||
"@floating-ui/utils": "^0.2.10"
|
||||
}
|
||||
},
|
||||
"@floating-ui/react": {
|
||||
"version": "0.27.15",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.27.15.tgz",
|
||||
"integrity": "sha512-0LGxhBi3BB1DwuSNQAmuaSuertFzNAerlMdPbotjTVnvPtdOs7CkrHLaev5NIXemhzDXNC0tFzuseut7cWA5mw==",
|
||||
"requires": {
|
||||
"@floating-ui/react-dom": "^2.1.5",
|
||||
"@floating-ui/utils": "^0.2.10",
|
||||
"tabbable": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@floating-ui/react-dom": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.5.tgz",
|
||||
"integrity": "sha512-HDO/1/1oH9fjj4eLgegrlH3dklZpHtUYYFiVwMUwfGvk9jWDRWqkklA2/NFScknrcNSspbV868WjXORvreDX+Q==",
|
||||
"requires": {
|
||||
"@floating-ui/dom": "^1.7.3"
|
||||
}
|
||||
},
|
||||
"@floating-ui/utils": {
|
||||
"version": "0.2.10",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz",
|
||||
"integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="
|
||||
},
|
||||
"@headlessui/react": {
|
||||
"version": "1.7.8",
|
||||
"resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.8.tgz",
|
||||
@ -9765,6 +9880,16 @@
|
||||
"integrity": "sha512-UfZZFnDsERI3c3CZGxzvNJd02SHjaSJ8kgW1djn65H1KK8rehwTjyrRKOG3VTMG8wtHZ5rgAO5oTHtHi9GCCmw==",
|
||||
"requires": {}
|
||||
},
|
||||
"react-datepicker": {
|
||||
"version": "8.4.0",
|
||||
"resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-8.4.0.tgz",
|
||||
"integrity": "sha512-6nPDnj8vektWCIOy9ArS3avus9Ndsyz5XgFCJ7nBxXASSpBdSL6lG9jzNNmViPOAOPh6T5oJyGaXuMirBLECag==",
|
||||
"requires": {
|
||||
"@floating-ui/react": "^0.27.3",
|
||||
"clsx": "^2.1.1",
|
||||
"date-fns": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"react-dom": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
|
||||
@ -10260,6 +10385,11 @@
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"tabbable": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
|
||||
"integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="
|
||||
},
|
||||
"tailwindcss": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz",
|
||||
|
@ -37,6 +37,7 @@
|
||||
"react-animate-height": "^3.1.0",
|
||||
"react-apexcharts": "^1.7.0",
|
||||
"react-chartjs-2": "^5.3.0",
|
||||
"react-datepicker": "^8.4.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-hot-toast": "^2.5.2",
|
||||
"react-i18next": "^12.1.5",
|
||||
|
@ -51,12 +51,12 @@
|
||||
}
|
||||
.sidebar .nav-item > button.active,
|
||||
.sidebar .nav-item > a.active {
|
||||
@apply bg-[#000]/[0.08] text-black dark:bg-[#181f32] dark:text-white-dark;
|
||||
@apply bg-[#000]/[0.08] text-black dark:bg-[#181f32] dark:text-white;
|
||||
}
|
||||
|
||||
.sidebar .nav-item > button.active > div > span,
|
||||
.sidebar .nav-item > a.active > div > span {
|
||||
@apply dark:!text-white-dark;
|
||||
@apply dark:!text-white;
|
||||
}
|
||||
|
||||
.sidebar ul.sub-menu li button,
|
||||
|
Loading…
x
Reference in New Issue
Block a user