From d5d99c6f4f05e79ea31ce1334d77715a30bef059 Mon Sep 17 00:00:00 2001 From: RezHackXYZ Date: Mon, 2 Jun 2025 10:32:09 +0530 Subject: [PATCH 01/12] hardcoded new ui, will now make it funtional --- src/routes/kahootclone/create/+page.svelte | 32 ++---- src/routes/kahootclone/create/Buttons.svelte | 11 +++ .../create/HowTheQuestionWillLook.svelte | 97 +++++++++++++++++++ .../kahootclone/create/QuestionOptions.svelte | 80 +++++++++++++++ .../kahootclone/create/QuestionsList.svelte | 13 +++ .../components/Questions/answers.svelte | 23 ----- .../components/Questions/question.svelte | 79 --------------- .../components/buttons/DeleteQuestion.svelte | 20 ---- .../buttons/GenerateOptionsUsingAI.svelte | 19 ---- .../buttons/GenerateQuetionsUsingAI.svelte | 14 --- .../components/buttons/NewQuestion.svelte | 15 --- .../components/buttons/StartGame.svelte | 18 ---- .../buttons/UseDemoQuestions.svelte | 15 --- .../components/buttons/WaitStartGame.svelte | 18 ---- .../create/logic/GameCreateData.svelte.js | 38 -------- .../create/logic/GenerateOptionsUsingAI.js | 43 -------- .../create/logic/GenerateQuestionsUsingAI.js | 41 -------- .../create/logic/InsertGameInDB.js | 80 --------------- .../kahootclone/create/logic/StartGame.js | 17 ---- .../kahootclone/create/logic/UpLoadFiles.js | 31 ------ src/routes/tailwind.css | 28 +++--- 21 files changed, 225 insertions(+), 507 deletions(-) create mode 100644 src/routes/kahootclone/create/Buttons.svelte create mode 100644 src/routes/kahootclone/create/HowTheQuestionWillLook.svelte create mode 100644 src/routes/kahootclone/create/QuestionOptions.svelte create mode 100644 src/routes/kahootclone/create/QuestionsList.svelte delete mode 100644 src/routes/kahootclone/create/components/Questions/answers.svelte delete mode 100644 src/routes/kahootclone/create/components/Questions/question.svelte delete mode 100644 src/routes/kahootclone/create/components/buttons/DeleteQuestion.svelte delete mode 100644 src/routes/kahootclone/create/components/buttons/GenerateOptionsUsingAI.svelte delete mode 100644 src/routes/kahootclone/create/components/buttons/GenerateQuetionsUsingAI.svelte delete mode 100644 src/routes/kahootclone/create/components/buttons/NewQuestion.svelte delete mode 100644 src/routes/kahootclone/create/components/buttons/StartGame.svelte delete mode 100644 src/routes/kahootclone/create/components/buttons/UseDemoQuestions.svelte delete mode 100644 src/routes/kahootclone/create/components/buttons/WaitStartGame.svelte delete mode 100644 src/routes/kahootclone/create/logic/GameCreateData.svelte.js delete mode 100644 src/routes/kahootclone/create/logic/GenerateOptionsUsingAI.js delete mode 100644 src/routes/kahootclone/create/logic/GenerateQuestionsUsingAI.js delete mode 100644 src/routes/kahootclone/create/logic/InsertGameInDB.js delete mode 100644 src/routes/kahootclone/create/logic/StartGame.js delete mode 100644 src/routes/kahootclone/create/logic/UpLoadFiles.js diff --git a/src/routes/kahootclone/create/+page.svelte b/src/routes/kahootclone/create/+page.svelte index 06798db..c602b2e 100644 --- a/src/routes/kahootclone/create/+page.svelte +++ b/src/routes/kahootclone/create/+page.svelte @@ -1,28 +1,12 @@ -
-
-
- {#each questions.v as question, index} - - {/each} -
- - {#if Wait.v == false} - - {:else} - - {/if} -
-
+
+ +
+
diff --git a/src/routes/kahootclone/create/Buttons.svelte b/src/routes/kahootclone/create/Buttons.svelte new file mode 100644 index 0000000..93d2c80 --- /dev/null +++ b/src/routes/kahootclone/create/Buttons.svelte @@ -0,0 +1,11 @@ +
+ + + +
diff --git a/src/routes/kahootclone/create/HowTheQuestionWillLook.svelte b/src/routes/kahootclone/create/HowTheQuestionWillLook.svelte new file mode 100644 index 0000000..53e26a8 --- /dev/null +++ b/src/routes/kahootclone/create/HowTheQuestionWillLook.svelte @@ -0,0 +1,97 @@ + + +
+

How it will look

+ +
+
+

+ 1.What is the capital of France? +

+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+
+
+
diff --git a/src/routes/kahootclone/create/QuestionOptions.svelte b/src/routes/kahootclone/create/QuestionOptions.svelte new file mode 100644 index 0000000..d2dd500 --- /dev/null +++ b/src/routes/kahootclone/create/QuestionOptions.svelte @@ -0,0 +1,80 @@ +
+
+

Options

+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ {#if "SingleAnswer" === "SingleAnswer"} + Options +
+
+ + + +
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+ +
+ {/if} +
+
+
+
+ + +
+
+
diff --git a/src/routes/kahootclone/create/QuestionsList.svelte b/src/routes/kahootclone/create/QuestionsList.svelte new file mode 100644 index 0000000..b883026 --- /dev/null +++ b/src/routes/kahootclone/create/QuestionsList.svelte @@ -0,0 +1,13 @@ + + +
+

Questions

+ {#each questions as questions, questionIndex} +
+ {questionIndex + 1}.{questions} +
+ {/each} +
+
diff --git a/src/routes/kahootclone/create/components/Questions/answers.svelte b/src/routes/kahootclone/create/components/Questions/answers.svelte deleted file mode 100644 index dd8002e..0000000 --- a/src/routes/kahootclone/create/components/Questions/answers.svelte +++ /dev/null @@ -1,23 +0,0 @@ - - -
- - - -
diff --git a/src/routes/kahootclone/create/components/Questions/question.svelte b/src/routes/kahootclone/create/components/Questions/question.svelte deleted file mode 100644 index e739168..0000000 --- a/src/routes/kahootclone/create/components/Questions/question.svelte +++ /dev/null @@ -1,79 +0,0 @@ - - -
-
-
-

Q{index + 1}.

- - - - -
- -
- {#each questions.v[index].answers as _, answersIndex} - - {/each} -
- - { - questions.v[index].media = await UpLoadFiles(files[0]); - }} - bind:files - accept="image/*,video/*" - /> -
-
diff --git a/src/routes/kahootclone/create/components/buttons/DeleteQuestion.svelte b/src/routes/kahootclone/create/components/buttons/DeleteQuestion.svelte deleted file mode 100644 index 7057ea9..0000000 --- a/src/routes/kahootclone/create/components/buttons/DeleteQuestion.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - - diff --git a/src/routes/kahootclone/create/components/buttons/GenerateOptionsUsingAI.svelte b/src/routes/kahootclone/create/components/buttons/GenerateOptionsUsingAI.svelte deleted file mode 100644 index b657a8c..0000000 --- a/src/routes/kahootclone/create/components/buttons/GenerateOptionsUsingAI.svelte +++ /dev/null @@ -1,19 +0,0 @@ - - -{#if questions.v[index].answers.every((answer) => answer === "")} - -{/if} diff --git a/src/routes/kahootclone/create/components/buttons/GenerateQuetionsUsingAI.svelte b/src/routes/kahootclone/create/components/buttons/GenerateQuetionsUsingAI.svelte deleted file mode 100644 index 8932152..0000000 --- a/src/routes/kahootclone/create/components/buttons/GenerateQuetionsUsingAI.svelte +++ /dev/null @@ -1,14 +0,0 @@ - - -{#if questions.v.length === 0 || (questions.v.length === 1 && questions.v[0].name === "" && questions.v[0].answers.every((answer) => answer === "") && questions.v[0].correctAnswer === undefined)} - -{/if} diff --git a/src/routes/kahootclone/create/components/buttons/NewQuestion.svelte b/src/routes/kahootclone/create/components/buttons/NewQuestion.svelte deleted file mode 100644 index 63cc2d6..0000000 --- a/src/routes/kahootclone/create/components/buttons/NewQuestion.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - - diff --git a/src/routes/kahootclone/create/components/buttons/StartGame.svelte b/src/routes/kahootclone/create/components/buttons/StartGame.svelte deleted file mode 100644 index 10f8d3a..0000000 --- a/src/routes/kahootclone/create/components/buttons/StartGame.svelte +++ /dev/null @@ -1,18 +0,0 @@ - - - diff --git a/src/routes/kahootclone/create/components/buttons/UseDemoQuestions.svelte b/src/routes/kahootclone/create/components/buttons/UseDemoQuestions.svelte deleted file mode 100644 index ead81cd..0000000 --- a/src/routes/kahootclone/create/components/buttons/UseDemoQuestions.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - - diff --git a/src/routes/kahootclone/create/components/buttons/WaitStartGame.svelte b/src/routes/kahootclone/create/components/buttons/WaitStartGame.svelte deleted file mode 100644 index 0102b86..0000000 --- a/src/routes/kahootclone/create/components/buttons/WaitStartGame.svelte +++ /dev/null @@ -1,18 +0,0 @@ - - - diff --git a/src/routes/kahootclone/create/logic/GameCreateData.svelte.js b/src/routes/kahootclone/create/logic/GameCreateData.svelte.js deleted file mode 100644 index 33a6316..0000000 --- a/src/routes/kahootclone/create/logic/GameCreateData.svelte.js +++ /dev/null @@ -1,38 +0,0 @@ - -import { DefaultQuestions } from "$lib/config.js"; -import toast from "svelte-5-french-toast"; - -export let Wait = $state({ v: false }); -export let questions = $state({ - v: [ - { - name: "", - answers: ["", "", "", ""], - correctAnswer: undefined, - timeLimit: 30, - }, - ], -}); - -export function SetQuestionsToDemoQuestions() { - questions.v = DefaultQuestions; -} - -export function AddQuestion() { - questions.v.push({ - name: "", - answers: ["", "", "", ""], - correctAnswer: undefined, - timeLimit: 30, - }); -} - -export function DeleteQuestion(index) { - if (questions.v.length > 1) { - if (confirm("Are you sure you want to delete this question? You cant undo this.")) { - questions.v.splice(index, 1); - } - } else { - toast.error("You need at least one question."); - } -} diff --git a/src/routes/kahootclone/create/logic/GenerateOptionsUsingAI.js b/src/routes/kahootclone/create/logic/GenerateOptionsUsingAI.js deleted file mode 100644 index 175c8d3..0000000 --- a/src/routes/kahootclone/create/logic/GenerateOptionsUsingAI.js +++ /dev/null @@ -1,43 +0,0 @@ -import { questions } from "./GameCreateData.svelte.js"; -import { AiPrompts } from "$lib/config.js"; -import toast from "svelte-5-french-toast"; - -export function GenerateOptionsUsingAI(index) { - if (!questions.v[index].name) { - toast.error("Please enter a question to generate options."); - return; - } - - const fetchOptions = async () => { - const response = await fetch("https://ai.hackclub.com/chat/completions", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - messages: [ - { - role: "user", - content: AiPrompts.GenerateOptionsUsingAI.replace( - "[question]", - questions.v[index].name, - ), - }, - ], - }), - }); - const data = await response.json(); - let question = questions.v[index].name; - questions.v[index] = JSON.parse(data.choices[0].message.content); - questions.v[index].name = question; - }; - - toast.promise( - fetchOptions(), - { - loading: "Generating options...", - success: "Options generated!", - error: (err) => "Error: " + (err?.message || err), - } - ); -} diff --git a/src/routes/kahootclone/create/logic/GenerateQuestionsUsingAI.js b/src/routes/kahootclone/create/logic/GenerateQuestionsUsingAI.js deleted file mode 100644 index 7c369f9..0000000 --- a/src/routes/kahootclone/create/logic/GenerateQuestionsUsingAI.js +++ /dev/null @@ -1,41 +0,0 @@ -import { questions } from "./GameCreateData.svelte.js"; -import { AiPrompts } from "$lib/config.js"; -import toast from "svelte-5-french-toast"; - -export function GenerateQuestionsUsingAI() { - let topic = window.prompt( - "What is the topic of the questions?\nand the number of questions in the topic?", - ); - - if (!topic) { - return; - } - - const fetchQuestions = async () => { - const response = await fetch("https://ai.hackclub.com/chat/completions", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - messages: [ - { - role: "user", - content: AiPrompts.GenerateQuestionsUsingAI.replace("[topic]", topic), - }, - ], - }), - }); - const data = await response.json(); - questions.v = JSON.parse(data.choices[0].message.content); - }; - - toast.promise( - fetchQuestions(), - { - loading: "Generating questions...", - success: "Questions added!", - error: (err) => "Error: " + err.message || err, - } - ); -} \ No newline at end of file diff --git a/src/routes/kahootclone/create/logic/InsertGameInDB.js b/src/routes/kahootclone/create/logic/InsertGameInDB.js deleted file mode 100644 index 8d4e525..0000000 --- a/src/routes/kahootclone/create/logic/InsertGameInDB.js +++ /dev/null @@ -1,80 +0,0 @@ -import { supabase } from "$lib/supabase"; -import toast from "svelte-5-french-toast"; -import { Wait } from "./GameCreateData.svelte.js"; - -export async function createGame(questions, gamePin) { - // Insert game - const insertGamePromise = supabase.from("games").insert({ - creator: "anonymous", - creationdate: new Date().toISOString(), - status: "lobby", - gamepin: gamePin, - }); - - const { data: gameData, error: gameError } = await toast.promise(insertGamePromise, { - loading: "Creating game...", - success: "Game created!", - error: (err) => - "Failed to create game: " + (err?.message || "Unknown error") + "\n\nPlease try again.", - }); - - if (gameError) { - Wait.v = false; - return; - } - - // Prepare questions and answers for batch insertion - const questionsData = questions.map((q) => ({ - gameid: gamePin, - questionstext: q.name, - correctanswer: q.correctAnswer, - timelimit: q.timeLimit, - media: q.media || null, - })); - - const insertQuestionsPromise = supabase.from("questions").insert(questionsData).select("id"); - - const { data: questionsResult, error: questionsError } = await toast.promise( - insertQuestionsPromise, - { - loading: "Inserting questions...", - success: "Questions inserted!", - error: (err) => - "Failed to insert questions: " + - (err?.message || "Unknown error") + - "\n\nPlease try again.", - }, - ); - - if (questionsError) { - Wait.v = false; - - return; - } - - const answersData = []; - questionsResult.forEach((question, index) => { - questions[index].answers.forEach((answer) => { - answersData.push({ - questionid: question.id, - content: answer, - }); - }); - }); - - const insertAnswersPromise = supabase.from("answers").insert(answersData); - - const { error: answersError } = await toast.promise(insertAnswersPromise, { - loading: "Inserting answers...", - success: "Answers inserted!", - error: (err) => - "Failed to insert answers: " + (err?.message || "Unknown error") + "\n\nPlease try again.", - }); - - if (answersError) { - Wait.v = false - return; - } - - window.location.href = `/kahootclone/host?gamepin=${gamePin}`; -} diff --git a/src/routes/kahootclone/create/logic/StartGame.js b/src/routes/kahootclone/create/logic/StartGame.js deleted file mode 100644 index 6060fac..0000000 --- a/src/routes/kahootclone/create/logic/StartGame.js +++ /dev/null @@ -1,17 +0,0 @@ -import { createGame } from "./InsertGameInDB.js"; -import { questions,Wait } from "./GameCreateData.svelte.js"; -import toast from "svelte-5-french-toast"; - -export async function startGame() { - if (questions.v.some((q) => q.name === "")) return toast.error("Please fill all questions"); - if (questions.v.some((q) => q.answers.some((a) => a === ""))) return toast.error("Fill all options"); - if (questions.v.some((q) => q.correctAnswer === undefined)) - return toast.error("Select correct answers"); - - const gamePin = Math.floor(Math.random() * 1000000) - .toString() - .padStart(6, "0"); - - Wait.v = true; - - await createGame(questions.v, gamePin);} diff --git a/src/routes/kahootclone/create/logic/UpLoadFiles.js b/src/routes/kahootclone/create/logic/UpLoadFiles.js deleted file mode 100644 index 254d180..0000000 --- a/src/routes/kahootclone/create/logic/UpLoadFiles.js +++ /dev/null @@ -1,31 +0,0 @@ -import toast from "svelte-5-french-toast"; -import { supabase } from "$lib/supabase.js"; - -export async function UpLoadFiles(file) { - if (!file) { - toast.error("Please select a file to upload first."); - return; - } - - const fileExt = file.name.split(".").pop(); - const fileName = `${Date.now()}.${fileExt}`; - const filePath = `${fileName}`; - - const uploadPromise = supabase.storage.from("useruploadedcontent").upload(filePath, file); - - const result = await toast.promise(uploadPromise, { - loading: "Uploading...", - success: "Upload successful!", - error: (error) => `Upload failed. ${error.message} Please try again.`, - }); - - if (result.error) { - toast.error("Upload error:"+ result.error.message); - return; - } - - // Retrieve public URL - const { data: publicData } = supabase.storage.from("useruploadedcontent").getPublicUrl(filePath); - - return publicData.publicUrl; -} diff --git a/src/routes/tailwind.css b/src/routes/tailwind.css index f745326..9caf8e9 100644 --- a/src/routes/tailwind.css +++ b/src/routes/tailwind.css @@ -7,28 +7,32 @@ } .btn { - @apply flex cursor-pointer items-center gap-1 rounded border-2 border-white bg-gray-600 px-4 py-2 font-bold text-white transition-all hover:scale-105 hover:bg-gray-500 hover:shadow-lg; - - &.compact { - @apply px-1 py-0.5; - } - - &.circular { - @apply rounded-full; - &.compact { - @apply px-0.75 py-0.75; - } - } + @apply flex cursor-pointer items-center gap-1 rounded border-2 border-white bg-gray-700 px-4 py-2 font-bold text-white transition-all hover:scale-105 hover:bg-gray-500 hover:shadow-lg; &.dull { @apply border-gray-700 bg-transparent text-gray-700 hover:bg-gray-700 hover:text-white; } + &.slim { + @apply px-1 py-3; + } + &.green { @apply bg-green-600 hover:bg-green-500; } + &.red { + @apply bg-red-600 hover:bg-red-500; + } } .card { @apply cursor-pointer rounded border-2 border-gray-700 bg-gray-800 p-4 shadow-[4px_4px_0px_0px_white] transition-all hover:-translate-0.5 hover:shadow-[6px_6px_0px_0px_white] active:translate-0.5 active:shadow-[2px_2px_0px_0px_white]; } + +.input { + @apply w-full rounded border-2 border-gray-700 bg-gray-800 px-4 py-2 text-white transition-all placeholder:text-gray-500 focus:border-white focus:outline-none; +} + +.ratio { + @apply h-6 w-6; +} From 52aab530e36b6c440a8ed8a3b5ccb43b42647979 Mon Sep 17 00:00:00 2001 From: RezHackXYZ Date: Mon, 2 Jun 2025 10:38:56 +0530 Subject: [PATCH 02/12] remove backup and th main branch is now the backup and the actual work is in a diffrent branch --- .../create copy backup/+page.svelte | 26 ------ .../components/Questions/answers.svelte | 23 ------ .../components/Questions/question.svelte | 79 ------------------ .../components/buttons/DeleteQuestion.svelte | 20 ----- .../buttons/GenerateOptionsUsingAI.svelte | 19 ----- .../buttons/GenerateQuetionsUsingAI.svelte | 14 ---- .../components/buttons/NewQuestion.svelte | 15 ---- .../components/buttons/StartGame.svelte | 18 ----- .../buttons/UseDemoQuestions.svelte | 15 ---- .../components/buttons/WaitStartGame.svelte | 18 ----- .../logic/GameCreateData.svelte.js | 38 --------- .../logic/GenerateOptionsUsingAI.js | 43 ---------- .../logic/GenerateQuestionsUsingAI.js | 41 ---------- .../logic/InsertGameInDB.js | 80 ------------------- .../create copy backup/logic/StartGame.js | 17 ---- .../create copy backup/logic/UpLoadFiles.js | 31 ------- 16 files changed, 497 deletions(-) delete mode 100644 src/routes/kahootclone/create copy backup/+page.svelte delete mode 100644 src/routes/kahootclone/create copy backup/components/Questions/answers.svelte delete mode 100644 src/routes/kahootclone/create copy backup/components/Questions/question.svelte delete mode 100644 src/routes/kahootclone/create copy backup/components/buttons/DeleteQuestion.svelte delete mode 100644 src/routes/kahootclone/create copy backup/components/buttons/GenerateOptionsUsingAI.svelte delete mode 100644 src/routes/kahootclone/create copy backup/components/buttons/GenerateQuetionsUsingAI.svelte delete mode 100644 src/routes/kahootclone/create copy backup/components/buttons/NewQuestion.svelte delete mode 100644 src/routes/kahootclone/create copy backup/components/buttons/StartGame.svelte delete mode 100644 src/routes/kahootclone/create copy backup/components/buttons/UseDemoQuestions.svelte delete mode 100644 src/routes/kahootclone/create copy backup/components/buttons/WaitStartGame.svelte delete mode 100644 src/routes/kahootclone/create copy backup/logic/GameCreateData.svelte.js delete mode 100644 src/routes/kahootclone/create copy backup/logic/GenerateOptionsUsingAI.js delete mode 100644 src/routes/kahootclone/create copy backup/logic/GenerateQuestionsUsingAI.js delete mode 100644 src/routes/kahootclone/create copy backup/logic/InsertGameInDB.js delete mode 100644 src/routes/kahootclone/create copy backup/logic/StartGame.js delete mode 100644 src/routes/kahootclone/create copy backup/logic/UpLoadFiles.js diff --git a/src/routes/kahootclone/create copy backup/+page.svelte b/src/routes/kahootclone/create copy backup/+page.svelte deleted file mode 100644 index 02e29a7..0000000 --- a/src/routes/kahootclone/create copy backup/+page.svelte +++ /dev/null @@ -1,26 +0,0 @@ - - -
-
-
- {#each questions.v as question, index} - - {/each} -
- - {#if Wait.v == false} - - {:else} - - {/if} -
-
-
diff --git a/src/routes/kahootclone/create copy backup/components/Questions/answers.svelte b/src/routes/kahootclone/create copy backup/components/Questions/answers.svelte deleted file mode 100644 index dd8002e..0000000 --- a/src/routes/kahootclone/create copy backup/components/Questions/answers.svelte +++ /dev/null @@ -1,23 +0,0 @@ - - -
- - - -
diff --git a/src/routes/kahootclone/create copy backup/components/Questions/question.svelte b/src/routes/kahootclone/create copy backup/components/Questions/question.svelte deleted file mode 100644 index e739168..0000000 --- a/src/routes/kahootclone/create copy backup/components/Questions/question.svelte +++ /dev/null @@ -1,79 +0,0 @@ - - -
-
-
-

Q{index + 1}.

- - - - -
- -
- {#each questions.v[index].answers as _, answersIndex} - - {/each} -
- - { - questions.v[index].media = await UpLoadFiles(files[0]); - }} - bind:files - accept="image/*,video/*" - /> -
-
diff --git a/src/routes/kahootclone/create copy backup/components/buttons/DeleteQuestion.svelte b/src/routes/kahootclone/create copy backup/components/buttons/DeleteQuestion.svelte deleted file mode 100644 index 7057ea9..0000000 --- a/src/routes/kahootclone/create copy backup/components/buttons/DeleteQuestion.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - - diff --git a/src/routes/kahootclone/create copy backup/components/buttons/GenerateOptionsUsingAI.svelte b/src/routes/kahootclone/create copy backup/components/buttons/GenerateOptionsUsingAI.svelte deleted file mode 100644 index b657a8c..0000000 --- a/src/routes/kahootclone/create copy backup/components/buttons/GenerateOptionsUsingAI.svelte +++ /dev/null @@ -1,19 +0,0 @@ - - -{#if questions.v[index].answers.every((answer) => answer === "")} - -{/if} diff --git a/src/routes/kahootclone/create copy backup/components/buttons/GenerateQuetionsUsingAI.svelte b/src/routes/kahootclone/create copy backup/components/buttons/GenerateQuetionsUsingAI.svelte deleted file mode 100644 index 8932152..0000000 --- a/src/routes/kahootclone/create copy backup/components/buttons/GenerateQuetionsUsingAI.svelte +++ /dev/null @@ -1,14 +0,0 @@ - - -{#if questions.v.length === 0 || (questions.v.length === 1 && questions.v[0].name === "" && questions.v[0].answers.every((answer) => answer === "") && questions.v[0].correctAnswer === undefined)} - -{/if} diff --git a/src/routes/kahootclone/create copy backup/components/buttons/NewQuestion.svelte b/src/routes/kahootclone/create copy backup/components/buttons/NewQuestion.svelte deleted file mode 100644 index 63cc2d6..0000000 --- a/src/routes/kahootclone/create copy backup/components/buttons/NewQuestion.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - - diff --git a/src/routes/kahootclone/create copy backup/components/buttons/StartGame.svelte b/src/routes/kahootclone/create copy backup/components/buttons/StartGame.svelte deleted file mode 100644 index 10f8d3a..0000000 --- a/src/routes/kahootclone/create copy backup/components/buttons/StartGame.svelte +++ /dev/null @@ -1,18 +0,0 @@ - - - diff --git a/src/routes/kahootclone/create copy backup/components/buttons/UseDemoQuestions.svelte b/src/routes/kahootclone/create copy backup/components/buttons/UseDemoQuestions.svelte deleted file mode 100644 index ead81cd..0000000 --- a/src/routes/kahootclone/create copy backup/components/buttons/UseDemoQuestions.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - - diff --git a/src/routes/kahootclone/create copy backup/components/buttons/WaitStartGame.svelte b/src/routes/kahootclone/create copy backup/components/buttons/WaitStartGame.svelte deleted file mode 100644 index 0102b86..0000000 --- a/src/routes/kahootclone/create copy backup/components/buttons/WaitStartGame.svelte +++ /dev/null @@ -1,18 +0,0 @@ - - - diff --git a/src/routes/kahootclone/create copy backup/logic/GameCreateData.svelte.js b/src/routes/kahootclone/create copy backup/logic/GameCreateData.svelte.js deleted file mode 100644 index 33a6316..0000000 --- a/src/routes/kahootclone/create copy backup/logic/GameCreateData.svelte.js +++ /dev/null @@ -1,38 +0,0 @@ - -import { DefaultQuestions } from "$lib/config.js"; -import toast from "svelte-5-french-toast"; - -export let Wait = $state({ v: false }); -export let questions = $state({ - v: [ - { - name: "", - answers: ["", "", "", ""], - correctAnswer: undefined, - timeLimit: 30, - }, - ], -}); - -export function SetQuestionsToDemoQuestions() { - questions.v = DefaultQuestions; -} - -export function AddQuestion() { - questions.v.push({ - name: "", - answers: ["", "", "", ""], - correctAnswer: undefined, - timeLimit: 30, - }); -} - -export function DeleteQuestion(index) { - if (questions.v.length > 1) { - if (confirm("Are you sure you want to delete this question? You cant undo this.")) { - questions.v.splice(index, 1); - } - } else { - toast.error("You need at least one question."); - } -} diff --git a/src/routes/kahootclone/create copy backup/logic/GenerateOptionsUsingAI.js b/src/routes/kahootclone/create copy backup/logic/GenerateOptionsUsingAI.js deleted file mode 100644 index 175c8d3..0000000 --- a/src/routes/kahootclone/create copy backup/logic/GenerateOptionsUsingAI.js +++ /dev/null @@ -1,43 +0,0 @@ -import { questions } from "./GameCreateData.svelte.js"; -import { AiPrompts } from "$lib/config.js"; -import toast from "svelte-5-french-toast"; - -export function GenerateOptionsUsingAI(index) { - if (!questions.v[index].name) { - toast.error("Please enter a question to generate options."); - return; - } - - const fetchOptions = async () => { - const response = await fetch("https://ai.hackclub.com/chat/completions", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - messages: [ - { - role: "user", - content: AiPrompts.GenerateOptionsUsingAI.replace( - "[question]", - questions.v[index].name, - ), - }, - ], - }), - }); - const data = await response.json(); - let question = questions.v[index].name; - questions.v[index] = JSON.parse(data.choices[0].message.content); - questions.v[index].name = question; - }; - - toast.promise( - fetchOptions(), - { - loading: "Generating options...", - success: "Options generated!", - error: (err) => "Error: " + (err?.message || err), - } - ); -} diff --git a/src/routes/kahootclone/create copy backup/logic/GenerateQuestionsUsingAI.js b/src/routes/kahootclone/create copy backup/logic/GenerateQuestionsUsingAI.js deleted file mode 100644 index 7c369f9..0000000 --- a/src/routes/kahootclone/create copy backup/logic/GenerateQuestionsUsingAI.js +++ /dev/null @@ -1,41 +0,0 @@ -import { questions } from "./GameCreateData.svelte.js"; -import { AiPrompts } from "$lib/config.js"; -import toast from "svelte-5-french-toast"; - -export function GenerateQuestionsUsingAI() { - let topic = window.prompt( - "What is the topic of the questions?\nand the number of questions in the topic?", - ); - - if (!topic) { - return; - } - - const fetchQuestions = async () => { - const response = await fetch("https://ai.hackclub.com/chat/completions", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - messages: [ - { - role: "user", - content: AiPrompts.GenerateQuestionsUsingAI.replace("[topic]", topic), - }, - ], - }), - }); - const data = await response.json(); - questions.v = JSON.parse(data.choices[0].message.content); - }; - - toast.promise( - fetchQuestions(), - { - loading: "Generating questions...", - success: "Questions added!", - error: (err) => "Error: " + err.message || err, - } - ); -} \ No newline at end of file diff --git a/src/routes/kahootclone/create copy backup/logic/InsertGameInDB.js b/src/routes/kahootclone/create copy backup/logic/InsertGameInDB.js deleted file mode 100644 index 8d4e525..0000000 --- a/src/routes/kahootclone/create copy backup/logic/InsertGameInDB.js +++ /dev/null @@ -1,80 +0,0 @@ -import { supabase } from "$lib/supabase"; -import toast from "svelte-5-french-toast"; -import { Wait } from "./GameCreateData.svelte.js"; - -export async function createGame(questions, gamePin) { - // Insert game - const insertGamePromise = supabase.from("games").insert({ - creator: "anonymous", - creationdate: new Date().toISOString(), - status: "lobby", - gamepin: gamePin, - }); - - const { data: gameData, error: gameError } = await toast.promise(insertGamePromise, { - loading: "Creating game...", - success: "Game created!", - error: (err) => - "Failed to create game: " + (err?.message || "Unknown error") + "\n\nPlease try again.", - }); - - if (gameError) { - Wait.v = false; - return; - } - - // Prepare questions and answers for batch insertion - const questionsData = questions.map((q) => ({ - gameid: gamePin, - questionstext: q.name, - correctanswer: q.correctAnswer, - timelimit: q.timeLimit, - media: q.media || null, - })); - - const insertQuestionsPromise = supabase.from("questions").insert(questionsData).select("id"); - - const { data: questionsResult, error: questionsError } = await toast.promise( - insertQuestionsPromise, - { - loading: "Inserting questions...", - success: "Questions inserted!", - error: (err) => - "Failed to insert questions: " + - (err?.message || "Unknown error") + - "\n\nPlease try again.", - }, - ); - - if (questionsError) { - Wait.v = false; - - return; - } - - const answersData = []; - questionsResult.forEach((question, index) => { - questions[index].answers.forEach((answer) => { - answersData.push({ - questionid: question.id, - content: answer, - }); - }); - }); - - const insertAnswersPromise = supabase.from("answers").insert(answersData); - - const { error: answersError } = await toast.promise(insertAnswersPromise, { - loading: "Inserting answers...", - success: "Answers inserted!", - error: (err) => - "Failed to insert answers: " + (err?.message || "Unknown error") + "\n\nPlease try again.", - }); - - if (answersError) { - Wait.v = false - return; - } - - window.location.href = `/kahootclone/host?gamepin=${gamePin}`; -} diff --git a/src/routes/kahootclone/create copy backup/logic/StartGame.js b/src/routes/kahootclone/create copy backup/logic/StartGame.js deleted file mode 100644 index 6060fac..0000000 --- a/src/routes/kahootclone/create copy backup/logic/StartGame.js +++ /dev/null @@ -1,17 +0,0 @@ -import { createGame } from "./InsertGameInDB.js"; -import { questions,Wait } from "./GameCreateData.svelte.js"; -import toast from "svelte-5-french-toast"; - -export async function startGame() { - if (questions.v.some((q) => q.name === "")) return toast.error("Please fill all questions"); - if (questions.v.some((q) => q.answers.some((a) => a === ""))) return toast.error("Fill all options"); - if (questions.v.some((q) => q.correctAnswer === undefined)) - return toast.error("Select correct answers"); - - const gamePin = Math.floor(Math.random() * 1000000) - .toString() - .padStart(6, "0"); - - Wait.v = true; - - await createGame(questions.v, gamePin);} diff --git a/src/routes/kahootclone/create copy backup/logic/UpLoadFiles.js b/src/routes/kahootclone/create copy backup/logic/UpLoadFiles.js deleted file mode 100644 index 254d180..0000000 --- a/src/routes/kahootclone/create copy backup/logic/UpLoadFiles.js +++ /dev/null @@ -1,31 +0,0 @@ -import toast from "svelte-5-french-toast"; -import { supabase } from "$lib/supabase.js"; - -export async function UpLoadFiles(file) { - if (!file) { - toast.error("Please select a file to upload first."); - return; - } - - const fileExt = file.name.split(".").pop(); - const fileName = `${Date.now()}.${fileExt}`; - const filePath = `${fileName}`; - - const uploadPromise = supabase.storage.from("useruploadedcontent").upload(filePath, file); - - const result = await toast.promise(uploadPromise, { - loading: "Uploading...", - success: "Upload successful!", - error: (error) => `Upload failed. ${error.message} Please try again.`, - }); - - if (result.error) { - toast.error("Upload error:"+ result.error.message); - return; - } - - // Retrieve public URL - const { data: publicData } = supabase.storage.from("useruploadedcontent").getPublicUrl(filePath); - - return publicData.publicUrl; -} From b3ee5ebc78daf5acaf22721bec10af71ba1de73a Mon Sep 17 00:00:00 2001 From: RezHackXYZ Date: Mon, 2 Jun 2025 12:04:34 +0530 Subject: [PATCH 03/12] it mostly works and and it will generate a json (you can see the json in the console) and that json can be pussed to the supabase table with some extra code witch i will now write! --- src/lib/config.js | 79 +++------ src/routes/kahootclone/create/Buttons.svelte | 7 +- .../create/HowTheQuestionWillLook.svelte | 122 +++++-------- .../kahootclone/create/QuestionOptions.svelte | 167 ++++++++++++++---- .../kahootclone/create/QuestionsList.svelte | 30 +++- .../kahootclone/create/create.svelte.js | 17 ++ 6 files changed, 243 insertions(+), 179 deletions(-) create mode 100644 src/routes/kahootclone/create/create.svelte.js diff --git a/src/lib/config.js b/src/lib/config.js index 006b120..8270aec 100644 --- a/src/lib/config.js +++ b/src/lib/config.js @@ -59,20 +59,28 @@ export let AnswersSymbolAndColorScheme = [ export let DefaultQuestions = [ { - name: "What should you do when you're free?", - answers: ["Do something in real life!", "Play video games", "Code!", "Touch grass!"], - correctAnswer: 2, - timeLimit: 30, + questionText: "What should you do when you're free?", + timeLimit: 15, + type: "SingleAnswer", + options: ["Do something in real life!", "Play video games", "Code!", "Touch grass!"], + CorrectOption: 2, + hasMedia: false, + mediaURL: null, }, { - name: "Is RezHackXYZ the best programmer in the world?", - answers: ["Yes :)", "No :("], - correctAnswer: 0, + questionText: "Is RezHackXYZ the best programmer in the world?", timeLimit: 5, + type: "SingleAnswer", + options: ["Yes :)", "No :("], + CorrectOption: 0, + hasMedia: true, + mediaURL: "https://github.com/RezHackXYZ.png", }, { - name: "Best place in the world?", - answers: [ + questionText: "Best place in the world?", + timeLimit: 5, + type: "SingleAnswer", + options: [ "Google", "Microsoft", "Apple", @@ -82,55 +90,8 @@ export let DefaultQuestions = [ "Facebook", "Twitter", ], - correctAnswer: 4, - timeLimit: 120, + CorrectOption: 4, + hasMedia: false, + mediaURL: null, }, ]; - -export let AiPrompts = { - GenerateQuestionsUsingAI: ` -You are the AI of a quiz game. -Generate a list of quiz questions with possible answers and the correct answer index. -Each question must have: -- A "name" (question text) -- An "answers" array (minimum 2, maximum 8 options) -- A "correctAnswer" (index starting from 0) -Ensure the questions are diverse. -Example format: -{ -"name": "What is the capital of France?", -"answers": [ - "Paris", - "London", - "Berlin", - "Madrid" -], -"correctAnswer": 0 -} -JUST PROVIDE THE JSON AND NOTHING ELSE. - -The user's topic of interest is: -[topic]`, - GenerateOptionsUsingAI: ` -You are the AI of a quiz game. -Generate a list of answers relevant to the Question the correct answer index. -generate 2 things for the question: -- An "answers" array (minimum 2, maximum 8 options) -- A "correctAnswer" (index starting from 0) -Ensure the questions are diverse. -Example format if the question is "What is the capital of France?": -{ -"answers": [ - "Paris", - "London", - "Berlin", - "Madrid" -], -"correctAnswer": 0 -} -JUST PROVIDE THE JSON AND NOTHING ELSE. - -The user's Question that they want to generate options for is: -[question] -`, -}; diff --git a/src/routes/kahootclone/create/Buttons.svelte b/src/routes/kahootclone/create/Buttons.svelte index 93d2c80..c673c8d 100644 --- a/src/routes/kahootclone/create/Buttons.svelte +++ b/src/routes/kahootclone/create/Buttons.svelte @@ -1,5 +1,10 @@ + +
- + {#each QuestionsData.v[selectedQuestionIndex.v].options as Option, index} +
+
+ + + +
-
-
-
- - - -
-
-
-
- - - -
-
+ {/each}
- +
{/if}
@@ -74,7 +166,18 @@
- +
diff --git a/src/routes/kahootclone/create/QuestionsList.svelte b/src/routes/kahootclone/create/QuestionsList.svelte index b883026..13ff2eb 100644 --- a/src/routes/kahootclone/create/QuestionsList.svelte +++ b/src/routes/kahootclone/create/QuestionsList.svelte @@ -1,13 +1,31 @@

Questions

- {#each questions as questions, questionIndex} -
- {questionIndex + 1}.{questions} -
+ {#each QuestionsData.v as question, questionIndex} + {/each} -
+
+ +
diff --git a/src/routes/kahootclone/create/create.svelte.js b/src/routes/kahootclone/create/create.svelte.js new file mode 100644 index 0000000..d40cd65 --- /dev/null +++ b/src/routes/kahootclone/create/create.svelte.js @@ -0,0 +1,17 @@ +export let selectedQuestionIndex = $state({ v: 0 }); +export let QuestionsData = $state({ + v: [ + { + questionText: "", + timeLimit: 15, + type: "SingleAnswer", + options: ["", "", "", ""], + CorrectOption: null, + hasMedia: false, + mediaURL: null + }, + ], +}); + + +$inspect(QuestionsData.v); \ No newline at end of file From 757f3906c4e17686026f178a2ce9d79e80eb2f0a Mon Sep 17 00:00:00 2001 From: RezHackXYZ Date: Mon, 2 Jun 2025 12:09:50 +0530 Subject: [PATCH 04/12] fix small bug! --- src/routes/kahootclone/create/+page.svelte | 7 +++++++ src/routes/kahootclone/create/create.svelte.js | 2 -- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/routes/kahootclone/create/+page.svelte b/src/routes/kahootclone/create/+page.svelte index c602b2e..50c5b13 100644 --- a/src/routes/kahootclone/create/+page.svelte +++ b/src/routes/kahootclone/create/+page.svelte @@ -3,6 +3,13 @@ import QuestionsList from "./QuestionsList.svelte"; import QuestionOptions from "./QuestionOptions.svelte"; import Buttons from "./Buttons.svelte"; + + import { QuestionsData } from "./create.svelte.js"; + import { onMount } from "svelte"; + + onMount(() => { + $inspect(QuestionsData.v); + });
diff --git a/src/routes/kahootclone/create/create.svelte.js b/src/routes/kahootclone/create/create.svelte.js index d40cd65..a9675d1 100644 --- a/src/routes/kahootclone/create/create.svelte.js +++ b/src/routes/kahootclone/create/create.svelte.js @@ -13,5 +13,3 @@ export let QuestionsData = $state({ ], }); - -$inspect(QuestionsData.v); \ No newline at end of file From 9da2ddc1232abcf7fa66b757f13cb40a9e14eda7 Mon Sep 17 00:00:00 2001 From: RezHackXYZ Date: Mon, 2 Jun 2025 15:51:42 +0530 Subject: [PATCH 05/12] it now also adds the awnsers to the db --- src/lib/config.js | 4 +- src/routes/kahootclone/create/+page.svelte | 2 +- src/routes/kahootclone/create/Buttons.svelte | 3 +- src/routes/kahootclone/create/createGame.js | 51 ++++++++++++++++++++ src/routes/tailwind.css | 3 +- 5 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 src/routes/kahootclone/create/createGame.js diff --git a/src/lib/config.js b/src/lib/config.js index 8270aec..c685e6d 100644 --- a/src/lib/config.js +++ b/src/lib/config.js @@ -59,11 +59,11 @@ export let AnswersSymbolAndColorScheme = [ export let DefaultQuestions = [ { - questionText: "What should you do when you're free?", + questionText: "What should you do when you're free?", timeLimit: 15, type: "SingleAnswer", options: ["Do something in real life!", "Play video games", "Code!", "Touch grass!"], - CorrectOption: 2, + CorrectOption: { SingleAnswer: 2 }, hasMedia: false, mediaURL: null, }, diff --git a/src/routes/kahootclone/create/+page.svelte b/src/routes/kahootclone/create/+page.svelte index 50c5b13..be012d0 100644 --- a/src/routes/kahootclone/create/+page.svelte +++ b/src/routes/kahootclone/create/+page.svelte @@ -16,4 +16,4 @@
-
+ \ No newline at end of file diff --git a/src/routes/kahootclone/create/Buttons.svelte b/src/routes/kahootclone/create/Buttons.svelte index c673c8d..4985f05 100644 --- a/src/routes/kahootclone/create/Buttons.svelte +++ b/src/routes/kahootclone/create/Buttons.svelte @@ -1,6 +1,7 @@
@@ -10,7 +11,7 @@ -
diff --git a/src/routes/kahootclone/create/createGame.js b/src/routes/kahootclone/create/createGame.js new file mode 100644 index 0000000..782eb87 --- /dev/null +++ b/src/routes/kahootclone/create/createGame.js @@ -0,0 +1,51 @@ +import { supabase } from "$lib/supabase.js"; +import { QuestionsData } from "./create.svelte.js"; +import toast from "svelte-5-french-toast"; + +export async function createGame() { + let GamesData; + try { + GamesData = await toast.promise( + (async () => { + let { data, error } = await supabase.from("games").insert([{}]).select("id,gamepin"); + if (error) { + throw new Error(error.message); + } + return data; + })(), + { + loading: "Adding Game...", + success: "Game added!", + error: (err) => `Could not add game.\nError: ${err.message}\n\n Please try again.`, + }, + ); + + await toast.promise( + (async () => { + const { data, error } = await supabase + .from("questions") + .insert( + QuestionsData.v.map((_, index) => ({ + ...QuestionsData.v[index], + gameid: GamesData[0].id, + })), + ) + .select(); + if (error) { + throw new Error(error.message); + } + return data; + })(), + { + loading: "Adding Questions and Answers...", + success: "Questions and Answers added!", + error: (err) => + `Could not add Questions and Answers.\nError: ${err.message}\n\n Please try again.`, + }, + ); + } catch (error) { + return; + } + + toast.success(`Game created! Your game pin is: ${GamesData[0].gamepin}`); +} diff --git a/src/routes/tailwind.css b/src/routes/tailwind.css index 9caf8e9..3192c45 100644 --- a/src/routes/tailwind.css +++ b/src/routes/tailwind.css @@ -1,9 +1,10 @@ @import "https://www.nerdfonts.com/assets/css/webfont.css"; @import url("https://fonts.googleapis.com/css2?family=Comfortaa:wght@300..700&family=JetBrains+Mono:wght@200&family=Sour+Gummy:wght@300&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300&display=swap"); @import "tailwindcss"; :root { - @apply bg-gray-950 font-[Sour_Gummy] text-white; + @apply bg-gray-950 font-[Space_Grotesk] text-white; } .btn { From 47a6e59eb98aec4ef3e6e49982bb97b2e9cebea6 Mon Sep 17 00:00:00 2001 From: RezHackXYZ Date: Mon, 2 Jun 2025 16:06:29 +0530 Subject: [PATCH 06/12] fix the { SingleAnswer: part not being in many places --- src/lib/config.js | 4 ++-- src/routes/kahootclone/create/QuestionOptions.svelte | 2 +- src/routes/kahootclone/create/QuestionsList.svelte | 2 +- src/routes/kahootclone/create/create.svelte.js | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lib/config.js b/src/lib/config.js index c685e6d..2089f8d 100644 --- a/src/lib/config.js +++ b/src/lib/config.js @@ -72,7 +72,7 @@ export let DefaultQuestions = [ timeLimit: 5, type: "SingleAnswer", options: ["Yes :)", "No :("], - CorrectOption: 0, + CorrectOption: { SingleAnswer: 0 }, hasMedia: true, mediaURL: "https://github.com/RezHackXYZ.png", }, @@ -90,7 +90,7 @@ export let DefaultQuestions = [ "Facebook", "Twitter", ], - CorrectOption: 4, + CorrectOption: { SingleAnswer: 4 }, hasMedia: false, mediaURL: null, }, diff --git a/src/routes/kahootclone/create/QuestionOptions.svelte b/src/routes/kahootclone/create/QuestionOptions.svelte index 310f7db..046c07e 100644 --- a/src/routes/kahootclone/create/QuestionOptions.svelte +++ b/src/routes/kahootclone/create/QuestionOptions.svelte @@ -129,7 +129,7 @@ name="options" class="ratio" value={index} - bind:group={QuestionsData.v[selectedQuestionIndex.v].CorrectOption} + bind:group={QuestionsData.v[selectedQuestionIndex.v].CorrectOption.SingleAnswer} /> - diff --git a/src/routes/kahootclone/host/components/lobby/display.svelte b/src/routes/kahootclone/host/components/lobby/display.svelte deleted file mode 100644 index 495fee0..0000000 --- a/src/routes/kahootclone/host/components/lobby/display.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - -

HOSTING

-

Game Pin:

-

- {gamePin.v} -

- - diff --git a/src/routes/kahootclone/host/logic/GameOver.js b/src/routes/kahootclone/host/logic/GameOver.js deleted file mode 100644 index f0275b0..0000000 --- a/src/routes/kahootclone/host/logic/GameOver.js +++ /dev/null @@ -1,7 +0,0 @@ -import { supabase } from "$lib/supabase.js"; - -export async function GameOver(GamePin) { - await supabase.from("games").update({ status: `completed` }).eq("gamepin", GamePin); - - window.location.replace("/kahootclone/results?gamepin=" + GamePin + "&playerID=host-null"); -} diff --git a/src/routes/kahootclone/host/logic/GetCurrentPlayers.js b/src/routes/kahootclone/host/logic/GetCurrentPlayers.js deleted file mode 100644 index 5761345..0000000 --- a/src/routes/kahootclone/host/logic/GetCurrentPlayers.js +++ /dev/null @@ -1,17 +0,0 @@ -import { supabase } from "$lib/supabase.js"; -import toast from "svelte-5-french-toast"; -import { players } from "./HostsData.svelte.js"; - -export async function GetCurrentPlayers(gamePin) { - const { data, error } = await supabase - .from("players") - .select("playername") - .eq("gameid", Number(gamePin)); - - if (error) { - toast.error("Error fetching players: " + error.message); - return; - } - - players.v = data ? data.map((player) => player.playername) : []; -} diff --git a/src/routes/kahootclone/host/logic/HostsData.svelte.js b/src/routes/kahootclone/host/logic/HostsData.svelte.js deleted file mode 100644 index 32a0c5a..0000000 --- a/src/routes/kahootclone/host/logic/HostsData.svelte.js +++ /dev/null @@ -1,15 +0,0 @@ -export let players = $state({ v: [] }); -export let Status = $state({ v: "lobby" }); -export let questions = { v: {} }; - -export let currentQuestion = $state({ v: 0 }); -export let totalQuetions = $state({ v: 3 }); -export let PeopleAwnseredQ = $state({ v: 0 }); -export let Totalplayers = $state({ v: 3 }); - -export let CurrentQuestionDetails = $state({ v: {} }); - -export let gamePin = $state({ v: "" }); - -export let timeLeft = $state({ v: 0 }); -export let TotalTimeLeft = $state({ v: 0 }); \ No newline at end of file diff --git a/src/routes/kahootclone/host/logic/UpdatePlayersList.js b/src/routes/kahootclone/host/logic/UpdatePlayersList.js deleted file mode 100644 index 757ca4b..0000000 --- a/src/routes/kahootclone/host/logic/UpdatePlayersList.js +++ /dev/null @@ -1,26 +0,0 @@ -import { supabase } from "$lib/supabase.js"; -import { players } from "./HostsData.svelte.js"; - -export let LobbyConnection; - -function onNewPlayer(Newplayers) { - players.v.push(Newplayers.playername); -} - -export async function AutoUpdatePlayersList(gamePin) { - LobbyConnection = supabase - .channel("players-realtime") - .on( - "postgres_changes", - { - event: "INSERT", - schema: "public", - table: "players", - filter: `gameid=eq.${gamePin}`, - }, - (payload) => { - onNewPlayer(payload.new); - }, - ) - .subscribe(); -} diff --git a/src/routes/kahootclone/host/logic/WaitForAwnser.js b/src/routes/kahootclone/host/logic/WaitForAwnser.js deleted file mode 100644 index f640f66..0000000 --- a/src/routes/kahootclone/host/logic/WaitForAwnser.js +++ /dev/null @@ -1,85 +0,0 @@ -import { supabase } from "$lib/supabase.js"; -import { onNewPlayerAwnsered } from "./onNewPlayerAwnsered.js"; -import { - currentQuestion, - questions, - CurrentQuestionDetails, - TotalTimeLeft, - timeLeft, - PeopleAwnseredQ, - totalQuetions, -} from "./HostsData.svelte.js"; -import { GameOver } from "./GameOver.js"; - -let WaitingForAwnserConection; -let TimeLimitInterval; - -export async function WaitForAwnser(questionid, gamePin) { - if (questionid != 0) { - await supabase.removeChannel(WaitingForAwnserConection); - clearInterval(TimeLimitInterval); - } - - await supabase - .from("games") - .update({ status: `question-${currentQuestion.v}` }) - .eq("gamepin", gamePin); - - WaitingForAwnserConection = supabase - .channel("answeredby-realtime") - .on( - "postgres_changes", - { - event: "INSERT", - schema: "public", - table: "answeredby", - filter: `questionid=eq.${questions.v[questionid].id}`, - }, - (payload) => { - onNewPlayerAwnsered(gamePin); - }, - ) - .subscribe(); - - const { data: questionsData } = await supabase - .from("questions") - .select("*") - .eq("gameid", Number(gamePin)) - .order("id", { ascending: true }); - - const { data: answers } = await supabase - .from("answers") - .select("content") - .eq("questionid", Number(questionsData[currentQuestion.v].id)) - .order("id", { ascending: true }); - - CurrentQuestionDetails.v = { - question: questionsData[currentQuestion.v].questionstext, - correctAnswer: questionsData[currentQuestion.v].correctanswer, - answers: answers.map((answer) => answer.content), - questionid: questionsData[currentQuestion.v].id, - media: questionsData[currentQuestion.v].media || null, - timeLimit: questionsData[currentQuestion.v].timelimit, - }; - - TotalTimeLeft.v = CurrentQuestionDetails.v.timeLimit; - timeLeft.v = CurrentQuestionDetails.v.timeLimit; - - if (TotalTimeLeft.v != null) { - TimeLimitInterval = setInterval(() => { - if (timeLeft.v > 0) { - timeLeft.v--; - } else { - supabase.removeChannel(WaitingForAwnserConection); - currentQuestion.v++; - if (currentQuestion.v == totalQuetions.v) { - //GameOver(gamePin); - return; - } - PeopleAwnseredQ.v = 0; - - WaitForAwnser(currentQuestion.v, gamePin); - } - }, 1000); - } -} diff --git a/src/routes/kahootclone/host/logic/onNewPlayerAwnsered.js b/src/routes/kahootclone/host/logic/onNewPlayerAwnsered.js deleted file mode 100644 index 8c1176d..0000000 --- a/src/routes/kahootclone/host/logic/onNewPlayerAwnsered.js +++ /dev/null @@ -1,23 +0,0 @@ -import { - Totalplayers, - PeopleAwnseredQ, - currentQuestion, - totalQuetions, -} from "./HostsData.svelte.js"; -import { GameOver } from "./GameOver.js"; -import { WaitForAwnser } from "./WaitForAwnser.js"; - -export async function onNewPlayerAwnsered(GamePin) { - PeopleAwnseredQ.v++; - - if (PeopleAwnseredQ.v == Totalplayers.v) { - currentQuestion.v++; - if (currentQuestion.v == totalQuetions.v) { - GameOver(GamePin); - return; - } - PeopleAwnseredQ.v = 0; - - WaitForAwnser(currentQuestion.v, GamePin); - } -} diff --git a/src/routes/kahootclone/host/logic/startGame.js b/src/routes/kahootclone/host/logic/startGame.js deleted file mode 100644 index a54e163..0000000 --- a/src/routes/kahootclone/host/logic/startGame.js +++ /dev/null @@ -1,38 +0,0 @@ -import { supabase } from "$lib/supabase.js"; -import { LobbyConnection } from "./UpdatePlayersList.js"; -import { questions, Status, Totalplayers, totalQuetions, players } from "./HostsData.svelte.js"; -import { WaitForAwnser } from "./WaitForAwnser.js"; -import toast from "svelte-5-french-toast"; - -export async function startGame(gamePin) { - if (players.v.length == 0) { - toast.error("you need at least 1 person to start the game!"); - return; - - - } - - await supabase.removeChannel(LobbyConnection); - - Status.v = "started"; - - const { data } = await supabase - .from("questions") - .select("*") - .eq("gameid", Number(gamePin)) - .order("id", { ascending: true }); - - questions.v = data; - - totalQuetions.v = data.length; - - const { data: playersData } = await supabase - .from("players") - .select("id") - .eq("gameid", Number(gamePin)) - .order("id", { ascending: true }); - - Totalplayers.v = playersData.length; - - WaitForAwnser(0, gamePin); -} From 5b9054272ff1ded8930b4ba8f31af8a013135336 Mon Sep 17 00:00:00 2001 From: RezHackXYZ Date: Mon, 2 Jun 2025 20:31:38 +0530 Subject: [PATCH 09/12] remove inspect for now as its not needed --- src/routes/kahootclone/create/+page.svelte | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/routes/kahootclone/create/+page.svelte b/src/routes/kahootclone/create/+page.svelte index be012d0..d932189 100644 --- a/src/routes/kahootclone/create/+page.svelte +++ b/src/routes/kahootclone/create/+page.svelte @@ -3,13 +3,6 @@ import QuestionsList from "./QuestionsList.svelte"; import QuestionOptions from "./QuestionOptions.svelte"; import Buttons from "./Buttons.svelte"; - - import { QuestionsData } from "./create.svelte.js"; - import { onMount } from "svelte"; - - onMount(() => { - $inspect(QuestionsData.v); - });
From 3b254c1aa1970434e8746a90750b04937cb24b0c Mon Sep 17 00:00:00 2001 From: RezHackXYZ Date: Tue, 3 Jun 2025 13:28:27 +0530 Subject: [PATCH 10/12] make it backword compatible! --- src/routes/kahootclone/create/Buttons.svelte | 14 ++- .../kahootclone/create/create.svelte.js | 2 +- src/routes/kahootclone/create/createGame.js | 116 +++++++++++------- 3 files changed, 85 insertions(+), 47 deletions(-) diff --git a/src/routes/kahootclone/create/Buttons.svelte b/src/routes/kahootclone/create/Buttons.svelte index 8bbe757..bd66d33 100644 --- a/src/routes/kahootclone/create/Buttons.svelte +++ b/src/routes/kahootclone/create/Buttons.svelte @@ -2,7 +2,7 @@ import toast from "svelte-5-french-toast"; import { DefaultQuestions } from "$lib/config.js"; - import { QuestionsData } from "./create.svelte"; + import { QuestionsData, wait } from "./create.svelte"; import { createGame } from "./createGame.js"; let userInput = ""; @@ -87,7 +87,13 @@ The user's topic of interest is: - + {#if wait.v == true} + + {:else} + + {/if}
diff --git a/src/routes/kahootclone/create/create.svelte.js b/src/routes/kahootclone/create/create.svelte.js index 5e66cd0..53eed4a 100644 --- a/src/routes/kahootclone/create/create.svelte.js +++ b/src/routes/kahootclone/create/create.svelte.js @@ -12,4 +12,4 @@ export let QuestionsData = $state({ }, ], }); - +export let wait = $state({ v: false }); \ No newline at end of file diff --git a/src/routes/kahootclone/create/createGame.js b/src/routes/kahootclone/create/createGame.js index 782eb87..adbea5a 100644 --- a/src/routes/kahootclone/create/createGame.js +++ b/src/routes/kahootclone/create/createGame.js @@ -1,51 +1,83 @@ import { supabase } from "$lib/supabase.js"; -import { QuestionsData } from "./create.svelte.js"; +import { QuestionsData, wait } from "./create.svelte.js"; import toast from "svelte-5-french-toast"; export async function createGame() { - let GamesData; - try { - GamesData = await toast.promise( - (async () => { - let { data, error } = await supabase.from("games").insert([{}]).select("id,gamepin"); - if (error) { - throw new Error(error.message); - } - return data; - })(), - { - loading: "Adding Game...", - success: "Game added!", - error: (err) => `Could not add game.\nError: ${err.message}\n\n Please try again.`, - }, - ); + wait.v = true; + const gamePin = Math.floor(Math.random() * 1000000) + .toString() + .padStart(6, "0"); - await toast.promise( - (async () => { - const { data, error } = await supabase - .from("questions") - .insert( - QuestionsData.v.map((_, index) => ({ - ...QuestionsData.v[index], - gameid: GamesData[0].id, - })), - ) - .select(); - if (error) { - throw new Error(error.message); - } - return data; - })(), - { - loading: "Adding Questions and Answers...", - success: "Questions and Answers added!", - error: (err) => - `Could not add Questions and Answers.\nError: ${err.message}\n\n Please try again.`, - }, - ); - } catch (error) { + const questionsData = QuestionsData.v.map((q) => ({ + gameid: gamePin, + questionstext: q.questionText, + correctanswer: q.CorrectOption.SingleAnswer, + timeLimit: q.TimeLimit, + media: q.hasMedia ? q.mediaURL : null, + })); + + const insertGamePromise = supabase.from("games").insert({ + creator: "anonymous", + creationdate: new Date().toISOString(), + status: "lobby", + gamepin: gamePin, + }); + + const { data: gameData, error: gameError } = await toast.promise(insertGamePromise, { + loading: "Creating game...", + success: "Game created!", + error: (err) => + "Failed to create game: " + (err?.message || "Unknown error") + "\n\nPlease try again.", + }); + + if (gameError) { + wait.v = false; return; } - toast.success(`Game created! Your game pin is: ${GamesData[0].gamepin}`); + const insertQuestionsPromise = supabase.from("questions").insert(questionsData).select("id"); + + const { data: questionsResult, error: questionsError } = await toast.promise( + insertQuestionsPromise, + { + loading: "Inserting questions...", + success: "Questions inserted!", + error: (err) => + "Failed to insert questions: " + + (err?.message || "Unknown error") + + "\n\nPlease try again.", + }, + ); + + if (questionsError) { + wait.v = false; + return; + } + + const answersData = []; + questionsResult.forEach((question, index) => { + QuestionsData.v[index].options.forEach((answer) => { + answersData.push({ + questionid: question.id, + content: answer, + }); + }); + }); + + const insertAnswersPromise = supabase.from("answers").insert(answersData); + + const { error: answersError } = await toast.promise(insertAnswersPromise, { + loading: "Inserting answers...", + success: "Answers inserted!", + error: (err) => + "Failed to insert answers: " + (err?.message || "Unknown error") + "\n\nPlease try again.", + }); + + if (answersError) { + wait.v = false; + return; + } + + window.location.href = `/kahootclone/host?gamepin=${gamePin}`; + wait.v = false; } From d584e582072004a430f72223790ad958f1232537 Mon Sep 17 00:00:00 2001 From: RezHackXYZ Date: Tue, 3 Jun 2025 13:29:38 +0530 Subject: [PATCH 11/12] bring back host from the main branch --- src/routes/kahootclone/host/+page.svelte | 29 +++++++ .../DuringGame/PeopleAwnsered.svelte | 13 +++ .../awnseringQuetions/Awnsers.svelte | 24 ++++++ .../awnseringQuetions/ProgressBar.svelte | 13 +++ .../awnseringQuetions/display.svelte | 11 +++ .../awnseringQuetions/text/Quetion.svelte | 24 ++++++ .../host/components/DuringGame/display.svelte | 10 +++ .../components/DuringGame/timeLeft.svelte | 15 ++++ .../lobby/PlayersGUI/playerBadge.svelte | 6 ++ .../lobby/PlayersGUI/players.svelte | 12 +++ .../components/lobby/buttons/startGame.svelte | 12 +++ .../host/components/lobby/display.svelte | 15 ++++ src/routes/kahootclone/host/logic/GameOver.js | 7 ++ .../host/logic/GetCurrentPlayers.js | 17 ++++ .../host/logic/HostsData.svelte.js | 15 ++++ .../host/logic/UpdatePlayersList.js | 26 ++++++ .../kahootclone/host/logic/WaitForAwnser.js | 85 +++++++++++++++++++ .../host/logic/onNewPlayerAwnsered.js | 23 +++++ .../kahootclone/host/logic/startGame.js | 38 +++++++++ 19 files changed, 395 insertions(+) create mode 100644 src/routes/kahootclone/host/+page.svelte create mode 100644 src/routes/kahootclone/host/components/DuringGame/PeopleAwnsered.svelte create mode 100644 src/routes/kahootclone/host/components/DuringGame/awnseringQuetions/Awnsers.svelte create mode 100644 src/routes/kahootclone/host/components/DuringGame/awnseringQuetions/ProgressBar.svelte create mode 100644 src/routes/kahootclone/host/components/DuringGame/awnseringQuetions/display.svelte create mode 100644 src/routes/kahootclone/host/components/DuringGame/awnseringQuetions/text/Quetion.svelte create mode 100644 src/routes/kahootclone/host/components/DuringGame/display.svelte create mode 100644 src/routes/kahootclone/host/components/DuringGame/timeLeft.svelte create mode 100644 src/routes/kahootclone/host/components/lobby/PlayersGUI/playerBadge.svelte create mode 100644 src/routes/kahootclone/host/components/lobby/PlayersGUI/players.svelte create mode 100644 src/routes/kahootclone/host/components/lobby/buttons/startGame.svelte create mode 100644 src/routes/kahootclone/host/components/lobby/display.svelte create mode 100644 src/routes/kahootclone/host/logic/GameOver.js create mode 100644 src/routes/kahootclone/host/logic/GetCurrentPlayers.js create mode 100644 src/routes/kahootclone/host/logic/HostsData.svelte.js create mode 100644 src/routes/kahootclone/host/logic/UpdatePlayersList.js create mode 100644 src/routes/kahootclone/host/logic/WaitForAwnser.js create mode 100644 src/routes/kahootclone/host/logic/onNewPlayerAwnsered.js create mode 100644 src/routes/kahootclone/host/logic/startGame.js diff --git a/src/routes/kahootclone/host/+page.svelte b/src/routes/kahootclone/host/+page.svelte new file mode 100644 index 0000000..6f7a3df --- /dev/null +++ b/src/routes/kahootclone/host/+page.svelte @@ -0,0 +1,29 @@ + + +
+
+ {#if Status.v == "lobby"} + + {:else if Status.v == "started"} + + {/if} +
+
diff --git a/src/routes/kahootclone/host/components/DuringGame/PeopleAwnsered.svelte b/src/routes/kahootclone/host/components/DuringGame/PeopleAwnsered.svelte new file mode 100644 index 0000000..5c02b48 --- /dev/null +++ b/src/routes/kahootclone/host/components/DuringGame/PeopleAwnsered.svelte @@ -0,0 +1,13 @@ + + +
+

{PeopleAwnseredQ.v} out of {Totalplayers.v} have answered the question

+
+
+
+
diff --git a/src/routes/kahootclone/host/components/DuringGame/awnseringQuetions/Awnsers.svelte b/src/routes/kahootclone/host/components/DuringGame/awnseringQuetions/Awnsers.svelte new file mode 100644 index 0000000..0911124 --- /dev/null +++ b/src/routes/kahootclone/host/components/DuringGame/awnseringQuetions/Awnsers.svelte @@ -0,0 +1,24 @@ + + +
+ {#each CurrentQuestionDetails.v.answers as answer, index} +
+ + +
+ {/each} +
diff --git a/src/routes/kahootclone/host/components/DuringGame/awnseringQuetions/ProgressBar.svelte b/src/routes/kahootclone/host/components/DuringGame/awnseringQuetions/ProgressBar.svelte new file mode 100644 index 0000000..34cb551 --- /dev/null +++ b/src/routes/kahootclone/host/components/DuringGame/awnseringQuetions/ProgressBar.svelte @@ -0,0 +1,13 @@ + + +
+

Question {currentQuestion.v + 1} of {totalQuetions.v}

+
+
+
+
diff --git a/src/routes/kahootclone/host/components/DuringGame/awnseringQuetions/display.svelte b/src/routes/kahootclone/host/components/DuringGame/awnseringQuetions/display.svelte new file mode 100644 index 0000000..5643130 --- /dev/null +++ b/src/routes/kahootclone/host/components/DuringGame/awnseringQuetions/display.svelte @@ -0,0 +1,11 @@ + + + + + + + diff --git a/src/routes/kahootclone/host/components/DuringGame/awnseringQuetions/text/Quetion.svelte b/src/routes/kahootclone/host/components/DuringGame/awnseringQuetions/text/Quetion.svelte new file mode 100644 index 0000000..8ba9f89 --- /dev/null +++ b/src/routes/kahootclone/host/components/DuringGame/awnseringQuetions/text/Quetion.svelte @@ -0,0 +1,24 @@ + + +

+ Q{currentQuestion.v + 1}. {CurrentQuestionDetails.v.question} +

+{#if CurrentQuestionDetails.v.media != null} +
+ {#if CurrentQuestionDetails.v.media.match(/\.(mp4|webm|ogg|mov|avi|mkv)$/i)} +
+{/if} diff --git a/src/routes/kahootclone/host/components/DuringGame/display.svelte b/src/routes/kahootclone/host/components/DuringGame/display.svelte new file mode 100644 index 0000000..92a5995 --- /dev/null +++ b/src/routes/kahootclone/host/components/DuringGame/display.svelte @@ -0,0 +1,10 @@ + + +

HOSTING

+ + + \ No newline at end of file diff --git a/src/routes/kahootclone/host/components/DuringGame/timeLeft.svelte b/src/routes/kahootclone/host/components/DuringGame/timeLeft.svelte new file mode 100644 index 0000000..147daaa --- /dev/null +++ b/src/routes/kahootclone/host/components/DuringGame/timeLeft.svelte @@ -0,0 +1,15 @@ + + +{#if TotalTimeLeft.v != null} +
+

{timeLeft.v}sec out of {TotalTimeLeft.v}secs is left

+
+
+
+
+{/if} diff --git a/src/routes/kahootclone/host/components/lobby/PlayersGUI/playerBadge.svelte b/src/routes/kahootclone/host/components/lobby/PlayersGUI/playerBadge.svelte new file mode 100644 index 0000000..ced3664 --- /dev/null +++ b/src/routes/kahootclone/host/components/lobby/PlayersGUI/playerBadge.svelte @@ -0,0 +1,6 @@ + + +{playerName} diff --git a/src/routes/kahootclone/host/components/lobby/PlayersGUI/players.svelte b/src/routes/kahootclone/host/components/lobby/PlayersGUI/players.svelte new file mode 100644 index 0000000..de8b651 --- /dev/null +++ b/src/routes/kahootclone/host/components/lobby/PlayersGUI/players.svelte @@ -0,0 +1,12 @@ + + +

Players Joined:

+

(Total Players: {players.v.length})

+
+ {#each players.v as playerName} + + {/each} +
diff --git a/src/routes/kahootclone/host/components/lobby/buttons/startGame.svelte b/src/routes/kahootclone/host/components/lobby/buttons/startGame.svelte new file mode 100644 index 0000000..4c6e8ac --- /dev/null +++ b/src/routes/kahootclone/host/components/lobby/buttons/startGame.svelte @@ -0,0 +1,12 @@ + + + diff --git a/src/routes/kahootclone/host/components/lobby/display.svelte b/src/routes/kahootclone/host/components/lobby/display.svelte new file mode 100644 index 0000000..495fee0 --- /dev/null +++ b/src/routes/kahootclone/host/components/lobby/display.svelte @@ -0,0 +1,15 @@ + + +

HOSTING

+

Game Pin:

+

+ {gamePin.v} +

+ + diff --git a/src/routes/kahootclone/host/logic/GameOver.js b/src/routes/kahootclone/host/logic/GameOver.js new file mode 100644 index 0000000..f0275b0 --- /dev/null +++ b/src/routes/kahootclone/host/logic/GameOver.js @@ -0,0 +1,7 @@ +import { supabase } from "$lib/supabase.js"; + +export async function GameOver(GamePin) { + await supabase.from("games").update({ status: `completed` }).eq("gamepin", GamePin); + + window.location.replace("/kahootclone/results?gamepin=" + GamePin + "&playerID=host-null"); +} diff --git a/src/routes/kahootclone/host/logic/GetCurrentPlayers.js b/src/routes/kahootclone/host/logic/GetCurrentPlayers.js new file mode 100644 index 0000000..5761345 --- /dev/null +++ b/src/routes/kahootclone/host/logic/GetCurrentPlayers.js @@ -0,0 +1,17 @@ +import { supabase } from "$lib/supabase.js"; +import toast from "svelte-5-french-toast"; +import { players } from "./HostsData.svelte.js"; + +export async function GetCurrentPlayers(gamePin) { + const { data, error } = await supabase + .from("players") + .select("playername") + .eq("gameid", Number(gamePin)); + + if (error) { + toast.error("Error fetching players: " + error.message); + return; + } + + players.v = data ? data.map((player) => player.playername) : []; +} diff --git a/src/routes/kahootclone/host/logic/HostsData.svelte.js b/src/routes/kahootclone/host/logic/HostsData.svelte.js new file mode 100644 index 0000000..32a0c5a --- /dev/null +++ b/src/routes/kahootclone/host/logic/HostsData.svelte.js @@ -0,0 +1,15 @@ +export let players = $state({ v: [] }); +export let Status = $state({ v: "lobby" }); +export let questions = { v: {} }; + +export let currentQuestion = $state({ v: 0 }); +export let totalQuetions = $state({ v: 3 }); +export let PeopleAwnseredQ = $state({ v: 0 }); +export let Totalplayers = $state({ v: 3 }); + +export let CurrentQuestionDetails = $state({ v: {} }); + +export let gamePin = $state({ v: "" }); + +export let timeLeft = $state({ v: 0 }); +export let TotalTimeLeft = $state({ v: 0 }); \ No newline at end of file diff --git a/src/routes/kahootclone/host/logic/UpdatePlayersList.js b/src/routes/kahootclone/host/logic/UpdatePlayersList.js new file mode 100644 index 0000000..757ca4b --- /dev/null +++ b/src/routes/kahootclone/host/logic/UpdatePlayersList.js @@ -0,0 +1,26 @@ +import { supabase } from "$lib/supabase.js"; +import { players } from "./HostsData.svelte.js"; + +export let LobbyConnection; + +function onNewPlayer(Newplayers) { + players.v.push(Newplayers.playername); +} + +export async function AutoUpdatePlayersList(gamePin) { + LobbyConnection = supabase + .channel("players-realtime") + .on( + "postgres_changes", + { + event: "INSERT", + schema: "public", + table: "players", + filter: `gameid=eq.${gamePin}`, + }, + (payload) => { + onNewPlayer(payload.new); + }, + ) + .subscribe(); +} diff --git a/src/routes/kahootclone/host/logic/WaitForAwnser.js b/src/routes/kahootclone/host/logic/WaitForAwnser.js new file mode 100644 index 0000000..f640f66 --- /dev/null +++ b/src/routes/kahootclone/host/logic/WaitForAwnser.js @@ -0,0 +1,85 @@ +import { supabase } from "$lib/supabase.js"; +import { onNewPlayerAwnsered } from "./onNewPlayerAwnsered.js"; +import { + currentQuestion, + questions, + CurrentQuestionDetails, + TotalTimeLeft, + timeLeft, + PeopleAwnseredQ, + totalQuetions, +} from "./HostsData.svelte.js"; +import { GameOver } from "./GameOver.js"; + +let WaitingForAwnserConection; +let TimeLimitInterval; + +export async function WaitForAwnser(questionid, gamePin) { + if (questionid != 0) { + await supabase.removeChannel(WaitingForAwnserConection); + clearInterval(TimeLimitInterval); + } + + await supabase + .from("games") + .update({ status: `question-${currentQuestion.v}` }) + .eq("gamepin", gamePin); + + WaitingForAwnserConection = supabase + .channel("answeredby-realtime") + .on( + "postgres_changes", + { + event: "INSERT", + schema: "public", + table: "answeredby", + filter: `questionid=eq.${questions.v[questionid].id}`, + }, + (payload) => { + onNewPlayerAwnsered(gamePin); + }, + ) + .subscribe(); + + const { data: questionsData } = await supabase + .from("questions") + .select("*") + .eq("gameid", Number(gamePin)) + .order("id", { ascending: true }); + + const { data: answers } = await supabase + .from("answers") + .select("content") + .eq("questionid", Number(questionsData[currentQuestion.v].id)) + .order("id", { ascending: true }); + + CurrentQuestionDetails.v = { + question: questionsData[currentQuestion.v].questionstext, + correctAnswer: questionsData[currentQuestion.v].correctanswer, + answers: answers.map((answer) => answer.content), + questionid: questionsData[currentQuestion.v].id, + media: questionsData[currentQuestion.v].media || null, + timeLimit: questionsData[currentQuestion.v].timelimit, + }; + + TotalTimeLeft.v = CurrentQuestionDetails.v.timeLimit; + timeLeft.v = CurrentQuestionDetails.v.timeLimit; + + if (TotalTimeLeft.v != null) { + TimeLimitInterval = setInterval(() => { + if (timeLeft.v > 0) { + timeLeft.v--; + } else { + supabase.removeChannel(WaitingForAwnserConection); + currentQuestion.v++; + if (currentQuestion.v == totalQuetions.v) { + //GameOver(gamePin); + return; + } + PeopleAwnseredQ.v = 0; + + WaitForAwnser(currentQuestion.v, gamePin); + } + }, 1000); + } +} diff --git a/src/routes/kahootclone/host/logic/onNewPlayerAwnsered.js b/src/routes/kahootclone/host/logic/onNewPlayerAwnsered.js new file mode 100644 index 0000000..8c1176d --- /dev/null +++ b/src/routes/kahootclone/host/logic/onNewPlayerAwnsered.js @@ -0,0 +1,23 @@ +import { + Totalplayers, + PeopleAwnseredQ, + currentQuestion, + totalQuetions, +} from "./HostsData.svelte.js"; +import { GameOver } from "./GameOver.js"; +import { WaitForAwnser } from "./WaitForAwnser.js"; + +export async function onNewPlayerAwnsered(GamePin) { + PeopleAwnseredQ.v++; + + if (PeopleAwnseredQ.v == Totalplayers.v) { + currentQuestion.v++; + if (currentQuestion.v == totalQuetions.v) { + GameOver(GamePin); + return; + } + PeopleAwnseredQ.v = 0; + + WaitForAwnser(currentQuestion.v, GamePin); + } +} diff --git a/src/routes/kahootclone/host/logic/startGame.js b/src/routes/kahootclone/host/logic/startGame.js new file mode 100644 index 0000000..a54e163 --- /dev/null +++ b/src/routes/kahootclone/host/logic/startGame.js @@ -0,0 +1,38 @@ +import { supabase } from "$lib/supabase.js"; +import { LobbyConnection } from "./UpdatePlayersList.js"; +import { questions, Status, Totalplayers, totalQuetions, players } from "./HostsData.svelte.js"; +import { WaitForAwnser } from "./WaitForAwnser.js"; +import toast from "svelte-5-french-toast"; + +export async function startGame(gamePin) { + if (players.v.length == 0) { + toast.error("you need at least 1 person to start the game!"); + return; + + + } + + await supabase.removeChannel(LobbyConnection); + + Status.v = "started"; + + const { data } = await supabase + .from("questions") + .select("*") + .eq("gameid", Number(gamePin)) + .order("id", { ascending: true }); + + questions.v = data; + + totalQuetions.v = data.length; + + const { data: playersData } = await supabase + .from("players") + .select("id") + .eq("gameid", Number(gamePin)) + .order("id", { ascending: true }); + + Totalplayers.v = playersData.length; + + WaitForAwnser(0, gamePin); +} From 42b9e59ed7e4ab9e78e32df801567b1182cdb9c3 Mon Sep 17 00:00:00 2001 From: RezHackXYZ Date: Tue, 3 Jun 2025 16:22:11 +0530 Subject: [PATCH 12/12] fix! --- src/routes/kahootclone/create/createGame.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/routes/kahootclone/create/createGame.js b/src/routes/kahootclone/create/createGame.js index adbea5a..38a466c 100644 --- a/src/routes/kahootclone/create/createGame.js +++ b/src/routes/kahootclone/create/createGame.js @@ -3,6 +3,9 @@ import { QuestionsData, wait } from "./create.svelte.js"; import toast from "svelte-5-french-toast"; export async function createGame() { + if (wait.v) { + return; + } wait.v = true; const gamePin = Math.floor(Math.random() * 1000000) .toString() @@ -12,7 +15,7 @@ export async function createGame() { gameid: gamePin, questionstext: q.questionText, correctanswer: q.CorrectOption.SingleAnswer, - timeLimit: q.TimeLimit, + timeLimit: q.timelimit, media: q.hasMedia ? q.mediaURL : null, }));