Skip to content

Commit

Permalink
Question tags in creation menu and model
Browse files Browse the repository at this point in the history
  • Loading branch information
david-vct committed Mar 29, 2024
1 parent 9096ca8 commit f2fab13
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 61 deletions.
22 changes: 8 additions & 14 deletions src/pages/QuestionCreator/ChoiceQuestionCreator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ export const ChoiceQuestionCreator = () => {
const [title, setTitle] = useState("")
const [choices, setChoices] = useState("")
const [answers, setAnswers] = useState("")
const [tags, setTags] = useState("")

const createQuestionHandler = () => {
const question = {
title,
choices: splitAndTrim(choices, ","),
answers: splitAndTrim(answers, ","),
choices: splitAndTrim(choices),
answers: splitAndTrim(answers),
tags: splitAndTrim(tags),
...initializeEmptyQuestionFields(),
}

Expand All @@ -20,18 +22,10 @@ export const ChoiceQuestionCreator = () => {

return (
<div>
<input
placeholder="Question"
onChange={(e) => setTitle(e.target.value)}
/>
<input
placeholder="Description"
onChange={(e) => setChoices(e.target.value)}
/>
<input
placeholder="Réponses"
onChange={(e) => setAnswers(e.target.value)}
/>
<input placeholder="Question" onChange={(e) => setTitle(e.target.value)} />
<input placeholder="Choix" onChange={(e) => setChoices(e.target.value)} />
<input placeholder="Réponses" onChange={(e) => setAnswers(e.target.value)} />
<input placeholder="Tags" onChange={(e) => setTags(e.target.value)} />
<button onClick={createQuestionHandler}>Créer</button>
</div>
)
Expand Down
18 changes: 6 additions & 12 deletions src/pages/QuestionCreator/CompleteQuestionCreator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ export const CompleteQuestionCreator = () => {
const [title, setTitle] = useState("")
const [description, setDescription] = useState("")
const [answers, setAnswers] = useState("")
const [tags, setTags] = useState("")

const createQuestionHandler = () => {
const question = {
title,
description,
answers: splitAndTrim(answers, ","),
tags: splitAndTrim(tags),
...initializeEmptyQuestionFields(),
}

Expand All @@ -20,18 +22,10 @@ export const CompleteQuestionCreator = () => {

return (
<div>
<input
placeholder="Question"
onChange={(e) => setTitle(e.target.value)}
/>
<input
placeholder="Description"
onChange={(e) => setDescription(e.target.value)}
/>
<input
placeholder="Réponses"
onChange={(e) => setAnswers(e.target.value)}
/>
<input placeholder="Question" onChange={(e) => setTitle(e.target.value)} />
<input placeholder="Description" onChange={(e) => setDescription(e.target.value)} />
<input placeholder="Réponses" onChange={(e) => setAnswers(e.target.value)} />
<input placeholder="Tags" onChange={(e) => setTags(e.target.value)} />
<button onClick={createQuestionHandler}>Créer</button>
</div>
)
Expand Down
15 changes: 6 additions & 9 deletions src/pages/QuestionCreator/SimpleQuestionCreator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import { initializeEmptyQuestionFields, splitAndTrim } from "../../utils/utils"
export const SimpleQuestionCreator = () => {
const [title, setTitle] = useState("")
const [answers, setAnswers] = useState("")
const [tags, setTags] = useState("")

const createQuestionHandler = () => {
const question = {
title,
answers: splitAndTrim(answers, ","),
answers: splitAndTrim(answers),
tags: splitAndTrim(tags),
...initializeEmptyQuestionFields(),
}

Expand All @@ -18,14 +20,9 @@ export const SimpleQuestionCreator = () => {

return (
<div>
<input
placeholder="Question"
onChange={(e) => setTitle(e.target.value)}
/>
<input
placeholder="Réponses"
onChange={(e) => setAnswers(e.target.value)}
/>
<input placeholder="Question" onChange={(e) => setTitle(e.target.value)} />
<input placeholder="Réponses" onChange={(e) => setAnswers(e.target.value)} />
<input placeholder="Tags" onChange={(e) => setTags(e.target.value)} />
<button onClick={createQuestionHandler}>Créer</button>
</div>
)
Expand Down
3 changes: 2 additions & 1 deletion src/pages/game/GameController.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export const GameController = () => {
setQuestionIndex(game.questionIndex)
}
})
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

if (gameId === undefined) {
Expand All @@ -82,7 +83,7 @@ export const GameController = () => {
<div>
<h1>Nouvelle partie</h1>
<LobbySettings gameId={gameId} />
<LobbyPlayers gameId={gameId} usernames={usernames} />
<LobbyPlayers usernames={usernames} />
</div>
)}
</div>
Expand Down
2 changes: 0 additions & 2 deletions src/pages/game/LobbyPlayers.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
type LobbyPlayersProps = {
gameId: string
usernames: string[]
}

export const LobbyPlayers = (props: LobbyPlayersProps) => {
return (
<div>
<h2>Joueurs</h2>
<div>Game id : {props.gameId}</div>
<ul>
{props.usernames.map((username) => (
<li>{username}</li>
Expand Down
21 changes: 19 additions & 2 deletions src/services/games-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,26 +45,43 @@ export async function createGame() {
return gameRef.id
}

/**
* Update data from an existing game
* @param id - Game id
* @param data - Object on filepath format ["a.b":c]
* @returns
*/
export async function updateGame(id: string, data: object): Promise<StoreResponse<Game>> {
// Verify game existance
if (!(await existsGameById(id))) {
return getErrorStoreResponse(`Game ${id} does not exist`)
}

// Update data
// Update game data
console.log(`Update Game : ${id} ${data}`)
const gameRef = doc(db, `games/${id}`)
await updateDoc(gameRef, data)
return getSuccessStoreResponse([])
}

/**
* Verify game existance by fetching from db
* @param id
* @returns
*/
export async function existsGameById(id: string) {
const response = await findGameById(id)
return response.success
}

/* Domain methods */

/**
* Starts game by finishing the setup
* @param id
* @returns
*/
export async function startGame(id: string) {
// TODO: Add setup logic
const response = await updateGame(id, { ["isSetup"]: true })
return response
}
Expand Down
38 changes: 21 additions & 17 deletions src/services/questions-store.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,44 @@
import { Query, addDoc, collection, documentId, query, where } from "firebase/firestore"
import { Query, addDoc, collection, documentId, limit, query, where } from "firebase/firestore"
import { db } from "../config/firebase"
import { Question, QuestionSchema } from "../utils/types"
import { Question, QuestionSchema, StoreResponse } from "../utils/types"
import { isValideQuestion } from "./validation"
import { findDataByQuery } from "./store"
import { getErrorStoreResponse, getSuccessStoreResponse } from "../utils/utils"

// References to the collections
const questionsRef = collection(db, "questions")

async function findQuestionByQuery(q: Query) {
const questions = await findDataByQuery(q, QuestionSchema)
return questions
const response: StoreResponse<Question> = await findDataByQuery(q, QuestionSchema)
return response
}

export async function findAllQuestions() {
const q = query(questionsRef)
const data = await findQuestionByQuery(q)
return data
const response = await findQuestionByQuery(q)
return response
}

export async function findQuestionById(questionId: string) {
const q = query(questionsRef, where(documentId(), "==", questionId))
const data = await findQuestionByQuery(q)
return data
const response = await findQuestionByQuery(q)
return response
}

export async function findQuestionByTags(tags: string[]) {
const q = query(questionsRef, where("tags", "array-contains-any", tags))
const data = await findQuestionByQuery(q)
return data
}

export const createQuestion = async (question: Question) => {
export async function createQuestion(question: Question) {
if (!isValideQuestion(question)) {
return
return getErrorStoreResponse("Not valide question")
}

const data = await addDoc(questionsRef, question)
return data.id
return getSuccessStoreResponse([data.id])
}

/* Domain methods */

export async function findQuestionByTags(tags: string[], nbQuestions: number = 10) {
const q = query(questionsRef, where("tags", "array-contains-any", tags), limit(nbQuestions))

const response = await findQuestionByQuery(q)
return response
}
4 changes: 2 additions & 2 deletions src/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { z } from "zod"

// Questions Schemas
const QuestionBaseSchema = z.object({
title: z.string().min(1).max(30),
title: z.string().min(1).max(100),
rating: z.object({
like: z.number(),
dislike: z.number(),
Expand All @@ -19,7 +19,7 @@ export const SimpleQuestionSchema = QuestionBaseSchema.extend({
})

export const CompleteQuestionSchema = QuestionBaseSchema.extend({
description: z.string().min(1),
description: z.string().min(1).max(250),
answers: z.array(z.string().trim()).min(1).max(10),
})

Expand Down
5 changes: 3 additions & 2 deletions src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export function initializeEmptyQuestionFields() {
return {
rating: { like: 0, dislike: 0 },
difficulty: { win: 0, lose: 0 },
tags: [],
}
}

Expand All @@ -31,6 +30,8 @@ export function initializeEmptyGameData(): GameData {
}
}

export function initializeEmptyQuestionData() {}

export function getSuccessStoreResponse<DataType>(data: DataType[]): StoreResponse<DataType> {
return {
success: true,
Expand All @@ -51,6 +52,6 @@ export function getErrorStoreResponse<DataType>(error: unknown): StoreResponse<D
* @param separator
* @returns
*/
export function splitAndTrim(str: string, separator: string) {
export function splitAndTrim(str: string, separator: string = ",") {
return str.split(separator).map((item) => item.trim())
}

0 comments on commit f2fab13

Please sign in to comment.