From 1f2cb7d5ac1155a35669c1ac85cf3eea63a9f35b Mon Sep 17 00:00:00 2001 From: Meng <43998638+Meng-V@users.noreply.github.com> Date: Tue, 23 Sep 2025 11:40:41 -0400 Subject: [PATCH] added basic broadcast functions. Need more adjustment --- .../admin/superguide/page.tsx | 77 +++- app/api/admin/broadcast/route.ts | 266 ++++++++++++ app/api/admin/form-session/route.ts | 183 ++++++++ components/BroadcastFormModal.tsx | 406 ++++++++++++++++++ components/FormSessionController.tsx | 137 ++++++ docs/FORM_INTEGRATION_EXAMPLE.md | 196 +++++++++ hooks/useFormSession.ts | 171 ++++++++ lib/email.ts | 12 +- 8 files changed, 1438 insertions(+), 10 deletions(-) create mode 100644 app/api/admin/broadcast/route.ts create mode 100644 app/api/admin/form-session/route.ts create mode 100644 components/BroadcastFormModal.tsx create mode 100644 components/FormSessionController.tsx create mode 100644 docs/FORM_INTEGRATION_EXAMPLE.md create mode 100644 hooks/useFormSession.ts diff --git a/app/(authentication)/admin/superguide/page.tsx b/app/(authentication)/admin/superguide/page.tsx index 2e7a9389..cc12f9ab 100644 --- a/app/(authentication)/admin/superguide/page.tsx +++ b/app/(authentication)/admin/superguide/page.tsx @@ -2,8 +2,9 @@ import { Container } from '@/components/Container' import { Button } from '@/components/Button' -import React from 'react' +import React, { useState, useEffect } from 'react' import Link from 'next/link' +import BroadcastFormModal from '@/components/BroadcastFormModal' const openNewYearForm = async () => { // Show loading message @@ -108,13 +109,71 @@ const openNewYearForm = async () => { const adminHelp = () => { const currentYear = new Date().getFullYear(); + const [showBroadcastModal, setShowBroadcastModal] = useState(false); + const [userInfo, setUserInfo] = useState<{userId: number, userRoles: string[]} | null>(null); + + // Get user info from cookies on component mount + useEffect(() => { + const getUserInfo = () => { + // Get user info from cookies (this should match your authentication system) + const userIdCookie = document.cookie + .split('; ') + .find(row => row.startsWith('userId=')) + ?.split('=')[1]; + + const userRolesCookie = document.cookie + .split('; ') + .find(row => row.startsWith('userRoles=')) + ?.split('=')[1]; + + if (userIdCookie && userRolesCookie) { + try { + const roles = JSON.parse(decodeURIComponent(userRolesCookie)); + setUserInfo({ + userId: parseInt(userIdCookie), + userRoles: roles + }); + } catch (error) { + console.error('Failed to parse user info from cookies:', error); + } + } + }; + + getUserInfo(); + }, []); + return ( <>
+ Use "Open Forms & Broadcast" to create a new form session, open all library forms for editing (62-day period), + and automatically send notification emails to all CEAL members. +
+Dear CEAL Member,
+ +The annual data collection forms are now open for academic year ${year}.
+ +You can now access and submit your library's data through the CEAL Database system. Please ensure all forms are completed before the closing date.
+ +If you have any questions or need assistance, please contact the CEAL Database administrators.
+ +Best regards,
+ CEAL Database Administration
+ You can unsubscribe from these notifications here: {{{RESEND_UNSUBSCRIBE_URL}}} +
+Dear CEAL Member,
+ +The annual data collection forms are now open for academic year ${year}.
+ +You can now access and submit your library's data through the CEAL Database system. Please ensure all forms are completed before the closing date.
+ +If you have any questions or need assistance, please contact the CEAL Database administrators.
+ +Best regards,
+ CEAL Database Administration
+ You can unsubscribe from these notifications here: {{{RESEND_UNSUBSCRIBE_URL}}} +
+Super admin privileges required to access this feature.
+ +{error}
++ This email will be sent to all members in the broadcast list. +
++ Form session for {year} has been created and notification emails have been sent to all CEAL members. +
+Please sign in to access forms.
++ Forms are not currently open for editing. Please contact the CEAL Database Administrator for assistance. +
++ You can only edit forms for libraries you are associated with. + If you believe this is an error, please contact your administrator. +
++ You can now edit and submit this library's forms. Please ensure all data is accurate before submitting. +
+( + WrappedComponent: React.ComponentType
,
+ libraryId: number
+) {
+ const WithFormSessionControl = (props: P) => {
+ return (
+
+ Forms are not currently open for editing. Please contact the CEAL Database Administrator for assistance. +
+