From 1c81efd4b6e14f49009dd81487ad130ab07146bd Mon Sep 17 00:00:00 2001 From: Riku Rauhala Date: Tue, 12 Nov 2024 10:16:09 +0200 Subject: [PATCH 1/4] [Feedback] Rewrite with Material UI components --- .../frontend/src/components/Routes/index.jsx | 2 +- .../components/material/PageTitle/index.tsx | 16 +++ .../material/StatusNotification/index.tsx | 34 +++++ .../frontend/src/pages/Feedback/index.tsx | 136 ++++++++++++++++++ 4 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 services/frontend/src/components/material/PageTitle/index.tsx create mode 100644 services/frontend/src/components/material/StatusNotification/index.tsx create mode 100644 services/frontend/src/pages/Feedback/index.tsx diff --git a/services/frontend/src/components/Routes/index.jsx b/services/frontend/src/components/Routes/index.jsx index 5d5aec6ca6..328cc7a78a 100644 --- a/services/frontend/src/components/Routes/index.jsx +++ b/services/frontend/src/components/Routes/index.jsx @@ -10,7 +10,6 @@ import { CustomPopulation } from '@/components/CustomPopulation' import { EvaluationOverview } from '@/components/EvaluationOverview' import { UniversityViewPage } from '@/components/EvaluationOverview/UniversityView' import { FacultyStatistics } from '@/components/FacultyStatistics' -import { Feedback } from '@/components/Feedback' import { FrontPage } from '@/components/Frontpage' import { LanguageCenterView } from '@/components/LanguageCenterView' import { PopulationStatistics } from '@/components/PopulationStatistics' @@ -22,6 +21,7 @@ import { Teachers } from '@/components/Teachers' import { Updater } from '@/components/Updater' import { Users } from '@/components/Users' import { languageCenterViewEnabled } from '@/conf' +import { Feedback } from '@/pages/Feedback' import { ProtectedRoute } from './ProtectedRoute' const routes = { diff --git a/services/frontend/src/components/material/PageTitle/index.tsx b/services/frontend/src/components/material/PageTitle/index.tsx new file mode 100644 index 0000000000..f15d785757 --- /dev/null +++ b/services/frontend/src/components/material/PageTitle/index.tsx @@ -0,0 +1,16 @@ +import { Box, Typography } from '@mui/material' + +/** + * A title text displayed at the top of the page. + * + * @param {string} title - The main title of the page. + */ +export const PageTitle = ({ title }: { title: string }) => { + return ( + + + {title} + + + ) +} diff --git a/services/frontend/src/components/material/StatusNotification/index.tsx b/services/frontend/src/components/material/StatusNotification/index.tsx new file mode 100644 index 0000000000..adc0517946 --- /dev/null +++ b/services/frontend/src/components/material/StatusNotification/index.tsx @@ -0,0 +1,34 @@ +import { Alert, Snackbar } from '@mui/material' + +/** + * A temporary notification message to give feedback on the status of an action. + * + * @param message - The message to display to the user. + * @param onClose - The function to call when the notification is closed. + * @param open - Whether the notification is open or not. + * @param severity - The severity of the notification. Changes the color and icon of the notification. + */ +export const StatusNotification = ({ + message, + onClose, + open, + severity, +}: { + message: string + onClose: () => void + open: boolean + severity: 'success' | 'info' | 'warning' | 'error' +}) => { + return ( + + + {message} + + + ) +} diff --git a/services/frontend/src/pages/Feedback/index.tsx b/services/frontend/src/pages/Feedback/index.tsx new file mode 100644 index 0000000000..f89e0e8387 --- /dev/null +++ b/services/frontend/src/pages/Feedback/index.tsx @@ -0,0 +1,136 @@ +/* eslint-disable consistent-return */ +import { Send } from '@mui/icons-material' +import { Box, Button, Container, Link, Modal, TextField, Tooltip, Typography } from '@mui/material' +import { useEffect, useState } from 'react' + +import { useTitle } from '@/common/hooks' +import { PageTitle } from '@/components/material/PageTitle' +import { StatusNotification } from '@/components/material/StatusNotification' +import { useGetAuthorizedUserQuery } from '@/redux/auth' +import { useSendFeedbackMutation } from '@/redux/feedback' + +export const Feedback = () => { + useTitle('Feedback') + + const [feedback, setFeedback] = useState('') + const [showError, setShowError] = useState(false) + const [showSuccess, setShowSuccess] = useState(false) + const [modalOpen, setModalOpen] = useState(false) + + const { email } = useGetAuthorizedUserQuery() + const [sendFeedback, { isError, isLoading, isSuccess }] = useSendFeedbackMutation() + + useEffect(() => { + if (isSuccess) { + setFeedback('') + setShowSuccess(true) + const timer = setTimeout(() => setShowSuccess(false), 10000) + return () => clearTimeout(timer) + } + }, [isSuccess]) + + useEffect(() => { + if (isError) { + setShowError(true) + const timer = setTimeout(() => setShowError(false), 10000) + return () => clearTimeout(timer) + } + }, [isError]) + + const handleTyping = event => { + setFeedback(event.target.value) + } + + const handleSubmit = () => { + sendFeedback({ content: feedback }) + setModalOpen(false) + } + + return ( + + setShowSuccess(false)} + open={showSuccess} + severity="success" + /> + setShowError(false)} + open={showError} + severity="error" + /> + + + + We are constantly improving Oodikone. Please share your thoughts using the form below, or contact us at +
+ grp-toska@helsinki.fi. You can write in Finnish or English. +
+
+ + + + + + + + setModalOpen(false)} open={modalOpen}> + + + Sending feedback to Toska + + + + + + + +
+ ) +} From 73ff9f585bf3447ec1853e143ca1634490980812 Mon Sep 17 00:00:00 2001 From: Riku Rauhala Date: Tue, 12 Nov 2024 10:20:49 +0200 Subject: [PATCH 2/4] [Feedback] Remove old Semantic UI component --- .../src/components/Feedback/index.jsx | 97 ------------------- 1 file changed, 97 deletions(-) delete mode 100644 services/frontend/src/components/Feedback/index.jsx diff --git a/services/frontend/src/components/Feedback/index.jsx b/services/frontend/src/components/Feedback/index.jsx deleted file mode 100644 index 2575232670..0000000000 --- a/services/frontend/src/components/Feedback/index.jsx +++ /dev/null @@ -1,97 +0,0 @@ -import { useEffect, useState } from 'react' -import { Button, Form, Header, Icon, Message, Modal, TextArea } from 'semantic-ui-react' - -import { useTitle } from '@/common/hooks' -import { useSendFeedbackMutation } from '@/redux/feedback' - -export const Feedback = () => { - const [feedback, setFeedback] = useState('') - const [showError, setShowError] = useState(false) - const [showSuccess, setShowSuccess] = useState(false) - useTitle('Feedback') - - const [sendFeedback, { isError, isLoading, isSuccess }] = useSendFeedbackMutation() - - useEffect(() => { - if (!isSuccess) return undefined - setFeedback('') - setShowSuccess(true) - const timer = setTimeout(() => setShowSuccess(false), 10000) - return () => clearTimeout(timer) - }, [isSuccess]) - - useEffect(() => { - if (!isError) return undefined - setShowError(true) - const timer = setTimeout(() => setShowError(false), 10000) - return () => clearTimeout(timer) - }, [isError]) - - const handleTyping = ({ target }) => { - setFeedback(target.value) - } - - const handleSubmit = event => { - event.preventDefault() - sendFeedback({ content: feedback }) - } - - return ( -
- {showSuccess && ( - - - - Your message was sent -

Thank you for contacting us. We’ll get back to you soon.

-
-
- )} - {showError && ( - - - - Your message was not sent -

An error occured while trying to send your message. Please try again.

-
-
- )} -
- Give feedback - - We are constantly improving Oodikone. Please share your thoughts using the form below, or contact us at{' '} - grp-toska@helsinki.fi. -
You can write in Finnish or English.
-
-
-
-