diff --git a/apps/vite-ssr/server.js b/apps/vite-ssr/server.js index e5af2f9156..7faf085e8d 100644 --- a/apps/vite-ssr/server.js +++ b/apps/vite-ssr/server.js @@ -5,8 +5,6 @@ import dns from 'dns'; const isTest = process.env.NODE_ENV === 'test' || !!process.env.VITE_TEST_BUILD; -// If DNS returns both ipv4 and ipv6 addresses, prefer ipv4 - export async function createServer( root = process.cwd(), isProd = process.env.NODE_ENV === 'production', @@ -16,12 +14,9 @@ export async function createServer( const app = express(); const prodIndexHtml = isProd - ? await fs.readFile('./dist/client/index.html', 'utf-8') + ? await fs.readFile('./event_scheduler/dist/client/index.html', 'utf-8') : ''; - /** - * @type {import('vite').ViteDevServer} - */ let vite; if (!isProd) { vite = await ( @@ -32,8 +27,6 @@ export async function createServer( server: { middlewareMode: true, watch: { - // During tests we edit the files too fast and sometimes chokidar - // misses change events, so enforce polling for consistency usePolling: true, interval: 100, }, @@ -43,14 +36,62 @@ export async function createServer( }, appType: 'custom', }); - // use vite's connect instance as middleware app.use(vite.middlewares); } else { const sirv = (await import('sirv')).default; app.use((await import('compression')).default()); - app.use('/', sirv('./dist/client', { extensions: [] })); + app.use('/', sirv('./event_scheduler/dist/client', { extensions: [] })); } + // Middleware to parse JSON requests + app.use(express.json()); + + // Event scheduling validation logic + app.post('/schedule-event', (req, res) => { + const { startDatetime, endDatetime, isAllDay, isRecurring } = req.body; + + if (!startDatetime) { + return res.status(400).json({ error: 'Start datetime is required.' }); + } + + const start = new Date(startDatetime); + let end = endDatetime ? new Date(endDatetime) : null; + + // Validate event times + if (end && end <= start) { + return res.status(400).json({ + error: 'End datetime must be after start datetime.', + }); + } + + // Handle all-day event logic + if (isAllDay) { + const startDate = new Date(start.toDateString()); + const endDate = new Date(start.toDateString()); + endDate.setHours(23, 59, 59); + end = endDate; + + return res.json({ + message: 'All-day event created.', + event: { start: startDate, end: endDate }, + }); + } + + // Handle recurring event logic + if (isRecurring && !end) { + return res.json({ + message: 'Recurring event created without end datetime.', + event: { start }, + }); + } + + // Return successful response + res.json({ + message: 'Event scheduled successfully.', + event: { start, end }, + }); + }); + app.use('*', async (req, res) => { try { const url = req.originalUrl; @@ -62,7 +103,6 @@ export async function createServer( return; } - // Extract the head from vite's index transformation hook let viteHead = !isProd ? await vite.transformIndexHtml( url, @@ -79,7 +119,7 @@ export async function createServer( if (!isProd) { return vite.ssrLoadModule('/src/entry-server.tsx'); } else { - return import('./dist/server/entry-server.js'); + return import('./event_scheduler/dist/server/entry-server.js'); } })(); diff --git a/event_scheduler/index.html b/event_scheduler/index.html new file mode 100644 index 0000000000..fa7cc60b82 --- /dev/null +++ b/event_scheduler/index.html @@ -0,0 +1,26 @@ + + + + + + Event Scheduler + + + +
+ + + + + + + + + + + + + +
+ + diff --git a/event_scheduler/script.js b/event_scheduler/script.js new file mode 100644 index 0000000000..63d070ee22 --- /dev/null +++ b/event_scheduler/script.js @@ -0,0 +1,46 @@ +document.getElementById("event-form").addEventListener("submit", function (event) { + event.preventDefault(); + + const startField = document.getElementById("start-datetime"); + const endField = document.getElementById("end-datetime"); + const allDayCheckbox = document.getElementById("all-day-checkbox"); + + const start = new Date(startField.value); + const end = new Date(endField.value); + + // Validate start and end times + if (!allDayCheckbox.checked && end <= start) { + alert("End datetime must be after start datetime."); + return; + } + + // Handle all-day event logic + if (allDayCheckbox.checked) { + const startDate = start.toISOString().slice(0, 10); + startField.value = `${startDate}T00:00`; + endField.value = `${startDate}T23:59`; + } + + // Send data to the backend + const eventData = { + startDatetime: startField.value, + endDatetime: endField.value, + isAllDay: allDayCheckbox.checked, + isRecurring: document.getElementById("is-recurring").checked, + }; + + fetch("/create-event", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(eventData), + }) + .then((response) => response.json()) + .then((data) => { + if (data.error) { + alert(data.error); + } else { + alert("Event saved successfully!"); + } + }) + .catch((error) => console.error("Error:", error)); +});