Skip to content

Commit

Permalink
user feedback & message to event_rating
Browse files Browse the repository at this point in the history
  • Loading branch information
Tschonti committed Jan 13, 2024
1 parent 9bbec66 commit 9745cbe
Show file tree
Hide file tree
Showing 14 changed files with 155 additions and 25 deletions.
4 changes: 4 additions & 0 deletions packages/client/src/api/contexts/RatingContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export type RatingContextType = {
rateCriteria: (criterionId: number[]) => void
nextCategory: () => void
previousCategory: () => void
submitRating: (message?: string) => void
openSubmitModal: (onSuccessfulOpen: () => void) => void
}

export const RatingContext = createContext<RatingContextType>({
Expand All @@ -37,4 +39,6 @@ export const RatingContext = createContext<RatingContextType>({
rateCriteria: () => {},
nextCategory: () => {},
previousCategory: () => {},
submitRating: () => {},
openSubmitModal: () => {},
})
32 changes: 23 additions & 9 deletions packages/client/src/api/contexts/RatingProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,15 @@ export const RatingProvider = ({ children }: PropsWithChildren) => {
setRatedCriteria(newArray)
}

const openSubmitModal = (onSuccessfulOpen: () => void) => {
if (category?.criteria.some((c) => !ratedCriteria.includes(generateCriterionId(c.id)))) {
setValidate(true)
toast({ title: 'Minden szempont kitöltése kötelező!', status: 'warning' })
return
}
onSuccessfulOpen()
}

const nextCategory = () => {
if (!data) {
return
Expand Down Expand Up @@ -191,15 +200,18 @@ export const RatingProvider = ({ children }: PropsWithChildren) => {
setStage(newStage)
}

const submitRating = () => {
submitMutation.mutate(ratingId, {
onSuccess: () => {
reset()
toast({ title: 'Értékelés véglegesítve!', status: 'success' })
navigate(`${PATHS.EVENTS}/${data?.eventId}`)
},
onError: (e) => onError(e, toast),
})
const submitRating = (message?: string) => {
submitMutation.mutate(
{ ratingId, message },
{
onSuccess: () => {
reset()
toast({ title: 'Értékelés véglegesítve!', status: 'success' })
navigate(`${PATHS.EVENTS}/${data?.eventId}`)
},
onError: (e) => onError(e, toast),
}
)
}

const reset = () => {
Expand Down Expand Up @@ -231,6 +243,8 @@ export const RatingProvider = ({ children }: PropsWithChildren) => {
rateCriterion,
nextCategory,
previousCategory,
submitRating,
openSubmitModal,
}}
>
{children}
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/api/hooks/eventQueryHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const useFetchRateableEventsFromCache = () => {
const res = await functionAxios.get<DbEvent[]>('cached/events/rateable')
return res.data.sort((e1, e2) => -e1.startDate.localeCompare(e2.startDate))
},
{ retry: false }
{ retry: false, enabled: false } // cache likely won't be used in the future
)
}

Expand Down
10 changes: 8 additions & 2 deletions packages/client/src/api/hooks/ratingHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
GetEventRating,
PageTurn,
PontozoError,
SubmitEventRating,
} from '@pontozo/common'
import { useMutation, useQuery } from '@tanstack/react-query'
import { functionAxios } from '../../util/axiosConfig'
Expand All @@ -18,9 +19,14 @@ export const useStartRatingMutation = () => {
)
}

type SubmitEventRatingMutation = SubmitEventRating & {
ratingId: number
}

export const useSubmitRatingMutation = () => {
return useMutation<unknown, PontozoError, number>(
async (ratingId: number) => (await functionAxios.post(`${FUNC_HOST}/ratings/${ratingId}/submit`)).data
return useMutation<unknown, PontozoError, SubmitEventRatingMutation>(
async (data: SubmitEventRatingMutation) =>
(await functionAxios.post<SubmitEventRating>(`${FUNC_HOST}/ratings/${data.ratingId}/submit`, { message: data.message })).data
)
}

Expand Down
8 changes: 5 additions & 3 deletions packages/client/src/pages/ratings/Rating.page.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { Button, HStack, useMediaQuery } from '@chakra-ui/react'
import { RatingStatus } from '@pontozo/common'
import { createPortal } from 'react-dom'
import { FaChevronLeft, FaChevronRight } from 'react-icons/fa'
import { useParams } from 'react-router-dom'
import { HelmetTitle } from 'src/components/commons/HelmetTitle'
import { RatingStatus } from '../../../../common/src'
import { useRatingContext } from '../../api/contexts/useRatingContext'
import { LoadingSpinner } from '../../components/commons/LoadingSpinner'
import { CategoryWithCriteriaList } from './components/CategoryWithCriteriaList'
import { DesktopRatingProgressBar } from './components/DesktopRatingProgressBar'
import { MobileRatingProgressBar } from './components/MobileRatingProgressBar'
import { SubmitRatingModal } from './components/SubmitRatingModal'

export const RatingPage = () => {
const { ratingId } = useParams()
Expand All @@ -28,9 +29,10 @@ export const RatingPage = () => {
<Button leftIcon={<FaChevronLeft />} onClick={() => previousCategory()}>
{hasPrev ? 'Előző' : 'Vissza a versenyhez'}
</Button>
{(eventRatingInfo?.status === RatingStatus.STARTED || hasNext) && (
{eventRatingInfo?.status === RatingStatus.STARTED && !hasNext && <SubmitRatingModal colorScheme="brand" />}
{hasNext && (
<Button rightIcon={<FaChevronRight />} colorScheme="brand" onClick={() => nextCategory()}>
{hasNext ? 'Következő' : 'Véglegesítés'}
Következő
</Button>
)}
</HStack>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const CriterionRateForm = ({ criterion }: Props) => {
{criterion.text1 && <Radio value="1">{criterion.text1}</Radio>}
{criterion.text2 && <Radio value="2">{criterion.text2}</Radio>}
{criterion.text3 && <Radio value="3">{criterion.text3}</Radio>}
{criterion.allowEmpty && <Radio value="-1">Nem tudom megítélni</Radio>}
{criterion.allowEmpty && <Radio value="-1">Nem tudom megítélni/nem releváns</Radio>}
</Stack>
</RadioGroup>
</FormControl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { formatDateRange } from 'src/util/formatDateRange'
import { PATHS } from 'src/util/paths'
import './progressBar.css'
import { ProgressBarItem } from './ProgressBarItem'
import { SubmitRatingModal } from './SubmitRatingModal'

export const DesktopRatingProgressBar = () => {
const { eventRatingInfo, nextCategory, previousCategory, hasNext, hasPrev } = useRatingContext()
Expand Down Expand Up @@ -72,9 +73,10 @@ export const DesktopRatingProgressBar = () => {
<Button color="brand.500" leftIcon={<FaChevronLeft />} onClick={() => previousCategory()} variant="ghost">
{hasPrev ? 'Előző' : 'Vissza'}
</Button>
{(eventRatingInfo.status === RatingStatus.STARTED || hasNext) && (
<Button color="brand.500" rightIcon={<FaChevronRight />} onClick={() => nextCategory()} variant="ghost">
{hasNext ? 'Következő' : 'Véglegesítés'}
{eventRatingInfo?.status === RatingStatus.STARTED && !hasNext && <SubmitRatingModal variant="ghost" color="brand.500" />}
{hasNext && (
<Button rightIcon={<FaChevronRight />} onClick={() => nextCategory()} variant="ghost">
Következő
</Button>
)}
</HStack>
Expand Down
70 changes: 70 additions & 0 deletions packages/client/src/pages/ratings/components/SubmitRatingModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import {
Button,
FormControl,
FormLabel,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Text,
Textarea,
useDisclosure,
} from '@chakra-ui/react'
import { useState } from 'react'
import { FaChevronRight } from 'react-icons/fa'
import { useRatingContext } from 'src/api/contexts/useRatingContext'

type Props = {
variant?: string
color?: string
colorScheme?: string
}

export const SubmitRatingModal = ({ variant, color, colorScheme }: Props) => {
const { submitRating, openSubmitModal } = useRatingContext()
const [value, setValue] = useState('')
const { isOpen, onClose, onOpen } = useDisclosure()
return (
<>
<Button
color={color}
colorScheme={colorScheme}
rightIcon={<FaChevronRight />}
variant={variant}
onClick={() => openSubmitModal(onOpen)}
>
Véglegesítés
</Button>
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Értékelés véglegesítése</ModalHeader>
<ModalCloseButton />
<ModalBody textAlign="justify">
<Text mb={5}>
Köszönjük, hogy értékelted a versenyt! Az értékélest a 'Küldés' gombbal tudod véglegesíteni, ezután már nem fogod tudni
szerkeszteni. Ha szeretnél még szöveges formában visszajelzést küldeni a szervezőknek, azt megteheted az alábbi
szövegdobozban.
</Text>
<FormControl>
<FormLabel>Szöveges visszajelzés (opcionális)</FormLabel>
<Textarea rows={8} value={value} onChange={(e) => setValue(e.target.value)} />
</FormControl>
</ModalBody>

<ModalFooter>
<Button mr={3} colorScheme="gray" onClick={onClose}>
Mégse
</Button>
<Button colorScheme="brand" mr={3} onClick={() => submitRating(value)}>
Küldés
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</>
)
}
8 changes: 7 additions & 1 deletion packages/common/src/lib/types/eventRatings.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ArrayNotEmpty, ArrayUnique, IsEnum, IsInt, IsOptional, Min } from 'class-validator'
import { ArrayNotEmpty, ArrayUnique, IsEnum, IsInt, IsOptional, IsString, Min } from 'class-validator'
import { CategoryWithCriteria } from './categories'
import { DbEvent, DbStage } from './dbEvents'

Expand Down Expand Up @@ -87,3 +87,9 @@ export type RatingStartedResponse = {
id: number
status: string
}

export class SubmitEventRating {
@IsOptional()
@IsString()
message?: string
}
12 changes: 10 additions & 2 deletions packages/functions/src/functions/ratings/submit.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { app, HttpRequest, HttpResponseInit, InvocationContext } from '@azure/functions'
import { isHigherRank, PontozoException, RatingStatus } from '@pontozo/common'
import { isHigherRank, PontozoException, RatingStatus, SubmitEventRating } from '@pontozo/common'
import { plainToClass } from 'class-transformer'
import { getUserFromHeader } from '../../service/auth.service'
import EventRating from '../../typeorm/entities/EventRating'
import { getAppDataSource } from '../../typeorm/getConfig'
import { handleException } from '../../util/handleException'
import { validateId } from '../../util/validation'
import { validateBody, validateId, validateWithWhitelist } from '../../util/validation'

/**
* Called when the users submits their rating of an event.
Expand All @@ -14,6 +15,10 @@ export const submitOne = async (req: HttpRequest, context: InvocationContext): P
try {
const id = validateId(req)
const user = getUserFromHeader(req)
validateBody(req)
const dto = plainToClass(SubmitEventRating, await req.json())
await validateWithWhitelist(dto)

const ads = await getAppDataSource(context)
const eventRatingRepo = ads.getRepository(EventRating)
const rating = await eventRatingRepo.findOne({
Expand Down Expand Up @@ -41,6 +46,9 @@ export const submitOne = async (req: HttpRequest, context: InvocationContext): P
throw new PontozoException('Nem értékelted le a versenyt az összes szempont szerint!', 400)
}

if (dto.message) {
rating.message = dto.message
}
rating.status = RatingStatus.SUBMITTED
rating.submittedAt = new Date()
await eventRatingRepo.save(rating)
Expand Down
4 changes: 2 additions & 2 deletions packages/functions/src/functions/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ const vk = [
text3: 'Kiváló',
nationalOnly: true,
stageSpecific: false,
allowEmpty: false,
allowEmpty: true,
competitorWeight: 1,
organiserWeight: 1,
roles: '["COMPETITOR", "COACH","ORGANISER", "JURY"]',
Expand All @@ -183,7 +183,7 @@ const vk = [
text3: 'Kiváló',
nationalOnly: true,
stageSpecific: false,
allowEmpty: false,
allowEmpty: true,
competitorWeight: 1,
organiserWeight: 1,
roles: '["COMPETITOR", "COACH","ORGANISER", "JURY"]',
Expand Down
3 changes: 2 additions & 1 deletion packages/functions/src/typeorm/configOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import UserRoleAssignment from './entities/UserRoleAssignment'
import { Init1694205775872 } from './migrations/1694205775872-init'
import { AddRaterAge1695666298049 } from './migrations/1695666298049-add_rater_age'
import { UniqueEventForUser1696272553417 } from './migrations/1696272553417-unique_event_for_user'
import { MessageToRating1705141629515 } from './migrations/1705141629515-message_to_rating'

export const DBConfig: SqlServerConnectionOptions = {
type: 'mssql',
Expand All @@ -41,6 +42,6 @@ export const DBConfig: SqlServerConnectionOptions = {
SeasonCriterionCount,
],
subscribers: [],
migrations: [Init1694205775872, AddRaterAge1695666298049, UniqueEventForUser1696272553417],
migrations: [Init1694205775872, AddRaterAge1695666298049, UniqueEventForUser1696272553417, MessageToRating1705141629515],
options: { encrypt: ENCRYPT },
}
3 changes: 3 additions & 0 deletions packages/functions/src/typeorm/entities/EventRating.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ class EventRating implements IEventRating {
@Check("status in('STARTED', 'SUBMITTED')")
status: RatingStatus

@Column({ nullable: true })
message?: string

@Column()
@Check("role in('COMPETITOR', 'COACH', 'ORGANISER', 'JURY')")
role: RatingRole
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { MigrationInterface, QueryRunner } from "typeorm";

export class MessageToRating1705141629515 implements MigrationInterface {
name = 'MessageToRating1705141629515'

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "event_rating" ADD "message" nvarchar(255)`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "event_rating" DROP COLUMN "message"`);
}

}

0 comments on commit 9745cbe

Please sign in to comment.