Skip to content

Commit

Permalink
[DEV-1515] Fix webinar form and webinar questions page (#747)
Browse files Browse the repository at this point in the history
* Fix webinar form and webinar questions page

* Fixes after code review

* Fixes after code review

* Fixes after functional review

* Fixes after code review

* Simplify filter
  • Loading branch information
marcobottaro authored Mar 14, 2024
1 parent 5739492 commit 9bddc42
Show file tree
Hide file tree
Showing 8 changed files with 188 additions and 119 deletions.
5 changes: 5 additions & 0 deletions .changeset/lovely-drinks-mix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"nextjs-website": patch
---

Fix webinar form and webinar questions page
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const SummaryInformation: FC<SummaryInformationProps> = ({
alignContent: 'flex-start',
paddingTop: 10,
paddingBottom: 10,
width: '100%',
}}
>
<Typography
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import { WebinarQuestion } from '@/lib/webinars/webinarQuestions';
import { Box, IconButton, TableCell, TableRow, useTheme } from '@mui/material';
import {
Box,
IconButton,
TableCell,
TableRow,
Typography,
useTheme,
} from '@mui/material';
import { CopyToClipboardButton } from '@pagopa/mui-italia';
import DOMPurify from 'dompurify';
import AutoFixHighIcon from '@mui/icons-material/AutoFixHigh';
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff';
import Visibility from '@mui/icons-material/Visibility';
import { useFormatter, useTranslations } from 'next-intl';
import AutoFixOffIcon from '@mui/icons-material/AutoFixOff';
import { useTranslations } from 'next-intl';
import { defaultLocale, timeOptions } from '@/config';
import { ThumbUpAlt, ThumbUpOffAlt } from '@mui/icons-material';

type WebinarQuestionRowProps = {
question: WebinarQuestion;
Expand All @@ -21,13 +28,13 @@ export default function WebinarQuestionRow({
onHide,
onHighlight,
}: WebinarQuestionRowProps) {
const formatter = useFormatter();
const { palette } = useTheme();
const t = useTranslations('webinar.questionList');

const { hiddenBy, highlightedBy } = question;

const isHidden = !!hiddenBy;
const isHiddenByMe = hiddenBy === userName;
const isHighlighted = !!highlightedBy;

const tcColor =
Expand All @@ -45,42 +52,50 @@ export default function WebinarQuestionRow({
? palette.primary.dark
: palette.action.hover,
},
'& > .MuiTableCell-root': {
padding: '32px 16px 24px 16px',
},
backgroundColor:
isHighlighted && !isHidden ? palette.primary.light : '',
fontStyle: isHidden ? 'italic' : '',
position: 'relative',
}}
>
<TableCell
width='100%'
sx={{
color: tcColor,
'& > .MuiTypography-root': {
color: tcColor,
},
}}
>
{!isHidden
? formatter.dateTime(question.id.createdAt, {
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
})
: ''}
</TableCell>
<TableCell
width='70%'
sx={{
color: tcColor,
}}
>
{!isHidden
? question.question
: hiddenBy === userName
? `${t('hiddenByMe')}: (${question.question})`
: `${t('hiddenBy')}: ${hiddenBy}`}
</TableCell>
<TableCell>
<Box display={'flex'} justifyContent={'space-between'}>
{(!isHidden || (isHidden && hiddenBy === userName)) && (
{isHighlighted && !isHidden && (
<Box
sx={{
fontSize: 14,
color: palette.common.white,
marginBottom: 2,
}}
>
{t('highlightedBy')}: {highlightedBy}
</Box>
)}
<Typography fontStyle={'italic'} fontSize={14}>
{!isHidden
? question.id.createdAt.toLocaleTimeString(
defaultLocale,
timeOptions
)
: ''}
</Typography>
<Typography>
{isHiddenByMe
? `${t('hiddenByMe')}: (${question.question})`
: question.question}
</Typography>
<Box display={'flex'} justifyContent={'end'} mt={2}>
{!isHighlighted && (!isHidden || isHiddenByMe) && (
<IconButton
onClick={() => onHide(!isHidden)}
sx={{ color: tcColor }}
Expand All @@ -89,29 +104,15 @@ export default function WebinarQuestionRow({
</IconButton>
)}

{!isHidden &&
(userName === highlightedBy || !isHighlighted ? (
<IconButton
onClick={() => onHighlight(!isHighlighted)}
sx={{ color: tcColor }}
>
{!isHidden ? <AutoFixHighIcon /> : <AutoFixOffIcon />}
</IconButton>
) : (
<Box
sx={{
position: 'absolute',
top: 4,
left: 16,
fontSize: 14,
color: palette.common.white,
}}
>
{t('highlightedBy')}: {highlightedBy}
</Box>
))}

{!isHidden && (
{!isHidden && (userName === highlightedBy || !isHighlighted) && (
<IconButton
onClick={() => onHighlight(!isHighlighted)}
sx={{ color: tcColor }}
>
{!isHighlighted ? <ThumbUpAlt /> : <ThumbUpOffAlt />}
</IconButton>
)}
{!isHidden && isHighlighted && (
<CopyToClipboardButton
sx={{ color: tcColor }}
value={DOMPurify.sanitize(question.question)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { Alert, Card, Snackbar, TextField, Typography } from '@mui/material';
import { useTranslations } from 'next-intl';
import { useCallback, useState } from 'react';

const MAX_QUESTION_LENGTH = 240;

type FormState = 'submitting' | 'submitted' | undefined;
type WebinarQuestionsFormProps = {
disabled?: boolean;
Expand Down Expand Up @@ -78,7 +80,7 @@ export const WebinarQuestionsForm = ({
disabled ? theme.palette.text.disabled : theme.palette.text.primary
}
>
{t('questionsForm.title')}
{t('questionsForm.title', { maxLength: `${MAX_QUESTION_LENGTH}` })}
</Typography>

<TextField
Expand All @@ -90,9 +92,22 @@ export const WebinarQuestionsForm = ({
value={question}
variant='outlined'
onChange={handleChange}
inputProps={{ maxLength: MAX_QUESTION_LENGTH }}
helperText={
<Typography
component='span'
color={(theme) => theme.palette.text.secondary}
fontSize={12}
fontWeight={400}
sx={{ display: 'flex', justifyContent: 'end' }}
>
{question.length > 0 &&
`${question.length} / ${MAX_QUESTION_LENGTH}`}
</Typography>
}
/>
<LoadingButton
sx={{ alignSelf: 'start' }}
sx={{ alignSelf: 'end' }}
color='primary'
loadingPosition={hasFormState ? 'start' : undefined}
loading={formState === 'submitting'}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import {
Paper,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
} from '@mui/material';
import WebinarQuestionRow from '@/components/molecules/WebinarQuestion/WebinarQuestionRow';
import { updateWebinarQuestion } from '@/lib/webinarApi';
import { WebinarQuestion } from '@/lib/webinars/webinarQuestions';

type WebinarQuestionsTableProps = {
userName: string;
questions: WebinarQuestion[];
title: string;
};

const WebinarQuestionsTable = ({
userName,
questions,
title,
}: WebinarQuestionsTableProps) => {
return (
<TableContainer component={Paper} sx={{ marginY: 2 }}>
<Table aria-label='simple table'>
<TableHead>
<TableRow>
<TableCell>{title}</TableCell>
</TableRow>
</TableHead>
<TableBody>
{questions.map((question) => (
<WebinarQuestionRow
key={question.id.createdAt.toISOString()}
question={question}
userName={userName}
onHide={async (hide) =>
await updateWebinarQuestion({
id: question.id,
updates: {
hiddenBy: hide
? { operation: 'update', value: userName }
: { operation: 'remove' },
},
})
}
onHighlight={async (highlight) =>
await updateWebinarQuestion({
id: question.id,
updates: {
highlightedBy: highlight
? { operation: 'update', value: userName }
: { operation: 'remove' },
},
})
}
/>
))}
</TableBody>
</Table>
</TableContainer>
);
};

export default WebinarQuestionsTable;
Loading

0 comments on commit 9bddc42

Please sign in to comment.