mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-24 15:38:18 +02:00
Display promotional content alongside orders and deliveries on the calendar
Fetch and display publicity information on the calendar view, filtering based on selected store and user groups. Replit-Commit-Author: Agent Replit-Commit-Session-Id: b163d4c0-de5e-4f4e-a9c0-aed4c7049718 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/b163d4c0-de5e-4f4e-a9c0-aed4c7049718/ByygiiM
This commit is contained in:
1 parent
09036d0049
commit
745ddc6805
2 files changed
+114
-2
No files matched your search
@@ -11,6 +11,9 @@ interface CalendarGridProps {
|
|||||||
currentDate: Date;
|
currentDate: Date;
|
||||||
orders: OrderWithRelations[];
|
orders: OrderWithRelations[];
|
||||||
deliveries: DeliveryWithRelations[];
|
deliveries: DeliveryWithRelations[];
|
||||||
|
publicities: any[];
|
||||||
|
selectedStoreId: number | null;
|
||||||
|
userGroups: any[];
|
||||||
onDateClick: (date: Date) => void;
|
onDateClick: (date: Date) => void;
|
||||||
onItemClick: (item: any, type: 'order' | 'delivery') => void;
|
onItemClick: (item: any, type: 'order' | 'delivery') => void;
|
||||||
}
|
}
|
||||||
@@ -162,12 +165,49 @@ export default function CalendarGrid({
|
|||||||
currentDate,
|
currentDate,
|
||||||
orders,
|
orders,
|
||||||
deliveries,
|
deliveries,
|
||||||
|
publicities,
|
||||||
|
selectedStoreId,
|
||||||
|
userGroups,
|
||||||
onDateClick,
|
onDateClick,
|
||||||
onItemClick,
|
onItemClick,
|
||||||
}: CalendarGridProps) {
|
}: CalendarGridProps) {
|
||||||
const monthStart = startOfMonth(currentDate);
|
const monthStart = startOfMonth(currentDate);
|
||||||
const monthEnd = endOfMonth(currentDate);
|
const monthEnd = endOfMonth(currentDate);
|
||||||
|
|
||||||
|
// Helper function to filter publicities based on user's assigned stores
|
||||||
|
const getPublicitiesForDate = (date: Date) => {
|
||||||
|
const dateStr = format(date, 'yyyy-MM-dd');
|
||||||
|
|
||||||
|
return publicities.filter(pub => {
|
||||||
|
// Check if the date is within the publicity period
|
||||||
|
const pubStart = pub.startDate;
|
||||||
|
const pubEnd = pub.endDate;
|
||||||
|
|
||||||
|
if (dateStr < pubStart || dateStr > pubEnd) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no store is selected and user has no assigned groups, show all publicities
|
||||||
|
if (!selectedStoreId && (!userGroups || userGroups.length === 0)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a specific store is selected, check if that store participates
|
||||||
|
if (selectedStoreId) {
|
||||||
|
return pub.participatingGroups?.some((pg: any) => pg.groupId === selectedStoreId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no specific store selected but user has assigned stores,
|
||||||
|
// show publicities where any of user's stores participate
|
||||||
|
if (userGroups && userGroups.length > 0) {
|
||||||
|
const userGroupIds = userGroups.map((ug: any) => ug.groupId);
|
||||||
|
return pub.participatingGroups?.some((pg: any) => userGroupIds.includes(pg.groupId));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Get all days in the month
|
// Get all days in the month
|
||||||
const monthDays = eachDayOfInterval({
|
const monthDays = eachDayOfInterval({
|
||||||
start: monthStart,
|
start: monthStart,
|
||||||
@@ -280,6 +320,7 @@ export default function CalendarGrid({
|
|||||||
const isCurrentMonth = isSameMonth(date, currentDate);
|
const isCurrentMonth = isSameMonth(date, currentDate);
|
||||||
const isTodayDate = isToday(date);
|
const isTodayDate = isToday(date);
|
||||||
const { orders: dayOrders, deliveries: dayDeliveries } = getItemsForDate(date);
|
const { orders: dayOrders, deliveries: dayDeliveries } = getItemsForDate(date);
|
||||||
|
const dayPublicities = getPublicitiesForDate(date);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -310,8 +351,28 @@ export default function CalendarGrid({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Publicities in top-right corner */}
|
||||||
|
{dayPublicities.length > 0 && (
|
||||||
|
<div className="absolute top-1 right-1 flex flex-col items-end gap-1">
|
||||||
|
{dayPublicities.slice(0, 3).map((pub, idx) => (
|
||||||
|
<div
|
||||||
|
key={`${pub.id}-${idx}`}
|
||||||
|
className="bg-purple-100 text-purple-800 text-xs px-1.5 py-0.5 rounded-sm border border-purple-200 font-medium shadow-sm cursor-help"
|
||||||
|
title={`Pub ${pub.pubNumber}: ${pub.designation}${pub.participatingGroups ? ` - Magasins: ${pub.participatingGroups.map((pg: any) => pg.group?.name).join(', ')}` : ''}`}
|
||||||
|
>
|
||||||
|
{pub.pubNumber}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
{dayPublicities.length > 3 && (
|
||||||
|
<div className="bg-purple-200 text-purple-700 text-xs px-1.5 py-0.5 rounded-sm border border-purple-300 font-medium">
|
||||||
|
+{dayPublicities.length - 3}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Quick Create Button */}
|
{/* Quick Create Button */}
|
||||||
{isCurrentMonth && (
|
{isCurrentMonth && dayPublicities.length === 0 && (
|
||||||
<div className="absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity">
|
<div className="absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity">
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -325,6 +386,22 @@ export default function CalendarGrid({
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Quick Create Button when publicities are present */}
|
||||||
|
{isCurrentMonth && dayPublicities.length > 0 && (
|
||||||
|
<div className="absolute bottom-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity">
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
className="w-6 h-6 bg-accent text-white rounded-full p-0 hover:bg-orange-600"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
onDateClick(date);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Plus className="w-3 h-3" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -105,6 +105,38 @@ export default function Calendar() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Fetch publicities for the current year
|
||||||
|
const { data: publicities = [], isLoading: loadingPublicities } = useQuery({
|
||||||
|
queryKey: ['/api/publicities', currentDate.getFullYear(), selectedStoreId],
|
||||||
|
queryFn: async () => {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
params.append('year', currentDate.getFullYear().toString());
|
||||||
|
if (selectedStoreId && user?.role === 'admin') {
|
||||||
|
params.append('storeId', selectedStoreId.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = `/api/publicities?${params.toString()}`;
|
||||||
|
console.log('📅 Calendar fetching publicities:', {
|
||||||
|
url,
|
||||||
|
selectedStoreId,
|
||||||
|
userRole: user?.role,
|
||||||
|
year: currentDate.getFullYear()
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await fetch(url, {
|
||||||
|
credentials: 'include'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to fetch publicities');
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
console.log('📅 Calendar publicities received:', Array.isArray(data) ? data.length : 'NOT_ARRAY', 'items');
|
||||||
|
return Array.isArray(data) ? data : [];
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const navigateMonth = (direction: 'prev' | 'next') => {
|
const navigateMonth = (direction: 'prev' | 'next') => {
|
||||||
const newDate = new Date(currentDate);
|
const newDate = new Date(currentDate);
|
||||||
if (direction === 'prev') {
|
if (direction === 'prev') {
|
||||||
@@ -143,7 +175,7 @@ export default function Calendar() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const isLoading = loadingOrders || loadingDeliveries;
|
const isLoading = loadingOrders || loadingDeliveries || loadingPublicities;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex-1 flex flex-col overflow-hidden">
|
<div className="flex-1 flex flex-col overflow-hidden">
|
||||||
@@ -226,6 +258,9 @@ export default function Calendar() {
|
|||||||
currentDate={currentDate}
|
currentDate={currentDate}
|
||||||
orders={orders}
|
orders={orders}
|
||||||
deliveries={deliveries}
|
deliveries={deliveries}
|
||||||
|
publicities={publicities}
|
||||||
|
selectedStoreId={selectedStoreId}
|
||||||
|
userGroups={user?.userGroups || []}
|
||||||
onDateClick={handleDateClick}
|
onDateClick={handleDateClick}
|
||||||
onItemClick={handleItemClick}
|
onItemClick={handleItemClick}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in new issue
Block a user