From 217907db5cee616624a2688b7485ee25bcb410c0 Mon Sep 17 00:00:00 2001 From: Sudhanshu Vora Date: Tue, 1 Oct 2024 13:10:13 +0200 Subject: [PATCH] Add create new meeting page --- frontend/package-lock.json | 208 ++++++++++++++++++ frontend/package.json | 3 + .../MeetingsDrawer/MeetingsDrawer.tsx | 2 +- frontend/src/container/PrepNow/PrepNow.tsx | 191 +++++++++++++++- frontend/src/index.tsx | 2 +- 5 files changed, 395 insertions(+), 11 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index b8dfc9e..31c75f1 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -12,7 +12,9 @@ "@emotion/styled": "^11.13.0", "@mui/base": "^5.0.0-beta.58", "@mui/icons-material": "^6.1.1", + "@mui/lab": "^6.0.0-beta.10", "@mui/material": "^6.1.1", + "@mui/x-date-pickers": "^7.18.0", "@tanstack/react-query": "^5.56.2", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", @@ -21,6 +23,7 @@ "@types/node": "^22.7.4", "@types/react": "^18.3.10", "@types/react-dom": "^18.3.0", + "date-fns": "^4.1.0", "react": "^18.3.1", "react-beautiful-dnd": "^13.1.1", "react-dom": "^18.3.1", @@ -3742,6 +3745,50 @@ } } }, + "node_modules/@mui/lab": { + "version": "6.0.0-beta.10", + "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-6.0.0-beta.10.tgz", + "integrity": "sha512-eqCBz5SZS8Un9To3UcjH01AxkOOgvme/g0ZstFC8Nz1Kg5/EJMA0ByhKS5AvUMzUKrv0FXMdbuPqbBvF3bVrXg==", + "dependencies": { + "@babel/runtime": "^7.25.6", + "@mui/base": "5.0.0-beta.58", + "@mui/system": "^6.1.1", + "@mui/types": "^7.2.17", + "@mui/utils": "^6.1.1", + "clsx": "^2.1.1", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@mui/material": "^6.1.1", + "@mui/material-pigment-css": "^6.1.1", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@mui/material-pigment-css": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, "node_modules/@mui/material": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.1.1.tgz", @@ -3939,6 +3986,158 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" }, + "node_modules/@mui/x-date-pickers": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.18.0.tgz", + "integrity": "sha512-12tXIoMj9vpS8fS/bS3kWPCoVrH38vNGCxgplI0vOnUrN9rJuYJz3agLPJe1S0xciTw+9W8ZSe3soaW+owoz1Q==", + "dependencies": { + "@babel/runtime": "^7.25.6", + "@mui/utils": "^5.16.6", + "@mui/x-internals": "7.18.0", + "@types/react-transition-group": "^4.4.11", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14 || ^6.0.0", + "@mui/system": "^5.15.14 || ^6.0.0", + "date-fns": "^2.25.0 || ^3.2.0 || ^4.0.0", + "date-fns-jalali": "^2.13.0-0 || ^3.2.0-0", + "dayjs": "^1.10.7", + "luxon": "^3.0.2", + "moment": "^2.29.4", + "moment-hijri": "^2.1.2", + "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "date-fns": { + "optional": true + }, + "date-fns-jalali": { + "optional": true + }, + "dayjs": { + "optional": true + }, + "luxon": { + "optional": true + }, + "moment": { + "optional": true + }, + "moment-hijri": { + "optional": true + }, + "moment-jalaali": { + "optional": true + } + } + }, + "node_modules/@mui/x-date-pickers/node_modules/@mui/utils": { + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.6.tgz", + "integrity": "sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/types": "^7.2.15", + "@types/prop-types": "^15.7.12", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^18.3.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/x-date-pickers/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + }, + "node_modules/@mui/x-internals": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.18.0.tgz", + "integrity": "sha512-lzCHOWIR0cAIY1bGrWSprYerahbnH5C31ql/2OWCEjcngL2NAV1M6oKI2Vp4HheqzJ822c60UyWyapvyjSzY/A==", + "dependencies": { + "@babel/runtime": "^7.25.6", + "@mui/utils": "^5.16.6" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0" + } + }, + "node_modules/@mui/x-internals/node_modules/@mui/utils": { + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.6.tgz", + "integrity": "sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/types": "^7.2.15", + "@types/prop-types": "^15.7.12", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^18.3.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/x-internals/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", @@ -7936,6 +8135,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/date-fns": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz", + "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debug": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", diff --git a/frontend/package.json b/frontend/package.json index f5086ad..106a833 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -7,7 +7,9 @@ "@emotion/styled": "^11.13.0", "@mui/base": "^5.0.0-beta.58", "@mui/icons-material": "^6.1.1", + "@mui/lab": "^6.0.0-beta.10", "@mui/material": "^6.1.1", + "@mui/x-date-pickers": "^7.18.0", "@tanstack/react-query": "^5.56.2", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", @@ -16,6 +18,7 @@ "@types/node": "^22.7.4", "@types/react": "^18.3.10", "@types/react-dom": "^18.3.0", + "date-fns": "^4.1.0", "react": "^18.3.1", "react-beautiful-dnd": "^13.1.1", "react-dom": "^18.3.1", diff --git a/frontend/src/components/MeetingsDrawer/MeetingsDrawer.tsx b/frontend/src/components/MeetingsDrawer/MeetingsDrawer.tsx index fe3d3c0..323de93 100644 --- a/frontend/src/components/MeetingsDrawer/MeetingsDrawer.tsx +++ b/frontend/src/components/MeetingsDrawer/MeetingsDrawer.tsx @@ -126,7 +126,7 @@ export const MeetingsDrawer = ({
-
diff --git a/frontend/src/container/PrepNow/PrepNow.tsx b/frontend/src/container/PrepNow/PrepNow.tsx index aecfce0..7b4b58b 100644 --- a/frontend/src/container/PrepNow/PrepNow.tsx +++ b/frontend/src/container/PrepNow/PrepNow.tsx @@ -1,9 +1,182 @@ -import React from "react" - -export const PrepNow = () => { - return ( -
-

Create New meetings

-
- ) -} \ No newline at end of file +import React, { useState } from "react"; +import { + Box, + TextField, + Button, + Typography, + FormControl, + InputLabel, + Select, + MenuItem, + Container, + Snackbar, + Alert, + SelectChangeEvent, +} from "@mui/material"; +import { DateTimePicker } from "@mui/x-date-pickers/DateTimePicker"; +import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; +import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFnsV3"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; + +interface MeetingFormData { + title: string; + description: string; + date: Date | null; + meeting_type: string; +} + +const createMeeting = async (meetingData: MeetingFormData): Promise => { + const response = await fetch(`https://codefusion.lholz.de/meetings/`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(meetingData), + }); + + if (!response.ok) { + throw new Error('Failed to create meeting'); + } + + return response.json(); +}; + +export const PrepNow: React.FC = () => { + const [formData, setFormData] = useState({ + title: "", + description: "", + date: null, + meeting_type: "", + }); + const [snackbar, setSnackbar] = useState<{ open: boolean; message: string; severity: 'success' | 'error' }>({ + open: false, + message: '', + severity: 'success', + }); + + const queryClient = useQueryClient(); + + const mutation = useMutation({ + mutationFn: createMeeting, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ['meetings'] }); + setSnackbar({ open: true, message: 'Meeting created successfully!', severity: 'success' }); + resetForm(); + }, + onError: (error) => { + console.error('Error creating meeting:', error); + setSnackbar({ open: true, message: 'Failed to create meeting. Please try again.', severity: 'error' }); + }, + }); + + const handleChange = (event: React.ChangeEvent) => { + const { name, value } = event.target; + setFormData((prevData) => ({ + ...prevData, + [name]: value, + })); + }; + + const handleDateChange = (newDate: Date | null) => { + setFormData((prevData) => ({ + ...prevData, + date: newDate, + })); + }; + + const handleSubmit = (event: React.FormEvent) => { + event.preventDefault(); + const meetingData: MeetingFormData = { + ...formData, + date: formData.date ? formData.date : null, + }; + mutation.mutate(meetingData); + }; + + const resetForm = () => { + setFormData({ + title: "", + description: "", + date: null, + meeting_type: "", + }); + }; + + const handleCloseSnackbar = () => { + setSnackbar({ ...snackbar, open: false }); + }; + + return ( + + + + Create New Meeting + +
+ + + + + + + Meeting Type + + + + +
+ + + {snackbar.message} + + +
+ ); +}; \ No newline at end of file diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 80d6326..fec7392 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -41,7 +41,7 @@ const router = createHashRouter([ ], }, { - path: '/prep-now', + path: '/create-meeting', element: , } ],