diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..8c6153e
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,2 @@
+VITE_SUPABASE_URL=https://yourproject.supabase.co
+VITE_SUPABASE_ANON_KEY=your-service-role-key
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 4c67142..d9e3070 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,22 +1,26 @@
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-pnpm-debug.log*
-lerna-debug.log*
-
node_modules
-dist
-dist-ssr
-*.local
-# Editor directories and files
-.idea
+# Output
+.output
+.vercel
+.netlify
+.wrangler
+/.svelte-kit
+/build
+
+# OS
.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
\ No newline at end of file
+Thumbs.db
+
+# Env
+.env
+.env.*
+!.env.example
+!.env.test
+
+# Vite
+vite.config.js.timestamp-*
+vite.config.ts.timestamp-*
+
+
+package-lock.json
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 0000000..b6f27f1
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1 @@
+engine-strict=true
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000..ab78a95
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,4 @@
+# Package Managers
+package-lock.json
+pnpm-lock.yaml
+yarn.lock
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..7e71c41
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,15 @@
+{
+ "useTabs": true,
+ "singleQuote": false,
+ "trailingComma": "all",
+ "printWidth": 100,
+ "plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
+ "overrides": [
+ {
+ "files": "*.svelte",
+ "options": {
+ "parser": "svelte"
+ }
+ }
+ ]
+}
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
deleted file mode 100644
index a1f5c8a..0000000
--- a/.vscode/extensions.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "recommendations": ["svelte.svelte-vscode", "esbenp.prettier-vscode"]
-}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 81f11fa..77b25a7 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,7 +1,9 @@
{
- "editor.defaultFormatter": "esbenp.prettier-vscode",
- "[svelte]": {
- "editor.defaultFormatter": "svelte.svelte-vscode"
+ "tailwindCSS.emmetCompletions": true,
+ "editor.inlineSuggest.enabled": true,
+ "editor.quickSuggestions": {
+ "strings": true
},
- "cSpell.words": ["Kahoot", "kokoro"]
+ "editor.defaultFormatter": "esbenp.prettier-vscode",
+ "css.customData": [".vscode/tailwind.json"]
}
diff --git a/.vscode/tailwind.json b/.vscode/tailwind.json
new file mode 100644
index 0000000..72aad7e
--- /dev/null
+++ b/.vscode/tailwind.json
@@ -0,0 +1,96 @@
+{
+ "version": 1.2,
+ "atDirectives": [
+ {
+ "name": "@theme",
+ "description": "Use the `@theme` directive to define your project's custom design tokens, like fonts, colors, and breakpoints.",
+ "references": [
+ {
+ "name": "Tailwind Documentation",
+ "url": "https://tailwindcss.com/docs/functions-and-directives#theme-directive"
+ }
+ ]
+ },
+ {
+ "name": "@source",
+ "description": "Use the `@source` directive to explicitly specify source files that aren't picked up by Tailwind's automatic content detection.",
+ "references": [
+ {
+ "name": "Tailwind Documentation",
+ "url": "https://tailwindcss.com/docs/functions-and-directives#source-directive"
+ }
+ ]
+ },
+ {
+ "name": "@utility",
+ "description": "Use the `@utility` directive to add custom utilities to your project that work with variants like `hover`, `focus` and `lg`.",
+ "references": [
+ {
+ "name": "Tailwind Documentation",
+ "url": "https://tailwindcss.com/docs/functions-and-directives#utility-directive"
+ }
+ ]
+ },
+ {
+ "name": "@variant",
+ "description": "Use the `@variant` directive to apply a Tailwind variant to styles in your CSS.",
+ "references": [
+ {
+ "name": "Tailwind Documentation",
+ "url": "https://tailwindcss.com/docs/functions-and-directives#variant-directive"
+ }
+ ]
+ },
+ {
+ "name": "@custom-variant",
+ "description": "Use the `@custom-variant` directive to add a custom variant in your project.",
+ "references": [
+ {
+ "name": "Tailwind Documentation",
+ "url": "https://tailwindcss.com/docs/functions-and-directives#custom-variant-directive"
+ }
+ ]
+ },
+ {
+ "name": "@apply",
+ "description": "Use the `@apply` directive to inline any existing utility classes into your own custom CSS.",
+ "references": [
+ {
+ "name": "Tailwind Documentation",
+ "url": "https://tailwindcss.com/docs/functions-and-directives#apply-directive"
+ }
+ ]
+ },
+ {
+ "name": "@reference",
+ "description": "If you want to use `@apply` or `@variant` in the `
diff --git a/src/IdleScreen/main.svelte b/src/IdleScreen/main.svelte
deleted file mode 100644
index bdcb86c..0000000
--- a/src/IdleScreen/main.svelte
+++ /dev/null
@@ -1,180 +0,0 @@
-
-
-
-
-
GO BACK
-
-
Idle Screen
-
-
{
- ShowSeconds.v = !ShowSeconds.v;
- localStorage.setItem("ShowSeconds", String(ShowSeconds.v));
- }}
- >{#if ShowSeconds.v}Disable Seconds{:else}Enable Seconds{/if} EditTimetable()}
- > Edit timetable
-
-
-
-
-
-
-
-
-
-{#if TabOpen.v !== false}
-
-
-
- (TabOpen.v = false)}
- aria-label="close">CLOSE
-
-
-{/if}
-
-
diff --git a/src/IdleScreen/time.svelte b/src/IdleScreen/time.svelte
deleted file mode 100644
index dc660b6..0000000
--- a/src/IdleScreen/time.svelte
+++ /dev/null
@@ -1,231 +0,0 @@
-
-
-
-
-
-
-
0
- 1
- 0
-
-
-
0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 0
-
-
:
-
-
0
- 1
- 2
- 3
- 4
- 5
- 0
-
-
-
0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 0
-
- {#if ShowSeconds.v}
-
.
-
- {/if}
-
{AmOrPm}
-
-
-
- {new Date().toLocaleString("en-US", { weekday: "short" })}
- {new Date().getDate()},
- {new Date().toLocaleString("en-US", { month: "short" })}
- {new Date().getFullYear()}
-
-
-
-
-
-
diff --git a/src/IdleScreen/timeTable.svelte b/src/IdleScreen/timeTable.svelte
deleted file mode 100644
index 7eeb45d..0000000
--- a/src/IdleScreen/timeTable.svelte
+++ /dev/null
@@ -1,198 +0,0 @@
-
-
-
-
-
-
- {#if new Date().getDay() == 1}
- Monday
- {:else}
- Monday
- {/if}
- {#each table.Monday as time}
- {#if new Date().getDay() == 1}
- {time}
- {:else}
- {time}
- {/if}
- {/each}
-
-
- {#if new Date().getDay() == 2}
- Tuesday
- {:else}
- Tuesday
- {/if}
- {#each table.Tuesday as time}
- {#if new Date().getDay() == 2}
- {time}
- {:else}
- {time}
- {/if}
- {/each}
-
-
- {#if new Date().getDay() == 3}
- Wednesday
- {:else}
- Wednesday
- {/if}
- {#each table.Wednesday as time}
- {#if new Date().getDay() == 3}
- {time}
- {:else}
- {time}
- {/if}
- {/each}
-
-
- {#if new Date().getDay() == 4}
- Thursday
- {:else}
- Thursday
- {/if}
- {#each table.Thursday as time}
- {#if new Date().getDay() == 4}
- {time}
- {:else}
- {time}
- {/if}
- {/each}
-
-
- {#if new Date().getDay() == 5}
- Friday
- {:else}
- Friday
- {/if}
- {#each table.Friday as time}
- {#if new Date().getDay() == 5}
- {time}
- {:else}
- {time}
- {/if}
- {/each}
-
-
-
-
-
diff --git a/src/SelectionMenue/TypeSelector.svelte b/src/SelectionMenue/TypeSelector.svelte
deleted file mode 100644
index 464c230..0000000
--- a/src/SelectionMenue/TypeSelector.svelte
+++ /dev/null
@@ -1,249 +0,0 @@
-
-
-
- A collection of awesome tools, games, and more — made to be used in any
- classroom!
-
-
MAIN
-
-
-
OTHERS
-
-
-
-
-
-
diff --git a/src/announcer/ActualAnnouncer.svelte b/src/announcer/ActualAnnouncer.svelte
deleted file mode 100644
index 98fc832..0000000
--- a/src/announcer/ActualAnnouncer.svelte
+++ /dev/null
@@ -1,182 +0,0 @@
-
-
-
-
-
Most Announced announcements
-
-
- {#each CommonAnounce as anouncement, i}
-
-
{
- text = anouncement;
- speak();
- }}
- >
- {anouncement}
-
-
{
- if (
- confirm(
- "Are you sure you want to delete this anouncement?"
- )
- ) {
- CommonAnounce.splice(i, 1);
- localStorage.setItem(
- "CommonAnounce",
- JSON.stringify(CommonAnounce)
- );
- }
- }}
- >
-
-
- {/each}
-
-
-
-
-
Or announce something else
-
-
- Play
-
- {#if text}
-
{
- CommonAnounce.push(text);
- text = "";
- localStorage.setItem(
- "CommonAnounce",
- JSON.stringify(CommonAnounce)
- );
- }}>Add "{text}" to "Most Announced announcements"
- {/if}
-
-
-
-
-
-
diff --git a/src/announcer/main.svelte b/src/announcer/main.svelte
deleted file mode 100644
index 1c2008c..0000000
--- a/src/announcer/main.svelte
+++ /dev/null
@@ -1,100 +0,0 @@
-
-
-
-
-
diff --git a/src/app.html b/src/app.html
new file mode 100644
index 0000000..360389c
--- /dev/null
+++ b/src/app.html
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+ %sveltekit.head%
+
+
+ %sveltekit.body%
+
+
diff --git a/src/app.svelte b/src/app.svelte
deleted file mode 100644
index 8e424e2..0000000
--- a/src/app.svelte
+++ /dev/null
@@ -1,79 +0,0 @@
-
-
-
-
-
-{#if ShowAlertDiv == true}
-
-
{ShowAlertText}
-
-{/if}
-
-
diff --git a/src/lib/config.js b/src/lib/config.js
new file mode 100644
index 0000000..45391e8
--- /dev/null
+++ b/src/lib/config.js
@@ -0,0 +1,133 @@
+export let AnswersSymbolAndColorScheme = [
+ {
+ color: "#6E0000",
+ selectedColor: "#AA2222",
+ hoverBorderColor: "#FF5D5D",
+ selectedBorderColor: "#FF0000",
+ symbol: "nf-md-triangle",
+ },
+ {
+ color: "#00316E",
+ selectedColor: "#2255AA",
+ hoverBorderColor: "#5D9CFF",
+ selectedBorderColor: "#0000FF",
+ symbol: "nf-fa-square",
+ },
+ {
+ color: "#6E6E00",
+ selectedColor: "#AAAA22",
+ hoverBorderColor: "#FFFF5D",
+ selectedBorderColor: "#DDFF00",
+ symbol: "nf-fa-circle",
+ },
+ {
+ color: "#006E00",
+ selectedColor: "#22AA22",
+ hoverBorderColor: "#5DFF5D",
+ selectedBorderColor: "#00FF00",
+ symbol: "nf-fa-diamond",
+ },
+ {
+ color: "#4B0082",
+ selectedColor: "#7F33B5",
+ hoverBorderColor: "#B066FF",
+ selectedBorderColor: "#9932CC",
+ symbol: "nf-md-star",
+ },
+ {
+ color: "#FF8C00",
+ selectedColor: "#FFB347",
+ hoverBorderColor: "#FFD580",
+ selectedBorderColor: "#FFA500",
+ symbol: "nf-md-hexagon",
+ },
+ {
+ color: "#008B8B",
+ selectedColor: "#33CCCC",
+ hoverBorderColor: "#66FFFF",
+ selectedBorderColor: "#00CED1",
+ symbol: "nf-md-octagon",
+ },
+ {
+ color: "#8B4513",
+ selectedColor: "#CD853F",
+ hoverBorderColor: "#DEB887",
+ selectedBorderColor: "#A0522D",
+ symbol: "nf-md-heart",
+ },
+];
+
+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,
+ },
+ {
+ name: "Is RezHackXYZ the best programmer in the world?",
+ answers: ["Yes :)", "No :("],
+ correctAnswer: 0,
+ },
+ {
+ name: "Best place in the world?",
+ answers: [
+ "Google",
+ "Microsoft",
+ "Apple",
+ "Samsung",
+ "Hack Club!! :D",
+ "Amazon",
+ "Facebook",
+ "Twitter",
+ ],
+ correctAnswer: 4,
+ },
+];
+
+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]
+`
+};
\ No newline at end of file
diff --git a/src/lib/showAlert.js b/src/lib/showAlert.js
new file mode 100644
index 0000000..957e3d4
--- /dev/null
+++ b/src/lib/showAlert.js
@@ -0,0 +1,2 @@
+import JSConfetti from "js-confetti";
+const jsConfetti = new JSConfetti();
diff --git a/src/lib/supabase.js b/src/lib/supabase.js
new file mode 100644
index 0000000..0a5ac16
--- /dev/null
+++ b/src/lib/supabase.js
@@ -0,0 +1,6 @@
+import { createClient } from '@supabase/supabase-js';
+
+export const supabase = createClient(
+ import.meta.env.VITE_SUPABASE_URL,
+ import.meta.env.VITE_SUPABASE_ANON_KEY
+);
\ No newline at end of file
diff --git a/src/routes/+HomePage/Galery.svelte b/src/routes/+HomePage/Galery.svelte
new file mode 100644
index 0000000..d1f7b7f
--- /dev/null
+++ b/src/routes/+HomePage/Galery.svelte
@@ -0,0 +1,28 @@
+
+
+
diff --git a/src/routes/+HomePage/ascii.svelte b/src/routes/+HomePage/ascii.svelte
new file mode 100644
index 0000000..65e4818
--- /dev/null
+++ b/src/routes/+HomePage/ascii.svelte
@@ -0,0 +1,87 @@
+
+ ##########%#% ############%#
+ #%#################% %###################%#%%
+ %%###################### ###########################%
+ ########################## %###########################%#
+ %###########################% %#############################%#
+ ##############################% ######%##########################
+ %%###############%##%############ %#################################%
+ ###############*+=-----=+*%#######% #######+--=+**#####################%
+ %%###########+=-------------*######% %######=--------=-----=*############%
+ ############+----------------.######% #######------------------=*###########
+ ##########+------------------.######% %#######% ######*----------------::::=##########%
+ %#########=-----------------::.######%############%% %######+--------------::::::-=##########
+ ########*-----------------:::.:######################% %######=------------::::::-====*#########
+ %#######*:---------------:::::.-######################## %######=----------::::::-=======*########
+ #######*:::------------::::::-:=########################% #######---------::::::-======+++=########%
+ ########=::::----------:::::-==.+#########################% ######*-------::::::-======++++++=#######%
+ #######+==:::::------::...:--==.*#########################% %######+-----:::::.:-=====++++++++=+######%
+%#######+===-:::::-::...:===--:.:################%########## %######=---::::::=.-==-=+++++++++++-#######%
+#######*++====::::::. =#######################+++++*######## %%%% %% #%%% #######=-::::::===.####++++++++++++-*####### #%#%###%% #%%####%# %%#%####%%#
+#######++++====::::..*#######################*++++++==############## #%#####%% %###############::::::====-.#####*++++++++++==##################% %#%############%% %%%%%###############
+#######+++++=====-..*#######################%**+++++-:##################% %############ #################*::::======--######+++++++++++-###################%% #################### %%%######################%%
+######*+++++++====.=##############%##########****+++--#####################%%################################+::=======+-=######+++++++++++:######################%#################################################
+######*++++++++==-.##########################*****++:=#######################################################========+++:+######++++++++**+:#########################################################################
+######*++++++++++--##########################******+:+#######################################################+=====+++++.######*+++++*****+:##########################################################################
+######*++++++++++=-##########################*******.*#######################################################====+++++++.######++++*******=-##########################################################################%
+######*++++++++++==########################%#*******.########################################################==+++++++++=*###*+++*********-=##########***#############################################**+**#############
+######***++++++++=-########################%#******+.#####*++++++*###############*++++*#########*+===#######*++++++++++++++++++***********.*########*********############********##################*++++++++++##########
+######****++++++++:#################*+######*******+:####+++++++++++**########%*++++++-#######*+++==-+######*++++++++++++++++************=.#######************#########***********+#######%#+++++=======+++++++*########%
+#######****+++++++:################***+#####*******=-###++++++++++++++++++####+++++++++=#####++++++++-######*++++++++++++++*************+.+#####**************+*######***********+++*##%**+++=============+++++++########
+#######*****++++++=+##############****+*####++++***-=##**+++++++++++++++++:##++++++++++-####++++++++++-#####+++++++++++++***************::#####****************=#####*********++++++=*##++==================++++=*#######%
+#######*******+++++=#############******+*###+++++**:+##***++++++++++++++++.#********+=:.=##+++++++++-: #####+++++++++++****************::######*******+=+*******=###******+++++++++++-##+=========-----=======+++-########
+#######********+++++=###########******++=###++++++*.*##****+++=-=********=-#********+.=####++++++++::*######+++++++++*****************=.######*+*****-.:==******-###***++++-.:-=+++====#*=====-----------:======+=+#######
+%######**********+++*+*#######*******++++=##==+++++.##*******-.=*+*******:+#*********-#####++++++++-*######*+++++++***=+************+++-######++++++=.*###******==##++++++:.*###======:#*==---------------+=======-#######%
+########***************************++++++-=*====++=.##******+.*###*******.###**********####+++++++++=######*+++++*****.==-=*******+++++:######++++++:=####*++++++-#*++++++.*####======:*#------::--------:#=--====:########%
+ #######*************************+++++++=.=+=====+=:##******=-####******+:###**********+####**++++++++*####++++******* ###*=****+++++++-+#####++++++:*####*+++++=:#*+++++=.#####+===--:+#--------#-------.#+----==-*#######%
+ %#######**********************+++++++==::#+======--##******==####******=-####+*********+###+***++++++++###++********+:#####**+++++++===-#####=====+-*####*+++++=:#*++====:#####=-----:+#=------:#+------.**-------=########
+ %#######********************+++++++===- *#=----==:=##+******=####******:+#####+*********=###+*****++++=*##**********=-#####*++++++=====:#####========####++++++:-#*======:####+------.+#=-----:.#*:::---:+#--------########
+ ########+****************+++++++====:.+##------=:+##++*****+*##*******:*######+********-####********++-##**********:=######++++=======:#####+========*+=======.*##======--**+-------.*#+--::::.*#:::::::=#=--------#######
+ %########+**************++++++=====:.*###-------.*###++***************:*#######********-+####*********.#***********.*######++=======--:+####*--==============::###===--------------::##*::::::.+#:::::::-##--------.######
+ ########%=***********++++++======:.*###*-------.####+++**************=*######++++*****.*####********=:##********** ########======------#####=----------====-.*####---------------:.+###:::::::=#-::::::.##+------.-######
+ ##########=+*******+++++++=====-.:#####+-------.#####=++++++++++++++++-####+++++++++*-.###*********+.+##*********=:########====-------:######--------------.=#####+------------::.-####::::::::#=::::::.##%+:---.:#######
+ %#########*=+***+++++++=====-:.=######+::----::######=+++++++++++++++:+###+++++++++-.*###********+.-###-=+****++--#########=---------.######*-----------:.=#######+-------::::..-#####-::::::.#+::::::.*%##*-:..########
+ %##########=-+++++++=====-:.:*#######=::::--:-#######=-=+++++=+++++-.####*+++++++:.*####*******=.=####*+-::--=+:=#########=---------.#######*::-------..+#########*::-:::::...=######=::::::.#*:::::..=#####*+#########
+ ############=--======-:..-*##########=:..::.=########*-::::.:=====.+#####====-:.:#######***+=..+###########*=--##########*------::..#########=::::...-#############+:.....:+########+::::::.*#=...--+################
+ %#############+=--::-=*#################*+=##################===.-#######-:..=#########*-:.-+############################----:..:=############*==+*################################*::....:*##*#####################
+ #############################################################*-:#########+*############*+################################:..:=*####################################################*:=+*##########################
+ ########################################################################################################################**####################################################################################%
+ #######################%@%##############################################################+++*#######################################*#######################################################################%
+ ###################%@@@@@%##############################################**+++########*++++++++###############################+=-::=###############*+-:::*########################################%%###%%
+ ################%@@@@@@@@%##################++++*############**+==---------:#######++++++==-:#########################*+=:::::::.=#########*+=-:::::::.######%%%%%#################%%%%#######%
+ ##############%@@@@%#%@@@@@%############*+---------###*+=------------------:+######========-:#########*##########*+=-::::::::::::-#####+=-::::::::::::.######%@@@@@@%###########%@@@@@@#######%
+ ############%@@@@%%####%@@@@%##########------------.##=------:::::---------:=######========:=########+::-+*#####:::::::::::::::::.###=::::::::::::::::.+#####%@@@@@@@@%#######%@@@@@@@@########
+ ##########%@@@@@%########%@@@@%#######::::---::::::.##=:::::::::::::-------:=#####*-======-.+########-::::::-*##:::::::::::::::::.###=:::::::::::::::::=#####%@@@@@@@@@@%###%@@@@@@@@@@#######%
+ #########@@@@@%############%@@@@%####-:::::::::::::.*#=::::::::::::::::----:-#####+-------- #########:::::::::*#:::::::::::::::::.+##+::::::::::::::::::#####%@@%**%@@@@@%#%@@@@@#**@@@########
+ #########%@@@@@%##########%@@@@@@###*::::::::::::::.*#+::::::::::::::::::--::#####=--------.########*::::::::.=#=:::::::::::::::::=##*:::::::::::::::::.#####%@@%****%@@@@@@@@@#****@@@#######%
+ %##########%@@@@@%######%@@@@@@@@###=::::::::::::::.*#*:::::::::::::::::::::.#####--------:-########+::::::::.*#+::::.........:::.:###::::::::::::::::..*####%@@%******%@@@@@%******@@@########
+ %###########@@@@@%###%@@@@@%#@@@###-::::::::::::::.*#*:::::::::::::::......-#####--------.=########-:::::::: ##*::...............+###::::::::::::.....:#####%@@%*******#@@@%*******@@@#######%
+ ############@@@@@@@%@@@@%@@%#@@@###:::::::::::..:::*##:::::::::::::::.=+**######+-------:.*########::::::::.:###...........:-=*######=...........:=+*#######%@@%********%@@#*******@@@#######%
+ %##########@@#*%@@@@@%#*@@%#@@@###-:::::::::.=#######+....::::::::::.##########=:----:::.########*::::::::.=###:........=###########+........:#############%@@%********#@@#*******@@@#######%
+ %#########@@#***%@@#***@@%#@@@###-::::::::.:#########**###+::::::::.*#########-:::::::.:########=::::::::.*###=........=#*+=-+#####*.........##*+==#######%@@%********#@@#*******@@@########
+ %########@@#***#@#****@@%#@@@###+:::::::::-##############+::::::::.*#########::::::::.=########-:::::::. ####+........:......+#####:........:.....:######%@@%********%@@#*******@@@#######%
+ ########@@@#**#@#***%@@%#@@@####.::::::::-##############*::::::::.+########*::::::::.+########::::::...:####*...::::::::....-#####-.............:.*#####%@@%********%@@#*******@@@%#######
+ ########@@@@%*#@#*#@@@@%#%%%####-.:::::::.###############::::::::.=########+:::::::: ########*::::.....=#####::::::::::::::::#####=..........::::.*#####%@@@@%#*****%@@#****%%@@@@#######
+ #########%@@@@%@#@@@@%##########+..::::::.*##############.....::::-########=:::::::::########=::.......*#####=::::::::::::::.#####*:::::..::::::::+#####%@@@@@@@%#**%@@#*#%@@@@@@@#######
+ %##########%@@@@@@@@%############.........-##############:......:::########-:::::::.-########:........ ######+:::--:::::::::.######:::::::::::::::=#####%@@@@@@@@@%*%@@#%@@@@@@@@@#######
+ #########%#%%@@@@%##############-.........##############-........:########::::::::.=#######*.........:######*:------------:.*#####-:::::::::::----#########%%@@@@@@@@@@@@@@@%%##########
+ %############%@%################=.........=#############-.........########::::::::.=#######=.........=#######--------------.+#####=::::::::-----::#############%@@@@@@@@@%##############
+ %##############################=.........-#############=.........########:::::::::=#######:......::.*#######---------...:-=######+--------:...:-*##############%%@@@@@%###############
+ #######################%######:..........#############+.........*#######-:::::::::######-.....::::.########+-------:-###########*--------.*#####################%@@@%################
+ ###########################*-::.........#############*:::......+#######=:::::::..:###+-....:::::.=########+---------############--------.########################%#################
+ #%###################%=----:::::::::::.####%########*::::::...+#######*.................::::::: *########*--------:############=-------:+######################################%%
+ %%##################=-----:::::::::::##############::::::::.=########:..............:::::::-:-##########--------.############+-------:=###########%%####################%#%
+ #%########%%######=------::::::::.=##############-::::::::-########*............:::::::--- *##########=-------:+###########*--------:########% #%#################%
+ #%% #######=-------:::::::.###############=---::::::#########-.........:::::::----.-###########+-------:=############--------.#######% ###############%
+ %######=------------:.+###############=-----::::##########:......:::::::-----:.*###########*--------:############--------.*######% %##########%
+ #######+-----------:.+################=--------.###########-...:::::::------:.*#############--------.############=-------:=###### #%####%#
+ %######+---------:.-##################+--------.############=:::::::------:.:*##############--------:*###########+---------######
+ %#######+::::...:=*########## ######*-----::: ##############-:::------:..+################=-------.+###########*-------::######
+ ##########*+*#############% #######+..:--=+*################=::::...:=##################+--::..:-#############--::..:-*#####%
+ ########################## %###################%#############***#######################=:-+*#################:-=*#########
+ %######################% ###################% %###########################% #########################################%
+ ###################### #################%% %#########################%% ####################%##################%
+ #%################# ###############% %######################## %##################% %################%
+ ############### %############# ####################%% ################% %###############
+ #%##%%%#% %#######%## %%%###########%%% #############% ###########%%
+
diff --git a/src/routes/+HomePage/footer.svelte b/src/routes/+HomePage/footer.svelte
new file mode 100644
index 0000000..853c0bb
--- /dev/null
+++ b/src/routes/+HomePage/footer.svelte
@@ -0,0 +1,11 @@
+
+
+
+ and the "
?ascii " flag for a surprise!
+
+
diff --git a/src/routes/+HomePage/landingPage.svelte b/src/routes/+HomePage/landingPage.svelte
new file mode 100644
index 0000000..efbd1f9
--- /dev/null
+++ b/src/routes/+HomePage/landingPage.svelte
@@ -0,0 +1,42 @@
+
+
+
+
+
+ {#if FlagAscii == true}
+
+ {:else}
+
+ {/if}
+
+ The
+
+ ultimate
+
+ classroom
+
+ toolkit
+ for all the teachers and students needs!
+
+
+
+
+
+
+ Scroll to see more tools!
+
+
+
diff --git a/src/routes/+HomePage/rightCards.svelte b/src/routes/+HomePage/rightCards.svelte
new file mode 100644
index 0000000..eda5cc1
--- /dev/null
+++ b/src/routes/+HomePage/rightCards.svelte
@@ -0,0 +1,24 @@
+
+
+
+ {#each tools as tool, i}
+ {#if i < 3}
+
+
+
+
{tool.name}
+
+
+
{@html tool.description}
+
+ {/if}
+ {/each}
+
+
diff --git a/src/routes/+HomePage/tools.json b/src/routes/+HomePage/tools.json
new file mode 100644
index 0000000..56557b2
--- /dev/null
+++ b/src/routes/+HomePage/tools.json
@@ -0,0 +1,37 @@
+[
+ {
+ "name": "Kahoot Clone",
+ "description": "A Kahoot clone built from scratch with a Postgres DB, AI integration, and more.",
+ "link": "/kahootclone",
+ "icon": "nf-md-chat_question",
+ "image": "https://placehold.co/1800x1000?text=screenshot+TBA"
+ },
+ {
+ "name": "Wordle",
+ "description": "with unlimited tries, customizable world lengths and more.",
+ "link": "/wordle",
+ "icon": "nf-md-file_word_box",
+ "image": "https://placehold.co/1800x1000?text=screenshot+TBA"
+ },
+ {
+ "name": "Announcer",
+ "description": "To let the have computer talk shout on them, if they don't listen to you",
+ "link": "/announcer",
+ "icon": "nf-md-speaker_wireless",
+ "image": "https://placehold.co/1800x1000?text=screenshot+TBA"
+ },
+ {
+ "name": "Name Selecter",
+ "description": "to chose any student randomly, with memory of previous names and more.",
+ "link": "/randomname",
+ "icon": "nf-oct-people",
+ "image": "https://placehold.co/1800x1000?text=screenshot+TBA"
+ },
+ {
+ "name": "Time&Table",
+ "description": "The perfect idle screen when theres no teacher with the timetable, time and date!",
+ "link": "/randomname",
+ "icon": "nf-cod-table",
+ "image": "https://placehold.co/1800x1000?text=screenshot+TBA"
+ }
+]
diff --git a/src/routes/+layout.js b/src/routes/+layout.js
new file mode 100644
index 0000000..c8cacf0
--- /dev/null
+++ b/src/routes/+layout.js
@@ -0,0 +1 @@
+export const prerender = true;
\ No newline at end of file
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
new file mode 100644
index 0000000..7a687d6
--- /dev/null
+++ b/src/routes/+layout.svelte
@@ -0,0 +1,9 @@
+
+
+
+{@render children()}
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
new file mode 100644
index 0000000..2c6450a
--- /dev/null
+++ b/src/routes/+page.svelte
@@ -0,0 +1,9 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/routes/IdleScreen/+page.svelte b/src/routes/IdleScreen/+page.svelte
new file mode 100644
index 0000000..9090bc0
--- /dev/null
+++ b/src/routes/IdleScreen/+page.svelte
@@ -0,0 +1,36 @@
+
+
+
+
+ {
+ ShowSeconds.v = !ShowSeconds.v;
+ localStorage.setItem("ShowSeconds", String(ShowSeconds.v));
+ }}
+ >
+ {#if ShowSeconds.v}Disable Seconds{:else}Enable Seconds{/if}
+
+
+
+
+
+ Edit timetable
+
+
+
+
+
+
+
+
diff --git a/src/routes/IdleScreen/components/time/DisplayCollsOfTime.svelte b/src/routes/IdleScreen/components/time/DisplayCollsOfTime.svelte
new file mode 100644
index 0000000..69afb40
--- /dev/null
+++ b/src/routes/IdleScreen/components/time/DisplayCollsOfTime.svelte
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
:
+
+
+
+ {#if ShowSeconds}
+ .
+
+
+
+ {/if}
+ {ampm}
+
+
+
+ {new Date().toLocaleString("en-US", { weekday: "short" })}
+ {new Date().getDate()},
+ {new Date().toLocaleString("en-US", { month: "short" })}
+ {new Date().getFullYear()}
+
+
+
diff --git a/src/routes/IdleScreen/components/time/digit.svelte b/src/routes/IdleScreen/components/time/digit.svelte
new file mode 100644
index 0000000..98c8dc2
--- /dev/null
+++ b/src/routes/IdleScreen/components/time/digit.svelte
@@ -0,0 +1,11 @@
+
+
+{#if props.size == "small"}
+
+ {props.digit}
+
+{:else if props.size == "large"}
+ {props.digit}
+{/if}
\ No newline at end of file
diff --git a/src/routes/IdleScreen/components/time/row.svelte b/src/routes/IdleScreen/components/time/row.svelte
new file mode 100644
index 0000000..fa94570
--- /dev/null
+++ b/src/routes/IdleScreen/components/time/row.svelte
@@ -0,0 +1,29 @@
+
+
+
+ {#each Array(digits) as _, i}
+
+ {/each}
+
+
diff --git a/src/routes/IdleScreen/components/timetable/DisplayRowsOfTimetable.svelte b/src/routes/IdleScreen/components/timetable/DisplayRowsOfTimetable.svelte
new file mode 100644
index 0000000..2230b1b
--- /dev/null
+++ b/src/routes/IdleScreen/components/timetable/DisplayRowsOfTimetable.svelte
@@ -0,0 +1,37 @@
+
+
+
+ {#each timetableData.v as row, RowIndex}
+ {#each row as time, timeIndex}
+ {#if RowIndex == 0 && timeIndex == 0}
+
+ {:else if RowIndex == 0}
+ {time}
+ {:else if RowIndex == new Date().getDay() && timeIndex == 0}
+ {legend[RowIndex]}
+ {:else if RowIndex == new Date().getDay()}
+ {time}
+ {:else if timeIndex == 0}
+ {legend[RowIndex]}
+ {:else}
+ {time}
+ {/if}
+ {/each}
+ {/each}
+
diff --git a/src/routes/IdleScreen/components/timetable/EditTimetable.svelte b/src/routes/IdleScreen/components/timetable/EditTimetable.svelte
new file mode 100644
index 0000000..147446e
--- /dev/null
+++ b/src/routes/IdleScreen/components/timetable/EditTimetable.svelte
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+ {
+ timetableData.v = data;
+ localStorage.setItem("timetableData", JSON.stringify(data));
+ colseModal.v = true;
+ }}
+ class="btn green mt-3">SAVE
+
+
diff --git a/src/routes/IdleScreen/logic/TimeAndTableData.svelte.js b/src/routes/IdleScreen/logic/TimeAndTableData.svelte.js
new file mode 100644
index 0000000..d480d89
--- /dev/null
+++ b/src/routes/IdleScreen/logic/TimeAndTableData.svelte.js
@@ -0,0 +1,20 @@
+export let timetableData = $state({
+ v: [
+ [
+ "07:50 - 08:50",
+ "08:50 - 09:40",
+ "09:40 - 10:30 ",
+ "10:30 - 11:00",
+ "11:00 - 12:00",
+ "12:00 - 01:00",
+ "01:00 - 02:00",
+ ],
+ ["English", "Sanskrit", "Math", "Lunch", "Hindi", "Social Science", "Science"],
+ ["English", "Art & Craft", "Math", "Lunch", "Hindi", "Social Science", "Science"],
+ ["English", "GK", "Math", "Lunch", "Hindi", "Social Science", "Science"],
+ ["English", "Sanskrit", "Math", "Lunch", "Hindi", "Social Science", "Science"],
+ ["English", "Computers", "Math", "Lunch", "Hindi", "Social Science", "Science"],
+ ],
+});
+
+export let colseModal = $state({ v: false });
diff --git a/src/routes/IdleScreen/logic/updateTime.js b/src/routes/IdleScreen/logic/updateTime.js
new file mode 100644
index 0000000..0d4927a
--- /dev/null
+++ b/src/routes/IdleScreen/logic/updateTime.js
@@ -0,0 +1,31 @@
+export function updateTime(RowsObject, Digit, type) {
+ let DigitsHeight = parseInt(type == "sec" ? "75" : "200");
+ let LastZeroPos = Digit == 1 ? 10 : Digit == 0 && type == "hour" ? 2 : 6;
+ let currentTime;
+
+ if (type == "hour") {
+ if (new Date().getHours() > 12) {
+ currentTime = parseInt((new Date().getHours() - 12).toString().padStart(2, "0")[Digit]);
+ } else {
+ currentTime = parseInt(new Date().getHours().toString().padStart(2, "0")[Digit]);
+ }
+ } else if (type == "min") {
+ currentTime = parseInt(new Date().getMinutes().toString().padStart(2, "0")[Digit]);
+ } else if (type == "sec") {
+ currentTime = parseInt(new Date().getSeconds().toString().padStart(2, "0")[Digit]);
+ }
+
+ if (currentTime == 0) {
+ if (RowsObject.scrollTop != 0) {
+ RowsObject.scrollTop = LastZeroPos * DigitsHeight;
+ setTimeout(() => {
+ RowsObject.scroll({
+ top: 0,
+ behavior: "instant",
+ });
+ }, 500);
+ }
+ } else {
+ RowsObject.scrollTop = currentTime * DigitsHeight;
+ }
+}
diff --git a/src/routes/announcer/+page.svelte b/src/routes/announcer/+page.svelte
new file mode 100644
index 0000000..35064e4
--- /dev/null
+++ b/src/routes/announcer/+page.svelte
@@ -0,0 +1,20 @@
+
+
+
+
+
Most Announced announcements
+
+
+
Or announce something else
+
+
+
+
diff --git a/src/routes/announcer/components/CommonAnounceedTexts/delete.svelte b/src/routes/announcer/components/CommonAnounceedTexts/delete.svelte
new file mode 100644
index 0000000..a8363a1
--- /dev/null
+++ b/src/routes/announcer/components/CommonAnounceedTexts/delete.svelte
@@ -0,0 +1,14 @@
+
+
+ DeleteMostUsedAnnouncement(announcementID)}
+>
+
diff --git a/src/routes/announcer/components/CommonAnounceedTexts/list.svelte b/src/routes/announcer/components/CommonAnounceedTexts/list.svelte
new file mode 100644
index 0000000..01db9c0
--- /dev/null
+++ b/src/routes/announcer/components/CommonAnounceedTexts/list.svelte
@@ -0,0 +1,12 @@
+
+
+{#each MostUsedAnnouncements.v as announcementText, announcementID}
+
+
+
+
+{/each}
diff --git a/src/routes/announcer/components/CommonAnounceedTexts/text.svelte b/src/routes/announcer/components/CommonAnounceedTexts/text.svelte
new file mode 100644
index 0000000..371e9c4
--- /dev/null
+++ b/src/routes/announcer/components/CommonAnounceedTexts/text.svelte
@@ -0,0 +1,13 @@
+
+
+ AnnounceUsingTTS(announcementText)}
+>
+ {announcementText}
+
diff --git a/src/routes/announcer/components/CustomText/CustomText.svelte b/src/routes/announcer/components/CustomText/CustomText.svelte
new file mode 100644
index 0000000..0cde2e9
--- /dev/null
+++ b/src/routes/announcer/components/CustomText/CustomText.svelte
@@ -0,0 +1,9 @@
+
+
+
diff --git a/src/routes/announcer/components/CustomText/add.svelte b/src/routes/announcer/components/CustomText/add.svelte
new file mode 100644
index 0000000..8807c4d
--- /dev/null
+++ b/src/routes/announcer/components/CustomText/add.svelte
@@ -0,0 +1,16 @@
+
+
+{#if CurrentText.v}
+
+ {
+ AddMostUsedAnnouncement(CurrentText.v);
+ CurrentText.v = "";
+ }}>Add "{CurrentText.v}" to "Most Announced announcements"
+
+{/if}
diff --git a/src/routes/announcer/components/CustomText/input.svelte b/src/routes/announcer/components/CustomText/input.svelte
new file mode 100644
index 0000000..b7f9189
--- /dev/null
+++ b/src/routes/announcer/components/CustomText/input.svelte
@@ -0,0 +1,9 @@
+
+
+
diff --git a/src/routes/announcer/components/CustomText/play.svelte b/src/routes/announcer/components/CustomText/play.svelte
new file mode 100644
index 0000000..5bcf593
--- /dev/null
+++ b/src/routes/announcer/components/CustomText/play.svelte
@@ -0,0 +1,11 @@
+
+
+ AnnounceUsingTTS(CurrentText.v)}
+>
+ 📢
diff --git a/src/routes/announcer/logic/AddAndDeleteMostUsedAnnouncements.js b/src/routes/announcer/logic/AddAndDeleteMostUsedAnnouncements.js
new file mode 100644
index 0000000..099014b
--- /dev/null
+++ b/src/routes/announcer/logic/AddAndDeleteMostUsedAnnouncements.js
@@ -0,0 +1,13 @@
+import { MostUsedAnnouncements } from "./announcerData.svelte.js";
+
+export function AddMostUsedAnnouncement(announcementText) {
+ MostUsedAnnouncements.v.push(announcementText);
+ localStorage.setItem("MostUsedAnnouncements", JSON.stringify(MostUsedAnnouncements.v));
+}
+
+export function DeleteMostUsedAnnouncement(announcementID) {
+ if (confirm("Are you sure you want to delete this announcement?")) {
+ MostUsedAnnouncements.v.splice(announcementID, 1);
+ localStorage.setItem("MostUsedAnnouncements", JSON.stringify(MostUsedAnnouncements.v));
+ }
+}
diff --git a/src/routes/announcer/logic/AnnounceUsingTTS.js b/src/routes/announcer/logic/AnnounceUsingTTS.js
new file mode 100644
index 0000000..6927bff
--- /dev/null
+++ b/src/routes/announcer/logic/AnnounceUsingTTS.js
@@ -0,0 +1,7 @@
+export function AnnounceUsingTTS(text) {
+ window.speechSynthesis.speak(
+ Object.assign(new SpeechSynthesisUtterance(text), {
+ rate: 0.5,
+ }),
+ );
+}
\ No newline at end of file
diff --git a/src/routes/announcer/logic/LoadMostUsedAnnouncement.js b/src/routes/announcer/logic/LoadMostUsedAnnouncement.js
new file mode 100644
index 0000000..a9dc3c7
--- /dev/null
+++ b/src/routes/announcer/logic/LoadMostUsedAnnouncement.js
@@ -0,0 +1,12 @@
+import { MostUsedAnnouncements } from "./announcerData.svelte.js";
+
+export function LoadMostUsedAnnouncement() {
+ let TempMostUsedAnnouncements = JSON.parse(localStorage.getItem("MostUsedAnnouncements")) || "";
+
+ if (TempMostUsedAnnouncements == "") {
+ MostUsedAnnouncements.v = ["Please be quiet"];
+ localStorage.setItem("MostUsedAnnouncements", JSON.stringify(MostUsedAnnouncements.v));
+ } else {
+ MostUsedAnnouncements.v = TempMostUsedAnnouncements;
+ }
+}
diff --git a/src/routes/announcer/logic/announcerData.svelte.js b/src/routes/announcer/logic/announcerData.svelte.js
new file mode 100644
index 0000000..74f019e
--- /dev/null
+++ b/src/routes/announcer/logic/announcerData.svelte.js
@@ -0,0 +1,2 @@
+export let CurrentText = $state({ v: "" });
+export let MostUsedAnnouncements = $state({ v: [] });
\ No newline at end of file
diff --git a/src/routes/kahootclone/+page.svelte b/src/routes/kahootclone/+page.svelte
new file mode 100644
index 0000000..e37c4d3
--- /dev/null
+++ b/src/routes/kahootclone/+page.svelte
@@ -0,0 +1,18 @@
+
diff --git a/src/routes/kahootclone/create/+page.svelte b/src/routes/kahootclone/create/+page.svelte
new file mode 100644
index 0000000..06798db
--- /dev/null
+++ b/src/routes/kahootclone/create/+page.svelte
@@ -0,0 +1,28 @@
+
+
+
+
+
+ {#each questions.v as question, index}
+
+ {/each}
+
+
+ {#if Wait.v == false}
+
+ {:else}
+
+ {/if}
+
+
+
diff --git a/src/routes/kahootclone/create/components/Questions/answers.svelte b/src/routes/kahootclone/create/components/Questions/answers.svelte
new file mode 100644
index 0000000..dd8002e
--- /dev/null
+++ b/src/routes/kahootclone/create/components/Questions/answers.svelte
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
diff --git a/src/routes/kahootclone/create/components/Questions/question.svelte b/src/routes/kahootclone/create/components/Questions/question.svelte
new file mode 100644
index 0000000..99bc687
--- /dev/null
+++ b/src/routes/kahootclone/create/components/Questions/question.svelte
@@ -0,0 +1,54 @@
+
+
+
+
+
+
Q{index + 1}.
+
+ {
+ const newLength = questions.v[index].answers.length;
+ const currentAnswers = questions.v[index].answers;
+
+ if (newLength > currentAnswers.length) {
+ // Add more answers
+ while (questions.v[index].answers.length < newLength) {
+ questions.v[index].answers.push("");
+ }
+ } else if (newLength < currentAnswers.length) {
+ // Remove excess answers
+ questions.v[index].answers = currentAnswers.slice(0, newLength);
+ }
+ }}
+ class="h-fit rounded-xl bg-gray-800 p-1 text-center text-white"
+ >
+ Options
+ {#each Array(7) as _, i}
+ {i + 2}
+ {/each}
+
+
+
+
+
+ {#each questions.v[index].answers as _, answersIndex}
+
+ {/each}
+
+
+
+
diff --git a/src/routes/kahootclone/create/components/buttons/DeleteQuestion.svelte b/src/routes/kahootclone/create/components/buttons/DeleteQuestion.svelte
new file mode 100644
index 0000000..7057ea9
--- /dev/null
+++ b/src/routes/kahootclone/create/components/buttons/DeleteQuestion.svelte
@@ -0,0 +1,20 @@
+
+
+ DeleteQuestion(props.index)}
+ class="flex h-fit cursor-pointer items-center justify-center rounded-xl bg-red-700 p-2 transition-all hover:scale-110 hover:-rotate-10"
+ > Delete question
diff --git a/src/routes/kahootclone/create/components/buttons/GenerateOptionsUsingAI.svelte b/src/routes/kahootclone/create/components/buttons/GenerateOptionsUsingAI.svelte
new file mode 100644
index 0000000..b657a8c
--- /dev/null
+++ b/src/routes/kahootclone/create/components/buttons/GenerateOptionsUsingAI.svelte
@@ -0,0 +1,19 @@
+
+
+{#if questions.v[index].answers.every((answer) => answer === "")}
+ {
+ GenerateOptionsUsingAI(index);
+ }}
+ class="mt-1 mb-1 flex h-fit cursor-pointer items-center justify-center gap-2 rounded-xl bg-blue-700 p-2 transition-all hover:scale-110 hover:-rotate-5"
+ >
+
+ Generate Options using AI
+
+{/if}
diff --git a/src/routes/kahootclone/create/components/buttons/GenerateQuetionsUsingAI.svelte b/src/routes/kahootclone/create/components/buttons/GenerateQuetionsUsingAI.svelte
new file mode 100644
index 0000000..8932152
--- /dev/null
+++ b/src/routes/kahootclone/create/components/buttons/GenerateQuetionsUsingAI.svelte
@@ -0,0 +1,14 @@
+
+
+{#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)}
+
+
+ Generate questions using AI
+
+{/if}
diff --git a/src/routes/kahootclone/create/components/buttons/NewQuestion.svelte b/src/routes/kahootclone/create/components/buttons/NewQuestion.svelte
new file mode 100644
index 0000000..63cc2d6
--- /dev/null
+++ b/src/routes/kahootclone/create/components/buttons/NewQuestion.svelte
@@ -0,0 +1,15 @@
+
+
+ AddQuestion()}
+ class="flex h-fit cursor-pointer items-center justify-center rounded-xl bg-green-700 p-2 transition-all hover:scale-110 hover:-rotate-10"
+ > New question
diff --git a/src/routes/kahootclone/create/components/buttons/StartGame.svelte b/src/routes/kahootclone/create/components/buttons/StartGame.svelte
new file mode 100644
index 0000000..10f8d3a
--- /dev/null
+++ b/src/routes/kahootclone/create/components/buttons/StartGame.svelte
@@ -0,0 +1,18 @@
+
+
+ Start Quiz
diff --git a/src/routes/kahootclone/create/components/buttons/UseDemoQuestions.svelte b/src/routes/kahootclone/create/components/buttons/UseDemoQuestions.svelte
new file mode 100644
index 0000000..ead81cd
--- /dev/null
+++ b/src/routes/kahootclone/create/components/buttons/UseDemoQuestions.svelte
@@ -0,0 +1,15 @@
+
+
+ SetQuestionsToDemoQuestions()}
+ class="-mt-5 mb-3 flex h-fit cursor-pointer items-center justify-center rounded-xl bg-green-700 p-2 transition-all hover:scale-110 hover:-rotate-10"
+ > Use demo questions
diff --git a/src/routes/kahootclone/create/components/buttons/WaitStartGame.svelte b/src/routes/kahootclone/create/components/buttons/WaitStartGame.svelte
new file mode 100644
index 0000000..0102b86
--- /dev/null
+++ b/src/routes/kahootclone/create/components/buttons/WaitStartGame.svelte
@@ -0,0 +1,18 @@
+
+
+ Wait for game to be created
diff --git a/src/routes/kahootclone/create/logic/GameCreateData.svelte.js b/src/routes/kahootclone/create/logic/GameCreateData.svelte.js
new file mode 100644
index 0000000..bb61c12
--- /dev/null
+++ b/src/routes/kahootclone/create/logic/GameCreateData.svelte.js
@@ -0,0 +1,36 @@
+import { DefaultQuestions } from "$lib/config.js";
+
+export let Wait = $state({
+ v: false,
+});
+export let questions = $state({
+ v: [
+ {
+ name: "",
+ answers: ["", "", "", ""],
+ correctAnswer: undefined,
+ },
+ ],
+});
+
+export function SetQuestionsToDemoQuestions() {
+ questions.v = DefaultQuestions;
+}
+
+export function AddQuestion() {
+ questions.v.push({
+ name: "",
+ answers: ["", "", "", ""],
+ correctAnswer: undefined,
+ });
+}
+
+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 {
+ alert("You need at least one question.");
+ }
+}
diff --git a/src/routes/kahootclone/create/logic/GenerateOptionsUsingAI.js b/src/routes/kahootclone/create/logic/GenerateOptionsUsingAI.js
new file mode 100644
index 0000000..147561b
--- /dev/null
+++ b/src/routes/kahootclone/create/logic/GenerateOptionsUsingAI.js
@@ -0,0 +1,34 @@
+import { questions } from "./GameCreateData.svelte.js";
+import { AiPrompts } from "$lib/config.js";
+
+export function GenerateOptionsUsingAI(index) {
+ 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,
+ ),
+ },
+ ],
+ }),
+ })
+ .then((response) => response.json())
+ .then((data) => {
+ let question = questions.v[index].name;
+ questions.v[index] = JSON.parse(data.choices[0].message.content);
+ questions.v[index].name = question;
+ })
+ .catch((error) => {
+ alert("Error:" + error);
+ return;
+ });
+
+ alert("added!");
+}
diff --git a/src/routes/kahootclone/create/logic/GenerateQuestionsUsingAI.js b/src/routes/kahootclone/create/logic/GenerateQuestionsUsingAI.js
new file mode 100644
index 0000000..1938d10
--- /dev/null
+++ b/src/routes/kahootclone/create/logic/GenerateQuestionsUsingAI.js
@@ -0,0 +1,38 @@
+import { questions } from "./GameCreateData.svelte.js";
+import { AiPrompts } from "$lib/config.js";
+
+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;
+ }
+
+ 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),
+ },
+ ],
+ }),
+ })
+ .then((response) => response.json())
+ .then((data) => {
+ console.log(data);
+ questions.v = JSON.parse(data.choices[0].message.content);
+ })
+ .catch((error) => {
+ alert("Error:" + error);
+ return;
+ });
+
+ alert("added!");
+}
\ No newline at end of file
diff --git a/src/routes/kahootclone/create/logic/InsertGameInDB.js b/src/routes/kahootclone/create/logic/InsertGameInDB.js
new file mode 100644
index 0000000..39f8d0b
--- /dev/null
+++ b/src/routes/kahootclone/create/logic/InsertGameInDB.js
@@ -0,0 +1,51 @@
+import { supabase } from "$lib/supabase";
+
+export async function createGame(questions, gamePin) {
+ const { data: gameData, error: gameError } = await supabase.from("games").insert({
+ creator: "anonymous",
+ creationdate: new Date().toISOString(),
+ status: "lobby",
+ gamepin: gamePin,
+ });
+
+ if (gameError) {
+ alert("Failed to create game: " + gameError.message + "\n\nPlease try again.");
+ return;
+ }
+
+ // Prepare questions and answers for batch insertion
+ const questionsData = questions.map((q, index) => ({
+ gameid: gamePin,
+ questionstext: q.name,
+ correctanswer: q.correctAnswer,
+ }));
+
+ const { data: questionsResult, error: questionsError } = await supabase
+ .from("questions")
+ .insert(questionsData)
+ .select("id");
+
+ if (questionsError) {
+ alert("Failed to insert questions: " + questionsError.message + "\n\nPlease try again.");
+ return;
+ }
+
+ const answersData = [];
+ questionsResult.forEach((question, index) => {
+ questions[index].answers.forEach((answer, answerIndex) => {
+ answersData.push({
+ questionid: question.id,
+ content: answer,
+ });
+ });
+ });
+
+ const { error: answersError } = await supabase.from("answers").insert(answersData);
+
+ if (answersError) {
+ alert("Failed to insert answers: " + answersError.message + "\n\nPlease try again.");
+ return;
+ }
+
+ window.location.href = `/host?gamepin=${gamePin}` ;
+}
diff --git a/src/routes/kahootclone/create/logic/StartGame.js b/src/routes/kahootclone/create/logic/StartGame.js
new file mode 100644
index 0000000..c7a8456
--- /dev/null
+++ b/src/routes/kahootclone/create/logic/StartGame.js
@@ -0,0 +1,16 @@
+import { createGame } from "./InsertGameInDB.js";
+import { questions,Wait } from "./GameCreateData.svelte.js";
+
+export async function startGame() {
+ if (questions.v.some((q) => q.name === "")) return alert("Please fill all questions");
+ if (questions.v.some((q) => q.answers.some((a) => a === ""))) return alert("Fill all options");
+ if (questions.v.some((q) => q.correctAnswer === undefined))
+ return alert("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/host/+page.svelte b/src/routes/kahootclone/host/+page.svelte
new file mode 100644
index 0000000..2fd96bb
--- /dev/null
+++ b/src/routes/kahootclone/host/+page.svelte
@@ -0,0 +1,30 @@
+
+
+
+
+ {#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..c94ad33
--- /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}
+
+
+
+
+ {answer}
+
+
+ {/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..c2eed42
--- /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..b92f42b
--- /dev/null
+++ b/src/routes/kahootclone/host/components/DuringGame/awnseringQuetions/display.svelte
@@ -0,0 +1,9 @@
+
+
+
+
+
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..8fd3606
--- /dev/null
+++ b/src/routes/kahootclone/host/components/DuringGame/awnseringQuetions/text/Quetion.svelte
@@ -0,0 +1,7 @@
+
+
+
+ Q{currentQuestion.v + 1}. {CurrentQuestionDetails.v.question}
+
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..9952173
--- /dev/null
+++ b/src/routes/kahootclone/host/components/DuringGame/display.svelte
@@ -0,0 +1,8 @@
+
+
+HOSTING
+
+
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 @@
+
+
+ {
+ startGame(props.gamePin);
+ }}>Start the game
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..3cccce9
--- /dev/null
+++ b/src/routes/kahootclone/host/components/lobby/display.svelte
@@ -0,0 +1,15 @@
+
+
+HOSTING
+Game Pin:
+
+ {gamePin}
+
+
+
diff --git a/src/routes/kahootclone/host/logic/GameOver.js b/src/routes/kahootclone/host/logic/GameOver.js
new file mode 100644
index 0000000..48d22cb
--- /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("/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..1eac14a
--- /dev/null
+++ b/src/routes/kahootclone/host/logic/GetCurrentPlayers.js
@@ -0,0 +1,18 @@
+import { supabase } from "$lib/supabase.js";
+import { players } from "./HostsData.svelte.js";
+
+export async function GetCurrentPlayers(gamePin) {
+ const { data, error } = await supabase
+ .from("players")
+ .select("playername")
+ .eq("gameid", Number(gamePin));
+
+ console.log("Current players data:", JSON.stringify(data));
+
+ if (error) {
+ console.error("Error fetching players:", error);
+ 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..f384d09
--- /dev/null
+++ b/src/routes/kahootclone/host/logic/HostsData.svelte.js
@@ -0,0 +1,10 @@
+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: {} });
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..39f6cce
--- /dev/null
+++ b/src/routes/kahootclone/host/logic/WaitForAwnser.js
@@ -0,0 +1,51 @@
+import { supabase } from "$lib/supabase.js";
+import { onNewPlayerAwnsered } from "./onNewPlayerAwnsered.js";
+import { currentQuestion, questions, CurrentQuestionDetails } from "./HostsData.svelte.js";
+
+let WaitingForAwnserConection;
+
+export async function WaitForAwnser(questionid, gamePin) {
+ if (questionid != 0) {
+ await supabase.removeChannel(WaitingForAwnserConection);
+ }
+
+ 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("id,questionstext,correctanswer")
+ .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,
+ };
+}
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..cbc2edc
--- /dev/null
+++ b/src/routes/kahootclone/host/logic/startGame.js
@@ -0,0 +1,41 @@
+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";
+
+export async function startGame(gamePin) {
+ if (players.v.length == 0) {
+ alert("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);
+}
diff --git a/src/routes/kahootclone/join/+page.svelte b/src/routes/kahootclone/join/+page.svelte
new file mode 100644
index 0000000..f92c8b0
--- /dev/null
+++ b/src/routes/kahootclone/join/+page.svelte
@@ -0,0 +1,47 @@
+
+
+
diff --git a/src/routes/kahootclone/join/logic/InsertPlayerInDB.js b/src/routes/kahootclone/join/logic/InsertPlayerInDB.js
new file mode 100644
index 0000000..9c696c7
--- /dev/null
+++ b/src/routes/kahootclone/join/logic/InsertPlayerInDB.js
@@ -0,0 +1,19 @@
+import { supabase } from "$lib/supabase";
+
+export async function addPlayer(name, gamePin) {
+ const { data, error } = await supabase
+ .from("players")
+ .insert({
+ gameid: gamePin,
+ score: 0,
+ playername: name,
+ })
+ .select("id");
+
+ if (error) {
+ alert("Failed to join game: " + error.message + "\n\nPlease try again.");
+ return;
+ }
+
+ return data[0].id;
+}
diff --git a/src/routes/kahootclone/join/logic/JoinGameData.svelte.js b/src/routes/kahootclone/join/logic/JoinGameData.svelte.js
new file mode 100644
index 0000000..2ca2125
--- /dev/null
+++ b/src/routes/kahootclone/join/logic/JoinGameData.svelte.js
@@ -0,0 +1,3 @@
+export let Checking = $state({
+ v: false,
+});
diff --git a/src/routes/kahootclone/join/logic/joinGame.js b/src/routes/kahootclone/join/logic/joinGame.js
new file mode 100644
index 0000000..524f1d2
--- /dev/null
+++ b/src/routes/kahootclone/join/logic/joinGame.js
@@ -0,0 +1,19 @@
+import { addPlayer } from "./InsertPlayerInDB.js";
+import { validateGamePin } from "./validateGamePin.js";
+import { Checking } from "./JoinGameData.svelte.js";
+
+export async function joinGame(pin, name) {
+ Checking.v = true;
+
+ if (!(await validateGamePin(pin))) {
+ alert("Invalid game pin. Please try again.");
+ Checking.v = false;
+ return;
+ }
+
+ let id = await addPlayer(name, pin);
+
+ Checking.v = false;
+
+ window.location.href = `./play?gamepin=${pin}&name=${name}&playerid=${id}`;
+}
diff --git a/src/routes/kahootclone/join/logic/validateGamePin.js b/src/routes/kahootclone/join/logic/validateGamePin.js
new file mode 100644
index 0000000..6801d24
--- /dev/null
+++ b/src/routes/kahootclone/join/logic/validateGamePin.js
@@ -0,0 +1,11 @@
+import { supabase } from '$lib/supabase';
+
+export async function validateGamePin(pin) {
+ const { data, error } = await supabase
+ .from('games')
+ .select('gamepin')
+ .eq('gamepin', Number(pin))
+ .maybeSingle();
+
+ return data !== null && !error;
+}
diff --git a/src/routes/kahootclone/play/+page.svelte b/src/routes/kahootclone/play/+page.svelte
new file mode 100644
index 0000000..0a6054c
--- /dev/null
+++ b/src/routes/kahootclone/play/+page.svelte
@@ -0,0 +1,34 @@
+
+
+
+
+ {#if Status.v == "lobby"}
+
+ {:else if Status.v == "started"}
+
+ {/if}
+
+
diff --git a/src/routes/kahootclone/play/components/awnseringQuetions/Awnsers.svelte b/src/routes/kahootclone/play/components/awnseringQuetions/Awnsers.svelte
new file mode 100644
index 0000000..b9dae3f
--- /dev/null
+++ b/src/routes/kahootclone/play/components/awnseringQuetions/Awnsers.svelte
@@ -0,0 +1,36 @@
+
+
+
+ {#each questions.v.answers as answer, index}
+
+
+
+
+
+ {answer}
+
+
+ {/each}
+
diff --git a/src/routes/kahootclone/play/components/awnseringQuetions/ProgressBar.svelte b/src/routes/kahootclone/play/components/awnseringQuetions/ProgressBar.svelte
new file mode 100644
index 0000000..34de775
--- /dev/null
+++ b/src/routes/kahootclone/play/components/awnseringQuetions/ProgressBar.svelte
@@ -0,0 +1,13 @@
+
+
+
+
Question {CurrentQuestion.v + 1} of {TotalQuestions.v}
+
+
diff --git a/src/routes/kahootclone/play/components/awnseringQuetions/buttons/SelectFirst.svelte b/src/routes/kahootclone/play/components/awnseringQuetions/buttons/SelectFirst.svelte
new file mode 100644
index 0000000..e57ee47
--- /dev/null
+++ b/src/routes/kahootclone/play/components/awnseringQuetions/buttons/SelectFirst.svelte
@@ -0,0 +1,13 @@
+
+
+ Submit
+
+
+ Select an option to submit
+
+
diff --git a/src/routes/kahootclone/play/components/awnseringQuetions/buttons/submitAwnser.svelte b/src/routes/kahootclone/play/components/awnseringQuetions/buttons/submitAwnser.svelte
new file mode 100644
index 0000000..51b1633
--- /dev/null
+++ b/src/routes/kahootclone/play/components/awnseringQuetions/buttons/submitAwnser.svelte
@@ -0,0 +1,9 @@
+
+
+Submit
+
\ No newline at end of file
diff --git a/src/routes/kahootclone/play/components/awnseringQuetions/display.svelte b/src/routes/kahootclone/play/components/awnseringQuetions/display.svelte
new file mode 100644
index 0000000..3b77ab0
--- /dev/null
+++ b/src/routes/kahootclone/play/components/awnseringQuetions/display.svelte
@@ -0,0 +1,28 @@
+
+
+
+
+
+ {#if CurrentQuestion.v != null}
+
+
+ {#if Selected.v != null}
+
+ {:else}
+
+ {/if}
+ {:else}
+
+ {/if}
+
+
diff --git a/src/routes/kahootclone/play/components/awnseringQuetions/text/Quetion.svelte b/src/routes/kahootclone/play/components/awnseringQuetions/text/Quetion.svelte
new file mode 100644
index 0000000..b5d79fa
--- /dev/null
+++ b/src/routes/kahootclone/play/components/awnseringQuetions/text/Quetion.svelte
@@ -0,0 +1,7 @@
+
+
+
+ Q{CurrentQuestion.v + 1}. {questions.v.question}
+
diff --git a/src/routes/kahootclone/play/components/awnseringQuetions/text/wait.svelte b/src/routes/kahootclone/play/components/awnseringQuetions/text/wait.svelte
new file mode 100644
index 0000000..32d5985
--- /dev/null
+++ b/src/routes/kahootclone/play/components/awnseringQuetions/text/wait.svelte
@@ -0,0 +1 @@
+Please wait for everyone else to answer the question.
diff --git a/src/routes/kahootclone/play/components/lobby/PlayersGUI/playerBadge.svelte b/src/routes/kahootclone/play/components/lobby/PlayersGUI/playerBadge.svelte
new file mode 100644
index 0000000..ced3664
--- /dev/null
+++ b/src/routes/kahootclone/play/components/lobby/PlayersGUI/playerBadge.svelte
@@ -0,0 +1,6 @@
+
+
+{playerName}
diff --git a/src/routes/kahootclone/play/components/lobby/PlayersGUI/players.svelte b/src/routes/kahootclone/play/components/lobby/PlayersGUI/players.svelte
new file mode 100644
index 0000000..bcc3e2a
--- /dev/null
+++ b/src/routes/kahootclone/play/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/play/components/lobby/display.svelte b/src/routes/kahootclone/play/components/lobby/display.svelte
new file mode 100644
index 0000000..9dcc0db
--- /dev/null
+++ b/src/routes/kahootclone/play/components/lobby/display.svelte
@@ -0,0 +1,18 @@
+
+
+PLAYING
+
+Waiting for host to start the game
+
+
+
diff --git a/src/routes/kahootclone/play/logic/GetCurrentPlayers.js b/src/routes/kahootclone/play/logic/GetCurrentPlayers.js
new file mode 100644
index 0000000..1eac14a
--- /dev/null
+++ b/src/routes/kahootclone/play/logic/GetCurrentPlayers.js
@@ -0,0 +1,18 @@
+import { supabase } from "$lib/supabase.js";
+import { players } from "./HostsData.svelte.js";
+
+export async function GetCurrentPlayers(gamePin) {
+ const { data, error } = await supabase
+ .from("players")
+ .select("playername")
+ .eq("gameid", Number(gamePin));
+
+ console.log("Current players data:", JSON.stringify(data));
+
+ if (error) {
+ console.error("Error fetching players:", error);
+ return;
+ }
+
+ players.v = data ? data.map(player => player.playername) : [];
+}
diff --git a/src/routes/kahootclone/play/logic/HostsData.svelte.js b/src/routes/kahootclone/play/logic/HostsData.svelte.js
new file mode 100644
index 0000000..d596117
--- /dev/null
+++ b/src/routes/kahootclone/play/logic/HostsData.svelte.js
@@ -0,0 +1,9 @@
+export let players = $state({ v: {} });
+export let Status = $state({ v: "lobby" });
+export let questions = $state({ v: {} });
+export let CurrentQuestion = $state({ v: null });
+export let TotalQuestions = $state({ v: 0 });
+export let Selected = $state({ v: null });
+export let isWait = $state({ v: true });
+export let name = $state({ v: "" });
+export let playerid = $state({ v: null });
diff --git a/src/routes/kahootclone/play/logic/IntializeGameStart.js b/src/routes/kahootclone/play/logic/IntializeGameStart.js
new file mode 100644
index 0000000..cdd12c8
--- /dev/null
+++ b/src/routes/kahootclone/play/logic/IntializeGameStart.js
@@ -0,0 +1,22 @@
+import { supabase } from "$lib/supabase.js";
+import { NewStatus } from "./NewStatus.js";
+
+export async function IntializeGameStart(gamepin) {
+ supabase
+ .channel(`game_status_${gamepin}`)
+ .on(
+ "postgres_changes",
+ {
+ event: "UPDATE",
+ schema: "public",
+ table: "games",
+ filter: `gamepin=eq.${gamepin}`,
+ },
+ (payload) => {
+ if (payload.new.status) {
+ NewStatus(payload.new.status, gamepin);
+ }
+ },
+ )
+ .subscribe();
+}
diff --git a/src/routes/kahootclone/play/logic/NewStatus.js b/src/routes/kahootclone/play/logic/NewStatus.js
new file mode 100644
index 0000000..9dc22d7
--- /dev/null
+++ b/src/routes/kahootclone/play/logic/NewStatus.js
@@ -0,0 +1,44 @@
+import {
+ CurrentQuestion,
+ Status,
+ questions,
+ isWait,
+ Selected,
+ playerid,
+ TotalQuestions,
+} from "./HostsData.svelte.js";
+import { supabase } from "$lib/supabase.js";
+
+export async function NewStatus(NewStatus, gamePin) {
+ if (NewStatus == "completed") {
+ window.location.replace("/results?gamepin" + gamePin + "&playerID=" + playerid.v);
+ return;
+ }
+
+ Status.v = "started";
+ CurrentQuestion.v = Number(NewStatus.replace("question-", ""));
+
+ const { data: questionsData } = await supabase
+ .from("questions")
+ .select("id,questionstext,correctanswer")
+ .eq("gameid", Number(gamePin))
+ .order("id", { ascending: true });
+
+ TotalQuestions.v = questionsData.length;
+
+ const { data: answers } = await supabase
+ .from("answers")
+ .select("content")
+ .eq("questionid", Number(questionsData[CurrentQuestion.v].id))
+ .order("id", { ascending: true });
+
+ questions.v = {
+ question: questionsData[CurrentQuestion.v].questionstext,
+ correctAnswer: questionsData[CurrentQuestion.v].correctanswer,
+ answers: answers.map((answer) => answer.content),
+ questionid: questionsData[CurrentQuestion.v].id,
+ };
+
+ isWait.v = false;
+ Selected.v = null;
+}
diff --git a/src/routes/kahootclone/play/logic/SubmitAnswer.js b/src/routes/kahootclone/play/logic/SubmitAnswer.js
new file mode 100644
index 0000000..add80c2
--- /dev/null
+++ b/src/routes/kahootclone/play/logic/SubmitAnswer.js
@@ -0,0 +1,31 @@
+import { CurrentQuestion, Selected, questions, playerid } from "./HostsData.svelte.js";
+import { supabase } from "$lib/supabase.js";
+
+export async function SubmitAnswer() {
+ CurrentQuestion.v = null;
+
+ if (Selected.v == questions.v.correctAnswer) {
+ await supabase
+ .from("answeredby")
+ .insert([
+ { questionid: questions.v.questionid, nameofanswerer: playerid.v, correct: true },
+ ])
+ .select();
+
+ let { data: score } = await supabase.from("players").select("score").eq("id", playerid.v);
+
+ await supabase
+ .from("players")
+ .update({ score: score[0].score + 1 })
+ .eq("id", playerid.v)
+ .select();
+
+ } else {
+ await supabase
+ .from("answeredby")
+ .insert([
+ { questionid: questions.v.questionid, nameofanswerer: playerid.v, correct: false },
+ ])
+ .select();
+ }
+}
diff --git a/src/routes/kahootclone/play/logic/UpdatePlayersList.js b/src/routes/kahootclone/play/logic/UpdatePlayersList.js
new file mode 100644
index 0000000..757ca4b
--- /dev/null
+++ b/src/routes/kahootclone/play/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/play/logic/startGame.js b/src/routes/kahootclone/play/logic/startGame.js
new file mode 100644
index 0000000..74e752f
--- /dev/null
+++ b/src/routes/kahootclone/play/logic/startGame.js
@@ -0,0 +1,23 @@
+import { supabase } from "$lib/supabase.js";
+import { LobbyConnection } from "./UpdatePlayersList.js";
+import { questions, Status, CurrentQuestion, TotalQuestions } from "./HostsData.svelte.js";
+
+export async function startGame(gamePin) {
+ await supabase.removeChannel(LobbyConnection);
+
+ Status.v = "started";
+
+ const { data } = await supabase
+ .from("questions")
+ .select("*")
+ .eq("gameid", Number(gamePin))
+ .order("id", { ascending: true });
+ TotalQuestions.v = data.length;
+
+ CurrentQuestion.v = 0;
+
+ await supabase
+ .from("games")
+ .update({ status: `question-${CurrentQuestion.v}` })
+ .eq("gamepin", gamePin);
+}
diff --git a/src/routes/kahootclone/results/+page.svelte b/src/routes/kahootclone/results/+page.svelte
new file mode 100644
index 0000000..a1e9253
--- /dev/null
+++ b/src/routes/kahootclone/results/+page.svelte
@@ -0,0 +1,82 @@
+
+
+
+
+
Leaderboard
+
+ {#each players as player, i}
+ {#if player.id == playerID}
+
+
+ {i + 1}
+
+
+
{player.playername}
+
+
+
+
{player.score} points
+
+ {:else}
+
+
+ {i + 1}
+
+
+
{player.playername}
+
+
+
+
{player.score} points
+
+ {/if}
+ {/each}
+
+
+ Go back to the home page!
+
+
+
diff --git a/src/RandomName/main.svelte b/src/routes/randomname/+page.svelte
similarity index 97%
rename from src/RandomName/main.svelte
rename to src/routes/randomname/+page.svelte
index cbee3fd..7f778c9 100644
--- a/src/RandomName/main.svelte
+++ b/src/routes/randomname/+page.svelte
@@ -2,7 +2,7 @@
import Selector from "./selector.svelte";
import TopDisplay from "./TopDisplay.svelte";
import EditNameOfStudents from "./EditNameOfStudents.svelte";
- import {ShowAlert} from "../app.svelte";
+ //import {ShowAlert} from "../+page.svelte";
export let RandomNamesState = $state({
NotSelectedYet: [],
@@ -25,7 +25,7 @@
];
RandomNamesState.NotSelectedYet.splice(randomIndex, 1);
} else {
- ShowAlert("All students have been selected.", "warning");
+ //ShowAlert("All students have been selected.", "warning");
}
}
@@ -57,7 +57,7 @@