From 3feb2ff20afc27dbcf61b6fb25af9993cb3c78cf Mon Sep 17 00:00:00 2001 From: Ravi Gulhane <> Date: Wed, 22 Jul 2026 09:39:01 +0530 Subject: [PATCH] 22 july --- dist/index.html | 4 +- src/app/components/AppShell.tsx | 6 + src/app/components/MainContent.tsx | 12 + src/app/components/NavBar.tsx | 2 +- src/app/components/Sidebar.tsx | 167 ++++++- src/app/components/TopBar.tsx | 287 ++++++++---- .../components/activities/ActivitiesPage.tsx | 62 ++- .../activities/ActivityDetailPage.tsx | 82 +++- .../activities/ActivityEventSettings.tsx | 16 +- .../activities/activityRatingDisplay.ts | 22 + .../components/agenda/AgendaSessionPanel.tsx | 168 ++++++- .../components/attendance/AttendancePage.tsx | 103 ++-- .../dashboard/EventEmailCampaignsPanel.tsx | 279 +++++++++++ src/app/components/dashboard/EventHeader.tsx | 30 +- .../components/dashboard/EventHomeModules.tsx | 162 ++++++- src/app/components/global/GlobalStubPage.tsx | 174 +++++-- src/app/components/global/SettingsPage.tsx | 31 +- .../messaging/MessagingEmailPage.tsx | 228 ++++++--- .../components/messaging/mergePlaceholders.ts | 1 + .../ManageStaticMicrositePanel.tsx | 40 +- .../microsite-v2/MicrositeConfigForm.tsx | 224 +++++++-- .../microsite-v2/eventMicrositeAutofill.ts | 275 +++++++++++ .../components/microsite-v2/scheduleSync.ts | 11 + .../panels/BadgeDesignerPreview.tsx | 249 ++++++++-- .../components/panels/BadgeFieldInspector.tsx | 7 +- .../components/panels/CreateBadgePanel.tsx | 137 ++++-- .../panels/CreateCustomListPanel.tsx | 1 + .../panels/CreateEmailCampaignPanel.tsx | 443 ++++++++++++++++++ .../components/panels/CreateEmailerPanel.tsx | 30 +- .../components/panels/CreateEventPanel.tsx | 17 +- .../panels/CreateEventSessionPanel.tsx | 19 +- src/app/components/panels/CreateFormPanel.tsx | 357 +++++++++++++- .../panels/FormSubmissionsPanel.tsx | 31 ++ .../panels/WebsiteThemeSettingsPanel.tsx | 227 +++++++++ .../components/panels/badgeBatchFormState.ts | 14 +- src/app/components/panels/badgeLayout.ts | 76 ++- .../components/panels/createEventPayload.ts | 8 +- src/app/components/panels/eventFormFields.tsx | 9 +- src/app/components/panels/eventFormModel.ts | 15 +- .../participants/ParticipantBulkActionBar.tsx | 16 +- .../participants/ParticipantBulkDialogs.tsx | 21 +- .../participants/ParticipantsPage.tsx | 292 +++++++----- .../participants/useParticipantBulkActions.ts | 7 +- .../components/search/SearchResultsPage.tsx | 45 +- src/app/components/search/searchIndex.tsx | 71 ++- .../components/ui/FlatpickrDatetimeInput.tsx | 100 ++++ src/app/contexts/PermissionContext.tsx | 20 +- src/app/utils/emailerPreview.ts | 109 +++++ src/app/views/SuperAdminClientsPage.tsx | 90 ++-- src/config/colors.ts | 1 + src/config/constants.ts | 2 +- src/services/api/badgeBatches.ts | 8 + src/services/api/events.ts | 5 +- src/services/api/index.ts | 3 +- src/services/api/participants.ts | 43 +- src/services/api/sessions.ts | 13 +- src/services/api/types.ts | 62 ++- src/views/PublicFormView.tsx | 9 +- tsconfig.json | 1 - 59 files changed, 4285 insertions(+), 659 deletions(-) create mode 100644 src/app/components/activities/activityRatingDisplay.ts create mode 100644 src/app/components/dashboard/EventEmailCampaignsPanel.tsx create mode 100644 src/app/components/microsite-v2/eventMicrositeAutofill.ts create mode 100644 src/app/components/panels/CreateEmailCampaignPanel.tsx create mode 100644 src/app/components/panels/WebsiteThemeSettingsPanel.tsx create mode 100644 src/app/utils/emailerPreview.ts diff --git a/dist/index.html b/dist/index.html index d5b558b3..be891495 100644 --- a/dist/index.html +++ b/dist/index.html @@ -12,8 +12,8 @@ rel="stylesheet" /> - - + +
diff --git a/src/app/components/AppShell.tsx b/src/app/components/AppShell.tsx index 4ebe71f9..76d59b41 100644 --- a/src/app/components/AppShell.tsx +++ b/src/app/components/AppShell.tsx @@ -38,6 +38,12 @@ export function AppShell() { } }, [selectedEventId, activeNav, setActiveNav]); + useEffect(() => { + if (activeNav === "dashboard" && selectedEventId) { + setSidebarCollapsed(true); + } + }, [activeNav, selectedEventId, setSidebarCollapsed]); + return (+ Add programme items for this session block — e.g. lectures, panel discussions, and speaker roles. +
+ {topics.length === 0 ? ( ++ No topics yet. Add one below. +
+ ) : null} + {topics.map((topic, idx) => ( +{error}
+ ) : null} + +Loading…
+ ) : campaigns.length === 0 ? ( ++ No email campaigns for this event yet. +
+{statsCampaign.name}
++ Status: {statsCampaign.status} +
++ Sent: {new Date(statsCampaign.sentAt).toLocaleString()} +
+ )} +No HTML saved for this template yet. Use Edit to build the emailer.
'; @@ -462,7 +469,7 @@ export function DesignPage({ subPage }: { subPage?: string }) {{t.name}
Portfolio
- {total} in your organization (Including people not yet assigned to an event) · Page {page} of {Math.max(1, Math.ceil(total / limit))} + {total} {showDeleted ? "deleted" : "active"} in your organization · Page {page} of {Math.max(1, Math.ceil(total / limit))}
- No participants found + {showDeleted ? "No deleted participants" : "No participants found"}
- {(search || activeTag) ? "Try adjusting your filters or import participants." : "No one in your organization yet. Import a CSV or add people from an event."} + {showDeleted + ? "Soft-deleted people will appear here so you can restore them." + : (search || activeTag) ? "Try adjusting your filters or import participants." : "No one in your organization yet. Import a CSV or add people from an event."}
{(search || activeTag) && ({p.name}
-{p.status}
+{p.status}
{err}
} {msg &&{msg}
}
+ Microsoft 365 / Outlook: host smtp.office365.com, port 587, SSL off.
+ Username = full mailbox email. Authenticated SMTP must be enabled for that user; with MFA use an App Password.
+ Save settings, then re-enter the password if login still fails.
+
+ Use 587 with STARTTLS (SSL off), or 465 with SSL/TLS on. Mixing these causes “wrong version number” errors. +
+ Loading… +
+ ) : ( ++ {error} +
+ ) : null} +Type a tag or select one below to apply to {selectedCount} selected participant(s).
+Type a tag or select one below to apply to {selectedCount} selected participant(s).
+{scopeHint}
setManualTagInput(e.target.value)} diff --git a/src/app/components/participants/ParticipantsPage.tsx b/src/app/components/participants/ParticipantsPage.tsx index a070a300..aceed977 100644 --- a/src/app/components/participants/ParticipantsPage.tsx +++ b/src/app/components/participants/ParticipantsPage.tsx @@ -2,11 +2,12 @@ import React, { useState, useRef, useEffect, useCallback } from "react"; import { useBreakpoint } from "../../hooks/useBreakpoint"; import { useAppNav } from "../../contexts/AppNavContext"; import { useAuth } from "../../contexts/AuthContext"; +import { usePermission } from "../../contexts/PermissionContext"; import { Search, Plus, Download, Upload, Eye, Pencil, Trash2, Check, X, Phone, Mail, Calendar, User, Filter, UserCheck, AlertCircle, List, LayoutGrid, ChevronDown, CheckCircle2, Clock, - Users, UserX, ChevronLeft, ChevronRight, QrCode, + Users, ChevronLeft, ChevronRight, QrCode, } from "lucide-react"; import { participantsApi } from "../../../services/api"; import type { Participant as ApiParticipant } from "../../../services/api/types"; @@ -42,7 +43,7 @@ interface ParticipantDisplay { function toDisplay(p: ApiParticipant): ParticipantDisplay { const name = [p.firstName, p.lastName].filter(Boolean).join(" ").trim() || "—"; const regDate = p.registrationDate ? new Date(p.registrationDate).toLocaleDateString("en-IN", { day: "numeric", month: "short", year: "numeric" }) : null; - const statusLabel = { pending: "Pending", confirmed: "Confirmed", checked_in: "Checked In", cancelled: "Cancelled" }[p.status] ?? p.status; + const statusLabel = { pending: "Pending", confirmed: "Confirmed", checked_in: "Checked In", cancelled: "Cancelled", rejected: "Rejected" }[p.status] ?? p.status; return { id: p._id, name, @@ -142,8 +143,18 @@ function CheckInBadge({ checked }: { checked: boolean }) { } function StatusDot({ status }: { status: string }) { - const color = status === "Cancelled" ? "var(--muted)" : status === "Checked In" ? "#15803d" : status === "Confirmed" ? "#2563eb" : "var(--card-foreground)"; - const dotColor = status === "Cancelled" ? "#9ca3af" : status === "Checked In" ? "#16a34a" : status === "Confirmed" ? "#2563eb" : "#94a3b8"; + const color = + status === "Rejected" ? "var(--destructive)" + : status === "Cancelled" ? "var(--muted)" + : status === "Checked In" ? "#15803d" + : status === "Confirmed" ? "#2563eb" + : "var(--card-foreground)"; + const dotColor = + status === "Rejected" ? "#dc2626" + : status === "Cancelled" ? "#9ca3af" + : status === "Checked In" ? "#16a34a" + : status === "Confirmed" ? "#2563eb" + : "#94a3b8"; return ( @@ -152,6 +163,20 @@ function StatusDot({ status }: { status: string }) { ); } +const iconBtnStyle: React.CSSProperties = { + width: "28px", + height: "28px", + display: "flex", + alignItems: "center", + justifyContent: "center", + padding: 0, + borderRadius: "var(--radius-button)", + background: "var(--card)", + border: "1px solid var(--border)", + color: "var(--card-foreground)", + cursor: "pointer", +}; + /* ─────────────── Filter Chip ─────────────── */ function FilterSelect({ label, value, options, onChange }: { label: string; value: string; options: string[]; onChange: (v: string) => void }) { @@ -184,16 +209,19 @@ interface RowProps { onView: () => void; onEdit: () => void; onDelete: () => void; - onToggleCheckIn: () => void; + onConfirm: () => void; + onReject: () => void; onQr: () => void; canEdit?: boolean; + canDelete?: boolean; selectable?: boolean; selected?: boolean; onToggleSelect?: () => void; } -function ParticipantRow({ p, onView, onEdit, onDelete, onToggleCheckIn, onQr, canEdit, selectable, selected, onToggleSelect }: RowProps) { +function ParticipantRow({ p, onView, onEdit, onDelete, onConfirm, onReject, onQr, canEdit, canDelete, selectable, selected, onToggleSelect }: RowProps) { const [hovered, setHovered] = useState(false); + const isPending = p.status === "Pending"; return ({stat.value}
-{stat.label}
- {stat.sub &&{stat.sub}
} -+ No events in this organisation yet. +
+ )}| + + |
{msg}
+ ) : null} ); diff --git a/tsconfig.json b/tsconfig.json index 4a8d9152..b09f355f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,7 +10,6 @@ "noEmit": true, "jsx": "react-jsx", "strict": true, - "baseUrl": ".", "paths": { "@/*": ["./src/*"] }