From 4b5b77cd98c012be9df42aa649bf5070e7564089 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1muel=20Fekete?= Date: Sun, 17 Mar 2024 23:59:50 +0100 Subject: [PATCH 1/5] stuff --- .env.local.example | 2 ++ src/components/presentation/PresentationGrid.tsx | 2 +- src/components/tiles/question-tile.tsx | 7 ++++--- src/utils/dateHelper.ts | 5 ----- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/.env.local.example b/.env.local.example index 3b09280..3c27ffe 100644 --- a/.env.local.example +++ b/.env.local.example @@ -4,3 +4,5 @@ JWT_SCOPE="" GROUP_KEY="" BACKEND_URL="https://..." NEXT_PUBLIC_PLAUSIBLE_URL="" +NEXT_PUBLIC_RECAPTCHA_SITE_KEY="<>" +RECAPTCHA_SECRET="<>" diff --git a/src/components/presentation/PresentationGrid.tsx b/src/components/presentation/PresentationGrid.tsx index 3dcda05..e49d5be 100644 --- a/src/components/presentation/PresentationGrid.tsx +++ b/src/components/presentation/PresentationGrid.tsx @@ -102,7 +102,7 @@ export function PresentationTile({ - {presentation.room !== 'BOTH' && `${presentation.room} | `} + {presentation.room !== 'BOTH' && !preview && `${presentation.room} | `} {dateToHourAndMinuteString(presentation.startDate)} - {dateToHourAndMinuteString(presentation.endDate)}
diff --git a/src/components/tiles/question-tile.tsx b/src/components/tiles/question-tile.tsx index 74d05d4..50c39aa 100644 --- a/src/components/tiles/question-tile.tsx +++ b/src/components/tiles/question-tile.tsx @@ -1,6 +1,5 @@ 'use client'; import { PresentationWithDates } from '@/models/models'; -import { getCurrentDate } from '@/utils/dateHelper'; import { PresentationTile } from '../presentation/PresentationGrid'; @@ -10,8 +9,10 @@ type Props = { }; export function RoomQuestion({ presentations, room }: Props) { - const now = getCurrentDate(); - const presentation = presentations.find((p) => p.room === room && p.startDate < now && p.endDate > now); + const now = new Date(); + const presentation = presentations.find( + (p) => p.room === room && !p.placeholder && p.startDate < now && p.endDate > now + ); return presentation ? ( ) : ( diff --git a/src/utils/dateHelper.ts b/src/utils/dateHelper.ts index e6822b9..f7ada13 100644 --- a/src/utils/dateHelper.ts +++ b/src/utils/dateHelper.ts @@ -6,8 +6,3 @@ export function dateToHourAndMinuteString(date: Date): string { timeZone: 'Europe/Budapest', }); } - -export function getCurrentDate() { - return new Date(2024, 2, 19, 14, 12); - // return new Date(); -} From a9f7399df39fbcb62ebe8c544fb89c56864e1aa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Horv=C3=A1th=20Istv=C3=A1n?= Date: Mon, 18 Mar 2024 01:16:03 +0100 Subject: [PATCH 2/5] Limit the number of asked questions per visitor --- src/app/actions.ts | 4 +- src/app/questions/page.tsx | 18 +----- .../presentation/PresentationGrid.tsx | 7 +-- .../presentation/PresentationQuestion.tsx | 57 +++++++++++++------ .../questions/question-page-body.tsx | 27 +++++++++ src/utils/questionHelpers.ts | 31 ++++++++++ 6 files changed, 105 insertions(+), 39 deletions(-) create mode 100644 src/components/questions/question-page-body.tsx create mode 100644 src/utils/questionHelpers.ts diff --git a/src/app/actions.ts b/src/app/actions.ts index d554a73..a68e559 100644 --- a/src/app/actions.ts +++ b/src/app/actions.ts @@ -39,10 +39,12 @@ export async function sendQuestion({ question, slug, recaptchaToken, + userId, }: { question: string; slug: string; recaptchaToken: string; + userId: string; }) { const isRecaptchaValid = await validateRecaptcha(recaptchaToken); if (!isRecaptchaValid) { @@ -54,7 +56,7 @@ export async function sendQuestion({ } const res = await fetch(`https://konf-qna.kir-dev.hu/api/presentation/${slug}/question`, { method: 'POST', - body: JSON.stringify({ content: question, userId: 'zokni' }), + body: JSON.stringify({ content: question, userId }), }); if (res.status === 200) { return 201; diff --git a/src/app/questions/page.tsx b/src/app/questions/page.tsx index 5a7b9e0..2747da1 100644 --- a/src/app/questions/page.tsx +++ b/src/app/questions/page.tsx @@ -1,4 +1,4 @@ -import { RoomQuestion } from '@/components/tiles/question-tile'; +import { QuestionPageBody } from '@/components/questions/question-page-body'; import { getPresentationData } from '@/models/get-presentation-data'; export default async function questionsPage() { @@ -6,21 +6,7 @@ export default async function questionsPage() { return (

Kérdezz az elődóktól!

- -
-
-

IB028

-
-
-

IB025

-
-
- -
-
- -
-
+
); } diff --git a/src/components/presentation/PresentationGrid.tsx b/src/components/presentation/PresentationGrid.tsx index e49d5be..1f86e8c 100644 --- a/src/components/presentation/PresentationGrid.tsx +++ b/src/components/presentation/PresentationGrid.tsx @@ -3,7 +3,6 @@ import clsx from 'clsx'; import Link from 'next/link'; import React, { CSSProperties, useRef } from 'react'; -import { GoogleReCaptchaProvider } from 'react-google-recaptcha-v3'; import { PresentationQuestionForm } from '@/components/presentation/PresentationQuestion'; import { Tile } from '@/components/tiles/tile'; @@ -144,11 +143,7 @@ export function PresentationTile({ {presentation.presenter?.company?.category === SponsorCategory.MAIN_SPONSOR && !preview && (

{presentation.description.split('\n')[0]}

)} - {preview && ( - - - - )} + {preview && }
diff --git a/src/components/presentation/PresentationQuestion.tsx b/src/components/presentation/PresentationQuestion.tsx index 7ceb16f..52edd25 100644 --- a/src/components/presentation/PresentationQuestion.tsx +++ b/src/components/presentation/PresentationQuestion.tsx @@ -1,10 +1,11 @@ import { Dialog } from '@headlessui/react'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { useGoogleReCaptcha } from 'react-google-recaptcha-v3'; import { FaCheckCircle } from 'react-icons/fa'; import { sendQuestion } from '@/app/actions'; import { WhiteButton } from '@/components/white-button'; +import { AllowedQuestionCount, getQuestionCount, getUserId, incrementQuestionCount } from '@/utils/questionHelpers'; interface PresentationQuestionFormProps { slug: string; @@ -17,16 +18,25 @@ export function PresentationQuestionForm({ slug }: PresentationQuestionFormProps const [error, setError] = useState(''); const [isLoading, setIsLoading] = useState(false); const [question, setQuestion] = useState(''); + const [questionCount, setQuestionCount] = useState(0); + + const canAskQuestions = questionCount < AllowedQuestionCount; + + useEffect(() => { + setQuestionCount(getQuestionCount(slug)); + }, []); const onSend = async () => { if (!executeRecaptcha) return; const recaptchaToken = await executeRecaptcha('presentation_question'); - if (question.trim()) { + if (question.trim() && canAskQuestions) { setIsLoading(true); - const status = await sendQuestion({ question, slug, recaptchaToken }); + const status = await sendQuestion({ question, slug, recaptchaToken, userId: getUserId() }); setIsLoading(false); switch (status) { case 201: + incrementQuestionCount(slug); + setQuestionCount(questionCount + 1); setIsSuccessOpen(true); setQuestion(''); break; @@ -41,19 +51,34 @@ export function PresentationQuestionForm({ slug }: PresentationQuestionFormProps return (
-