diff --git a/src/admin/calendar/CalendarPage.jsx b/src/admin/calendar/CalendarPage.jsx
index dd94cc0..8e03657 100644
--- a/src/admin/calendar/CalendarPage.jsx
+++ b/src/admin/calendar/CalendarPage.jsx
@@ -1,7 +1,8 @@
import { useState } from 'react';
-import { ChevronLeft, ChevronRight } from 'lucide-react';
+import { ChevronLeft, ChevronRight, Plus } from 'lucide-react';
import { useCalendar } from './useCalendar';
import { useIsMobile } from '../../hooks/useIsMobile';
+import OrderModal from '../orders/OrderModal';
const MONTH_NAMES = [
'Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь',
@@ -41,10 +42,11 @@ function isSameDay(a, b) {
a.getDate() === b.getDate();
}
-function OrderChip({ order }) {
+function OrderChip({ order, onClick }) {
const color = getStatusColor(order.status);
return (
{ e.stopPropagation(); onClick(order); }}
title={`${order.name} — ${order.status}`}
style={{
background: color + '1A',
@@ -58,6 +60,7 @@ function OrderChip({ order }) {
textOverflow: 'ellipsis',
maxWidth: '100%',
lineHeight: 1.4,
+ cursor: 'pointer',
}}
>
{order.name}
@@ -65,7 +68,7 @@ function OrderChip({ order }) {
);
}
-function DayCell({ date, orders, isCurrentMonth, isToday, isSelected, onSelect, isMobile }) {
+function DayCell({ date, orders, isCurrentMonth, isToday, isSelected, onSelect, onOrderClick, isMobile }) {
const dayOrders = orders.filter((o) => o.scheduled_at && isSameDay(new Date(o.scheduled_at), date));
const visible = dayOrders.slice(0, 2);
const extra = dayOrders.length - visible.length;
@@ -110,7 +113,7 @@ function DayCell({ date, orders, isCurrentMonth, isToday, isSelected, onSelect,
{!isMobile && visible.map((o) => (
-
+
))}
{isMobile && dayOrders.length > 0 && (
@@ -137,25 +140,23 @@ function DayCell({ date, orders, isCurrentMonth, isToday, isSelected, onSelect,
);
}
-function DayDetail({ date, orders }) {
+function DayDetail({ date, orders, onOrderClick, onAdd }) {
const dayOrders = orders.filter((o) => o.scheduled_at && isSameDay(new Date(o.scheduled_at), date));
- if (dayOrders.length === 0) {
- return (
-
- На этот день записей нет
-
- );
- }
-
return (
+ {dayOrders.length === 0 && (
+
+ На этот день записей нет
+
+ )}
{dayOrders.map((o) => {
const color = getStatusColor(o.status);
const time = new Date(o.scheduled_at).toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' });
return (
onOrderClick(o)}
className="glass-panel"
style={{
padding: '12px 16px',
@@ -164,7 +165,11 @@ function DayDetail({ date, orders }) {
alignItems: 'center',
justifyContent: 'space-between',
gap: '12px',
+ cursor: 'pointer',
+ transition: 'box-shadow 0.15s',
}}
+ onMouseEnter={(e) => e.currentTarget.style.boxShadow = '0 4px 12px rgba(0,0,0,0.1)'}
+ onMouseLeave={(e) => e.currentTarget.style.boxShadow = ''}
>
@@ -194,6 +199,17 @@ function DayDetail({ date, orders }) {
);
})}
+
);
}
@@ -203,8 +219,13 @@ const CalendarPage = () => {
const [year, setYear] = useState(today.getFullYear());
const [month, setMonth] = useState(today.getMonth());
const [selectedDate, setSelectedDate] = useState(today);
+ const [editOrder, setEditOrder] = useState(null);
+ const [createDate, setCreateDate] = useState(null);
const isMobile = useIsMobile();
- const { orders, loading } = useCalendar(year, month);
+ const { orders, loading, refetch } = useCalendar(year, month);
+
+ const handleModalClose = () => { setEditOrder(null); setCreateDate(null); };
+ const handleModalSaved = () => { handleModalClose(); refetch(); };
const prevMonth = () => {
if (month === 0) { setYear((y) => y - 1); setMonth(11); }
@@ -317,6 +338,7 @@ const CalendarPage = () => {
isToday={isSameDay(date, today)}
isSelected={isSameDay(date, selectedDate)}
onSelect={setSelectedDate}
+ onOrderClick={setEditOrder}
isMobile={isMobile}
/>
))}
@@ -333,8 +355,33 @@ const CalendarPage = () => {
}}>
{selectedDateLabel}
- {loading ? null :
}
+ {loading ? null : (
+
setCreateDate(selectedDate)}
+ />
+ )}
+
+ {editOrder && (
+
+ )}
+
+ {createDate && (
+
+ )}
);
};
diff --git a/src/admin/calendar/useCalendar.js b/src/admin/calendar/useCalendar.js
index dac9f48..5b5b9e1 100644
--- a/src/admin/calendar/useCalendar.js
+++ b/src/admin/calendar/useCalendar.js
@@ -1,11 +1,16 @@
-import { useState, useEffect } from 'react';
+import { useState, useEffect, useCallback } from 'react';
import { supabase } from '../../lib/supabase';
export function useCalendar(year, month) {
const [orders, setOrders] = useState([]);
const [loading, setLoading] = useState(true);
+ const [trigger, setTrigger] = useState(0);
+
+ const refetch = useCallback(() => setTrigger((t) => t + 1), []);
useEffect(() => {
+ let isMounted = true;
+ setLoading(true);
const from = new Date(year, month, 1).toISOString();
const to = new Date(year, month + 1, 0, 23, 59, 59).toISOString();
@@ -16,10 +21,11 @@ export function useCalendar(year, month) {
.lte('scheduled_at', to)
.order('scheduled_at', { ascending: true })
.then(({ data }) => {
- setOrders(data || []);
- setLoading(false);
+ if (isMounted) { setOrders(data || []); setLoading(false); }
});
- }, [year, month]);
- return { orders, loading };
+ return () => { isMounted = false; };
+ }, [year, month, trigger]);
+
+ return { orders, loading, refetch };
}