Publication de la nouvelle branche au propre. Reste à tester.

This commit is contained in:
batche
2022-11-21 17:19:10 +01:00
parent 6412bfe1ce
commit 711a75e88d
69 changed files with 8669 additions and 644 deletions

View File

@@ -1,49 +1,36 @@
<script>
import Login from "./pages/auth/login.svelte";
import Home from "./pages/home/home.svelte";
import Router, {link, push} from 'svelte-spa-router';
import Profil from "./pages/profil/profil.svelte";
import UpdateProfil from "./pages/profil/updateProfil.svelte";
import DoubleFa from "./pages/auth/DoubleFa.svelte";
<script lang="ts">
// routing
// may not need {link} here
import Router, { link } from "svelte-spa-router";
import { primaryRoutes } from "./routes/primaryRoutes.js";
// this page should handle the SPA history management...
// set to false later for actual security
// let loggedIn = true;
// $: logout = async() => {
// await fetch("http://transcendance:8080/api/v2/auth/logout",{
// method : 'POST',
// }).then(push('/login'));
// }
const routes = {
"/": Home,
"/login": Login,
"/profil": Profil,
"/update-profil": UpdateProfil,
"/2fa": DoubleFa,
};
$: logout = async() => {
await fetch("http://transcendance:8080/api/v2/auth/logout",{
method : 'POST',
}).then(push('/login'));
}
</script>
<header class="p-3 text-bg-dark">
<div class="container">
<div
class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<!-- <h1>Testing</h1> -->
<Router routes={primaryRoutes} />
<style>
/* doesn't work... */
/* body{
background: bisque;
} */
</style>
<ul class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0">
<li>
<a href="/" type="button" class="btn btn-primary">Home</a>
</li>
<!-- <li>
<a href="/profil" use:link type="button" class="btn btn-primary">Profil</a>
</li> -->
</ul>
<div>
<button on:click={logout} class="w-100 btn btn-lg btn-primary" type="submit">
Deconnexion
</button>
</div>
<div class="text-end">
<a href="/login" use:link type="button" class="btn btn-warning">Connexion</a>
</div>
</div>
</div>
</header>
<Router {routes} />

View File

@@ -0,0 +1,17 @@
<script>
import { link } from "svelte-spa-router";
</script>
<h1>We are sorry!</h1>
<p>This isn't a url that we use.</p>
<!-- <img src="https://picsum.photos/id/685/800/400" alt="img"> -->
<p>Go home you're drunk.</p>
<a href="/" use:link>
<h2>Take me home →</h2>
</a>
<style>
/* img {
width: 100%;
} */
</style>

View File

@@ -0,0 +1,97 @@
<script lang="ts">
import {location} from 'svelte-spa-router';
// this could be how i
// this is how you access /:first for example
// export let params = {}
// <p>Your name is: <b>{params.first}</b> <b>{#if params.last}{params.last}{/if}</b></p>
// If i export these vars, maybe as an nice tidy object, i could pass whatever i like to them
// The current user, some other user, whatever, and thus reuse this Componente for the user and their friends or whatever
// will have to coordinate with Back, will know more once the Game stats are in the back
// wait maybe this won't work, cuz like it's still going through a route, i would have to update a Store Var each time...
// not sure if that's what i want...
// All the variables that will eventually be replaced by the real values
let username = 'Username';
let games = { total: 7, won: 4, lost: 3};
let rank = 'gold or whatever the fuck who cares...';
export const user = {
username: 'chaboi',
}
// maybe the rank is determined dynamically just in the front based on win loss ratio or something no one cares about
// why bother storing that shit in the back...
// maybe i need a Rank.svelte component
// ohhh i could make above a certain rank glitter! like that CSS tutorial showed me!
</script>
<!-- i don't think i need a div around this anymore, do i? -->
<main>
<!-- what the fuck do we even want in here? messges, about the user, STATISTICS!!! -->
<!-- <div>some stuff goes here</div> -->
<img class="icon" src="img/default_user_icon.png" alt="default user icon">
<div>{username}</div>
<div>Rank: {rank}</div>
<section class="main-stats">
<h4>Match Statistics</h4>
<p>Total: {games.total}</p>
<p>Victories: {games.won}</p>
<p>Losses: {games.lost}</p>
</section>
</main>
<style>
/* very clearly redo all this */
div.main-grid{
display: grid;
grid-template-columns: repeat(12, 1fr);
/* max-height: calc(100vh - 30vh); */
height: 85vh;
}
section.sidebar{
grid-column: 1 / span 2;
background: white;
}
/* The main part */
main{
max-width: 960px;
margin: 40px auto;
text-align: center;
}
main.offset{
grid-column: 3 / span 10;
}
/* Normal CSS stuff */
.icon{
max-width: 150px;
}
/* The variable rich section */
section.main-stats{
max-width: 600px;
margin: 40px auto;
text-align: center;
/* i think i want to use a grid? */
display: grid;
grid-template-columns: repeat(3, 1fr);
/* not sure about this, maybe top should be larger? */
grid-template-rows: repeat(3, 1fr);
}
/* the stuff in the grid*/
section.main-stats h4{
grid-column: 1 / span 3;
}
</style>

View File

@@ -0,0 +1,48 @@
<script lang="ts">
// import { loginStatus } from "./stores/loginStatusStore.js";
import Header from "./components/Header.svelte";
import Footer from "./components/Footer.svelte";
// import { createEventDispatcher } from "svelte";
import { push } from "svelte-spa-router";
import Router, { link } from "svelte-spa-router";
import { profileRoutes, prefix } from "./routes/profileRoutes.js";
// let dispatch = createEventDispatcher();
</script>
<!-- remove ={clickedHome} if you want to forward the event to App.svelte-->
<Header />
<!-- The Wave -->
<!-- <div class="spacer layer1"></div> -->
<Router routes={profileRoutes} {prefix} />
<!-- <Footer /> -->
<style>
/* from Haikei */
/* for any Haikei image */
/* .spacer{
aspect-ratio: 900/300;
width: 100%;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
} */
/* the specific image we use, you need both classes */
/* .layer1{
background-image: url('/img/wave-haikei.svg');
} */
</style>

View File

@@ -0,0 +1,14 @@
<script lang="ts">
</script>
<h1>this is settings</h1>
<style>
</style>

View File

@@ -0,0 +1,190 @@
<script lang="ts">
import Canvas from "./components/Canvas.svelte";
import { createEventDispatcher } from "svelte";
import { push } from "svelte-spa-router";
// import axios from 'axios';
import { onMount } from 'svelte';
import { loginStatus } from './stores/loginStatusStore.js';
import { onDestroy } from 'svelte';
let dispatch = createEventDispatcher();
onMount(async () => {
// console.log('PROFIL SVELTE');
console.log('SplashPage testing if logged in')
// const {data} = await axios.get('http://transcendance:8080/api/v2/user');
// if (data) {
// $loginStatus = true;
// push('/user');
// }
});
const login = () => {
// document.body.scrollIntoView();
// push
window.location.href = 'http://transcendance:8080/api/v2/auth';
// await fetch ('http://transcendance:8080/api/v2/auth');
console.log('you are now logged in');
push('/profile');
// it doesn't wait before changing the page tho which is really annoying... maybe the backend needs to be updated idk
// cuz rn i'm doing it in the front and that doesn't seem great...
}
const logout = async() => {
await fetch('http://transcendance:8080/api/v2/auth/logout',);
$loginStatus = false;
};
</script>
<header class="grid-container">
<!-- <div on:mouseenter={enter} on:mouseleave={leave} class:active > -->
<h1>Potato Pong</h1>
<!-- </div> -->
<nav>
<!-- placeholder links -->
<a href="/">Somewhere</a>
<!-- <a href="/">SomewhereElse</a> -->
{#if $loginStatus == false}
<div on:click={login}>Login {$loginStatus}</div>
{:else}
<div on:click={logout}>Logout {$loginStatus}</div>
{/if}
<!-- one of these will be login and it will scroll you down to the login part -->
</nav>
<h2>
<div>Welcome to</div>
<div>Potato Pong</div>
</h2>
<!-- here i want a flashing arrow pointing down to the login part -->
</header>
<!-- <Canvas class=".canvas2"/> -->
<Canvas/>
<style>
/* currently useless */
/* No styles get applied to the canvas from here, maybe i should move them to the Canvas Component... */
/* tho tbh, why bother, i'm gonna change it anyway... */
.canvas{
/* grid-column: 1 / 13;
grid-row: 1 / 3; */
/* don't rely on Z-Index!!!! */
z-index: -1;
position: relative;
width: 100%;
height: 100%;
white-space: nowrap;
/* Tmp? */
/* background-color: #666; */
/* somehow this got rid of they annoying white space under the canvas */
padding-bottom: 0;
margin-bottom: 0px;
overflow: hidden;
}
.canvas2{
z-index: -1;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
white-space: nowrap;
/* Tmp? */
/* background-color: #666; */
/* somehow this got rid of they annoying white space under the canvas */
padding-bottom: 0;
margin-bottom: 0px;
overflow: hidden;
}
/* .canvas .grid-container{ */
.grid-container{
position: absolute;
left: 0;
top: 0;
box-sizing: border-box;
width: 100%;
height: 100%;
white-space: nowrap;
/* padding-bottom: 0; */
margin-bottom: 0px;
overflow: hidden;
padding: 20px 40px;
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 1fr 1fr 1fr 1fr 1fr;
align-items: center;
}
header h1, header nav a{
/* tmp ? well i kinda like it */
color: bisque;
}
header h1{
grid-column: 1 / 7;
grid-row: 1;
/* grid-column: span 6; */
/* tmp? */
padding: 20px;
border: 1px solid bisque;
}
header nav{
/* make it a flexbox? */
grid-column: 7 / 13;
grid-row: 1;
justify-self: end;
/* tmp? */
padding: 20px;
border: 1px solid bisque;
}
header nav a{
margin-left: 10px;
text-decoration: none;
}
/* testing */
header nav a:hover{
font-weight: bold;
background-color: blue;
}
header h2:hover{
background: blue;
}
header h2{
grid-row: 3;
grid-column: 5 / span 4;
justify-self: center;
/* tmp */
border: 1px solid black;
z-index: 3;
}
header h2 div{
font-size: 2em;
}
/* tmp prolly */
nav div {
display: inline;
color: bisque;
font-weight: bold;
}
</style>

View File

@@ -0,0 +1,12 @@
<script>
import { onMount } from "svelte";
onMount( () => console.log('in TMP TEST'))
</script>
<h1>TMP TEST</h1>

View File

@@ -0,0 +1,112 @@
<script lang="ts">
import { onMount } from 'svelte';
// rename to PotatoCanvas?
let canvas;
// let img;
let loaded = false;
// i feel like they told me not to do this, new Image(), isn't there another way?
// never mind they do seem to do this shit...
// no idea if this should be in onMount...
const img = new Image();
img.src = 'img/potato_logo.png';
img.onload = () => {
loaded = true;
// not sure if i'll use this...
}
// $: scaleRatio = window.innerWidth / 10;
$: scaleRatio = 30;
$: nPotoatoRows = Math.floor(window.innerHeight / 200);
$: nPotoatoCols = Math.floor(window.innerWidth / 200);
// $: spacing = (canvas.height - (img.height / scaleRatio * (nPotoatoRows - 1) )) / nPotoatoRows;
// apparently i might need to move all my reactive statements outside the onMount... not sure why...
onMount(() => {
// in this on mount we will set the canvas and the img
const ctx = canvas.getContext('2d');
// let frame = requestAnimationFrame(loop);
ctx.width = window.innerWidth;
ctx.height = window.innerHeight;
// console.log(nPotoatoCols);
// img = fetch('img/potato_logo.png');
// Moving the IMG stuff from her out of mount
// let nPotoatoRows = 4;
// $: nPotoatoRows = Math.floor(canvas.height / 200);
let spacing = (canvas.height - (img.height / scaleRatio * (nPotoatoRows - 1) )) / nPotoatoRows;
// $: spacing = (canvas.height - (img.height / scaleRatio * (nPotoatoRows - 1) )) / nPotoatoRows;
// i prolly need a number of potatos X and Y vars
// i could do it so there are more potatos than can fit on the screen, translate them over, and then after some point
// shift them all back to the next position they would be in, so it looks like they keep going to infinity
// let dx = 1.5;
let dx = 1;
// let dy = -0.5;
let dy = -1;
// let startX = spacing;
// let startY = spacing;
// let startX = 0;
// let startY = 0;
let startX = -(spacing * 2.5);
let startY = -(spacing * 2.5);
let x = startX;
let y = startY;
let frame = requestAnimationFrame(loop);
// i don't think i need t...
function loop(t) {
// yea ok a loop in a loop in a loop, horrible idea...
ctx.clearRect(0, 0, canvas.width, canvas.height);
// this has to be at the end, no?
frame = requestAnimationFrame(loop);
// if (x > 900) {
// x = startX;
// y = startY;
// }
// else {
// x += dx;
// y += dy;
// }
for (let i = 0; i < 20; i++) {
for (let j = 0; j < 10; j++) {
// ctx.drawImage(img, x + (i * spacing * 2), y + (j * spacing), img.width / scaleRatio, img.height / scaleRatio);
ctx.drawImage(img, x + (i * spacing), y + (j * spacing), img.width / scaleRatio, img.height / scaleRatio);
}
}
}
return () => {
cancelAnimationFrame(frame);
};
});
</script>
<canvas
bind:this={canvas}
width={window.innerWidth}
height={window.innerHeight}
></canvas>
<style>
canvas {
width: 100%;
height: 100%;
background-color: #666;
}
</style>

View File

@@ -0,0 +1,18 @@
<footer>
<div class="copyright">I am official I have a Copyright in 2022</div>
</footer>
<style>
footer{
padding: 40px;
padding-bottom: 10px;
text-align: center;
}
.copyright{
color: #aaa;
font-size: 14px;
display: inline-block;
padding: 20px;
border-top: 1px solid #ddd;
}
</style>

View File

@@ -0,0 +1,124 @@
<script lang="ts">
// import { primaryRoutes } from "../routes.js";
import { push } from "svelte-spa-router";
import { loginStatus } from "../stores/loginStatusStore.js";
import {location} from 'svelte-spa-router';
// this could be how i change the header based on which Route it's in
import active from 'svelte-spa-router/active'
// or i could leave them all and not display if they're active?
// import { createEventDispatcher } from 'svelte';
// let dispatch = createEventDispatcher();
let handleClickHome = () => {
// dispatch('clickedHome');
// profile?
push('/profile');
};
let handleClickLogout = () => {
// dispatch('clickedLogout');
fetch ('http://transcendance:8080/api/v2/auth/logout');
push('/');
$loginStatus = false;
};
</script>
<!-- What if i could query what the current URL is and based on that change the button names in the NAV! -->
<header>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<img src="/img/potato_logo.png" alt="Potato Pong Logo" on:click={handleClickHome}>
<!-- {#if currentType === 'home'} -->
<h1>Potato Pong</h1>
<!-- {/if} -->
<nav>
<!-- <a href=""></a> -->
<!-- i might change these to links rather than buttons, i kinda hate the buttons -->
<!-- maybe just p or div actually idk -->
<!-- {#if userpage === 'display'} -->
<button>My Stats</button>
<!-- {:else if userpage === 'settings'} -->
<!-- {:else} -->
<!-- button idk something about -->
<button>Stream</button>
<button on:click={handleClickLogout}>Log Out</button>
</nav>
</header>
<style>
/* See "possible_fonts.css" for more font options... */
@font-face {
font-family: 'Bondi';
src:url('/fonts/Bondi.ttf.woff') format('woff'),
url('/fonts/Bondi.ttf.svg#Bondi') format('svg'),
url('/fonts/Bondi.ttf.eot'),
url('/fonts/Bondi.ttf.eot?#iefix') format('embedded-opentype');
font-weight: normal;
font-style: normal;
}
/* There is a bunch of unncessary shit in here... why so many flex grids, why is everything the same class? just seemed easier but... */
header{
/* background: #f7f7f7; */
background: #618174;
/* padding: 20px; */
margin: 0;
/* does nothing so far... */
/* display: flex; */
}
header{
/* for some reason this doesn't do shit! */
position: sticky;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
/* Headers */
h1{
font-family: 'Bondi';
}
h1{
margin: 0;
text-align: left;
/* max-width: 40px; */
/* this helped with the weird extra space under the image... */
display: flex;
justify-self: center;
align-self: center;
}
/* Images */
img{
cursor: pointer;
max-width: 40px;
padding: 7px 20px;
justify-self: left;
}
nav{
display: flex;
justify-content: right;
}
nav button{
margin: 7px 20px;
/* padding: 5px; */
border-radius: 4px;
}
/* .none{
} */
</style>

View File

@@ -7,4 +7,4 @@ const app = new App({
}
});
export default app;
export default app;

View File

@@ -0,0 +1,81 @@
<script lang="ts">
// routing
// may not need {link} here
import Router, { link } from "svelte-spa-router";
import { routes } from "../routes.js";
import LoginPage from "./LoginPage.svelte";
import UserPage from "../UserPage.svelte";
import NotFound from "../NotFound.svelte";
// Ideally fuck all this shit in the long run
let pages = ['login', 'user', 'account'];
// make this a $: currentPage ?
let currentPage = 'booba';
// prolly change this? yea idk...
// let userIndex;
// tmp for testing
let userId = 0;
// horrible naming... can be HOME or ACCOUNT
let currentType = 'account';
// this page should handle the SPA history management...
// set to false later for actual security
let loggedIn = true;
// not sure if this is how i want to do this...
// might do differently cuz URL route manangement...
const handleLogin = () => {
currentPage = 'user';
loggedIn = true;
};
// I don't know if i should but i'm tempted to put this here...
// import axios from 'axios';
// import { onMount } from 'svelte';
// import { push } from 'svelte-spa-router';
// let user = {logedIn: false};
// onMount(async () => {
// // console.log('PROFIL SVELTE');
// const {data} = await axios.get('http://transcendance:8080/api/v2/user');
// if (data)
// user.logedIn = true;
// });
// $: submit = async() => {
// window.location.href = 'http://transcendance:8080/api/v2/auth';
// }
// $: logout = async() => {
// await fetch('http://transcendance:8080/api/v2/auth/logout',);
// user.logedIn = false;
// }
</script>
<!-- eventually we will do this with routes, but for now use a prop -->
<!-- {#if currentPage === 'login'}
<LoginPage {pages} {currentPage} {userId} on:loggedIn={handleLogin}/>
{:else if currentPage === 'user'}
<UserPage {pages} {currentPage} {userId} {currentType}/>
{:else}
<NotFound />
{/if} -->
<Router {routes}/>
<style>
/* doesn't work... */
/* body{
background: bisque;
} */
</style>

View File

@@ -0,0 +1,167 @@
<!-- <script lang="ts"> -->
<script>
import { onMount } from 'svelte';
let canvas;
// $: scaleRatio = window.innerWidth / 10;
$: scaleRatio = 30;
onMount(() => {
// we're invoking JS methods of the canvas element
const ctx = canvas.getContext('2d');
ctx.width = window.innerWidth;
ctx.height = window.innerHeight;
// ctx.beginPath();
// ctx.moveTo(50,50);
// ctx.lineTo(70,70);
// ctx.stroke();
// attempting to import an image
const img = new Image();
// we may have to call an onMount or something to make sure the image has loaded...
// doing it in JS for now, ideally in Svelte later..
// img.addEventListener('load', () => {
// // execute drawImage statements here
// }, false);
img.src = 'img/potato_logo.png'; // seems like this does need to be above onload()
img.onload = () => {
// ctx.drawImage(img, 0, 0, img.width * (ctx.width / 15), img.height * (ctx.height / 15));
// ctx.drawImage(img, 0, 0, ctx.width / 15, ctx.height / 15);
// i think i don't want this cuz it'll get in the way?
// ctx.drawImage(img, 0, 0, img.width / scaleRatio, img.height / scaleRatio);
// it would seem you need to redraw the images when you change the Window size, it's not automatically responsive
};
let startX = 200;
let startY = 200;
let dx = 3;
let dy = -1;
// Time for some math
// lets say i want 6 rows
// ok so we're gonna draw all the potatos at the same time and each of them gets animated, like i have it now
// 6 in a row so # of rows aka x = width * 6/height
function Potato(x, y) {
this.x = x;
this.y = y;
// ctx.drawImage(img, x, y, img.width / scaleRatio, img.height / scaleRatio);
this.draw = function() {
ctx.drawImage(img, x, y, img.width / scaleRatio, img.height / scaleRatio);
}
this.animate = function() {
this.x += dx;
this.y += dy;
this.draw();
}
}
// let spacing = canvas.width * ((6 + 1) / canvas.height);
let spacing = 70;
let Potatos = [];
//check the math...
// for (let i = 0; i < 6 * spacing; i++) {
for (let i = 0; i < 2; i++) {
// for (let j = 0; j < 6; j++) {
for (let j = 0; i < 2; j++) {
Potatos.push(new Potato(spacing + (i * spacing), spacing + (j * spacing)));
}
}
// now i'm trying to move 1 potato
let frame = requestAnimationFrame(loop);
// function loop(t) {
// ctx.clearRect(0, 0, canvas.width, canvas.height);
// frame = requestAnimationFrame(loop);
// ctx.drawImage(img, startX, startY, img.width / scaleRatio, img.height / scaleRatio);
// startX += dx;
// startY += dy;
// }
// new Potato(70, 70).animate();
function loop(t) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
frame = requestAnimationFrame(loop);
for (let i = 0; i < Potatos.length; i++) {
Potatos[i].animate();
}
// Potatos[0].animate();
}
loop();
// Lets try again with a single loop
// THis shit makes the cool Gradient
// let frame = requestAnimationFrame(loop);
// function loop(t) {
// frame = requestAnimationFrame(loop);
// // const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
// for (let p = 0; p < imageData.data.length; p += 4) {
// const i = p / 4;
// const x = i % canvas.width;
// const y = i / canvas.width >>> 0;
// const r = 64 + (128 * x / canvas.width) + (64 * Math.sin(t / 1000));
// const g = 64 + (128 * y / canvas.height) + (64 * Math.cos(t / 1000));
// const b = 128;
// imageData.data[p + 0] = r;
// imageData.data[p + 1] = g;
// imageData.data[p + 2] = b;
// imageData.data[p + 3] = 255;
// }
// ctx.putImageData(imageData, 0, 0);
// }
return () => {
cancelAnimationFrame(frame);
// prolly something else...
};
});
</script>
<canvas
bind:this={canvas}
width={window.innerWidth}
height={window.innerHeight}
></canvas>
<!-- widht and height were 32, trying stuff -->
<!-- I don't have the /svelte-logo-mask.svg, i guess i'll go get something -->
<style>
canvas {
width: 100%;
height: 100%;
background-color: #666;
/* testing something */
/* -webkit-mask-image: radial-gradient(circle, black 50%, rgba(0, 0, 0, 0.5) 50%);
mask-image: radial-gradient(circle, black 50%, rgba(0, 0, 0, 0.5) 50%); */
/* Holy shit that worked! i got a mask */
/* it also works without a mask! i have a canvas! */
/* -webkit-mask: url(/svelte-logo-mask.svg) 50% 50% no-repeat; */
/* -webkit-mask: url(img/cartoon_potato3.jpg) 50% 50% no-repeat; */
/* mask: url(/svelte-logo-mask.svg) 50% 50% no-repeat; */
/* mask: url(img/cartoon_potato3.jpg) 50% 50% no-repeat; */
}
</style>

View File

@@ -0,0 +1,45 @@
<script lang="ts">
import { onMount, setContext } from "svelte";
let canvas;
// what do i want?
// lets start with an image of my potato
// then get it to move
// then have many displayed in an offset grid
const drawFunctions = [];
setContext('canvas', {
register(drawFn) {
drawFunctions.push(drawFn);
},
unregister(drawFn) {
drawFunctions.splice(drawFunctions.indexOf(drawFn), 1);
}
})
onMount(() => {
// not sure what this does...
const ctx = canvas.getContext('2d');
// no idea what this does...
function update() {
ctx.clearRect()
drawFunctions.forEach(drawFn => {
drawFn(ctx);
});
frameId = requestAnimationFrame(update);
}
let frameId = requestAnimationFrame(update);
return () => {
cancelAnimationFrame(update);
};
});
</script>
<canvas bind:this={canvas} />

View File

@@ -0,0 +1,24 @@
<script lang="ts">
// might rename...
// no idea what i'm doing...
import { getContext, onMount } from 'svelte';
// here you have to export the vars you need to draw this shit...
const { register, unregister } = getContext('canvas');
onMount(() => {
register(draw);
return () => {
unregister(draw);
}
});
function draw(ctx) {
ctx.beginPath();
ctx.fillStyle = fill;
}
</script>

View File

@@ -0,0 +1,124 @@
<script lang="ts">
// Fucking having a header that can change size, i don't really want the larger one
import { createEventDispatcher } from 'svelte';
let dispatch = createEventDispatcher();
let types: string[] = ['home', 'regular', 'none'];
// let currentType: string = 'regular';
export let currentType = 'regular';
// apparently Regular is the only one i use...
let handleClickHome = () => {
dispatch('clickedHome');
};
let handleClickLogout = () => {
dispatch('clickedLogout');
};
</script>
<!-- Make it so you can have a Big Home page header and a regular header or no header -->
<!-- So far my CSS is super Gross, i guess i'll get Hugo to help me with it -->
<header class={currentType}>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<img class={currentType} src="/img/potato_logo.png" alt="Potato Pong Logo" on:click={handleClickHome}>
<!-- {#if currentType === 'home'} -->
<h1 class={currentType}>Potato Pong</h1>
<!-- {/if} -->
<nav class={currentType}>
<!-- <a href=""></a> -->
<!-- i might change these to links rather than buttons, i kinda hate the buttons -->
<button>My Stats</button>
<button>Stream</button>
<button on:click={handleClickLogout}>Log Out</button>
</nav>
</header>
<style>
/* See "possible_fonts.css" for more font options... */
@font-face {
font-family: 'Bondi';
src:url('/fonts/Bondi.ttf.woff') format('woff'),
url('/fonts/Bondi.ttf.svg#Bondi') format('svg'),
url('/fonts/Bondi.ttf.eot'),
url('/fonts/Bondi.ttf.eot?#iefix') format('embedded-opentype');
font-weight: normal;
font-style: normal;
}
/* There is a bunch of unncessary shit in here... why so many flex grids, why is everything the same class? just seemed easier but... */
header{
/* background: #f7f7f7; */
background: #618174;
/* padding: 20px; */
margin: 0;
/* does nothing so far... */
/* display: flex; */
}
header.home{
/* position: sticky; */
}
header.regular{
/* for some reason this doesn't do shit! */
position: sticky;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
/* Headers */
h1{
font-family: 'Bondi';
}
h1.home {
margin: 0;
text-align: center;
/* max-width: 100px; */
}
h1.regular{
margin: 0;
text-align: left;
/* max-width: 40px; */
/* this helped with the weird extra space under the image... */
display: flex;
justify-self: center;
align-self: center;
}
/* Images */
img.home{
/* text-align: center; */
/* get the image squarely in the middle... */
cursor: pointer;
max-width: 100px;
}
img.regular{
cursor: pointer;
max-width: 40px;
padding: 7px 20px;
justify-self: left;
}
nav{
display: flex;
justify-content: right;
}
nav button{
margin: 7px 20px;
/* padding: 5px; */
border-radius: 4px;
}
/* .none{
} */
</style>

View File

@@ -0,0 +1,102 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
let dispatch = createEventDispatcher();
let types: string[] = ['home', 'regular', 'none'];
// let currentType: string = 'regular';
export let currentType = 'home';
let handleClick = () => {
dispatch('clickedHome');
};
</script>
<!-- Make it so you can have a Big Home page header and a regular header or no header -->
<!-- So far my CSS is super Gross, i guess i'll get Hugo to help me with it -->
<header class={currentType}>
<h1 class={currentType}>
<img class={currentType} src="/img/potato_logo.png" alt="Potato Pong Logo" on:click={handleClick}>
</h1>
<!-- {#if currentType === 'home'} -->
<h1 class={currentType}>Potato Pong</h1>
<!-- {/if} -->
</header>
<style>
/* See "possible_fonts.css" for more font options... */
@font-face {
font-family: 'Bondi';
src:url('/fonts/Bondi.ttf.woff') format('woff'),
url('/fonts/Bondi.ttf.svg#Bondi') format('svg'),
url('/fonts/Bondi.ttf.eot'),
url('/fonts/Bondi.ttf.eot?#iefix') format('embedded-opentype');
font-weight: normal;
font-style: normal;
}
/* There is a bunch of unncessary shit in here... why so many flex grids, why is everything the same class? just seemed easier but... */
header{
/* background: #f7f7f7; */
background: #618174;
/* padding: 20px; */
margin: 0;
font-family: 'Bondi';
/* does nothing so far... */
/* display: flex; */
}
header.home{
/* position: sticky; */
}
header.regular{
position: sticky;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
header.regular > h1:first-child{
justify-self: left;
}
header.regular > h1:nth-child(2){
justify-items: center;
}
/* Headers */
h1.home {
margin: 0;
text-align: center;
/* max-width: 100px; */
}
h1.regular{
margin: 0;
text-align: left;
/* max-width: 40px; */
/* this helped with the weird extra space under the image... */
display: flex;
justify-self: center;
align-self: center;
}
/* Images */
h1 img.home{
/* text-align: center; */
/* get the image squarely in the middle... */
cursor: pointer;
max-width: 100px;
}
h1 img.regular{
cursor: pointer;
max-width: 40px;
padding: 7px 15px;
}
/* .none{
} */
</style>

View File

@@ -0,0 +1,172 @@
<script lang="ts">
// Now called LoginPage
// import Header from "./Header.svelte";
import Footer from "../components/Footer.svelte";
import Login from "./Login.svelte";
import Tabs from "../shared/Tabs.svelte"
import Card from "../shared/Card.svelte"
// tmp
let login = { username: '', password: ''};
// let's us track any errors in a submited form
let errors = { username: '', password: ''};
let valid:boolean = false;
const loginHandler = () => {
console.log('hi');
};
const createAccountHandler = () => {
console.log('hi');
};
// Tabs
let items: string[] = ['Login', 'Create Account'];
let activeItem: string = 'Login';
const tabChange = (e) => {
activeItem = e.detail;
};
// TMP for switching page, down the line this will be down by modifying url
</script>
<!-- New New Approach -->
<!-- if i were to do all this with CSS Grids how would i do it? -->
<!-- Things i want -->
<!-- A title button, some nav buttons, a giant dope canvas and words over it -->
<!-- not sure if i want: login and create account -->
<!-- let's start with just the canvas -->
<!-- New aproach -->
<!-- just make the html in order you can move it around all you want into special Compoenents later -->
<!-- Ok i think all of this needs to go in a Home Page Component -->
<!-- and then i make another master component for the main page once you're logged in, no idea what that should look like -->
<!-- what if i kept the special canvas header in here and made another generic header for the rest of the site as a component -->
<header class="banner">
<!-- top left corner, sticky -->
<h1>Potato Pong</h1>
<!-- top right but it takes you down the page -->
<h2>Login</h2>
<!-- all this used to be in Welcome Section -->
<!-- the amazing backround! not sure yet if it should scroll with us or be the size of the View Port... -->
<!-- <canvas></canvas> -->
<!-- i think maybe the canvas needs to be in the header -->
<!-- using an image for now as a placehodler for the canvase -->
<img src="/img/tmp_mario_banner.png" alt="tmp Mario banner">
<div class="welcome">
<h2>Welcome to <br><span>Potato Pong</span></h2>
</div>
<!-- I want some sort of arrow pointing down and blinking to indicate you should scroll -->
</header>
<!-- <section class="banner"> -->
<section class="welcome">
</section>
<!-- no nav on home page -->
<section class="register">
<!-- i could have a toggle tab to login or create a new account -->
<Tabs items={items} {activeItem} on:tabChange={tabChange}/>
{#if activeItem === 'Login'}
<div class="card">
<Card>
<h2>Login</h2>
<form on:submit|preventDefault={loginHandler}>
<div class="form-field">
<input type="text" id="username" placeholder="username" bind:value={login.username}>
<div class="error">{ errors.username }</div>
</div>
<div class="form-field">
<input type="password" id="password" placeholder="password" bind:value={login.password}>
<div class="error">{ errors.password }</div>
</div>
<!-- type="" but flat={} cuz type is a string but flat is a bool-->
<!-- <Button type="secondary" flat={true}>Add Poll</Button> -->
<button>Login</button>
</form>
</Card>
</div>
{:else if activeItem = 'Create Account'}
<!-- Create Account -->
<div class="card">
<Card>
<h3>Create Account</h3>
<form on:submit|preventDefault={createAccountHandler}>
<div class="form-field">
<input type="text" id="username" placeholder="username" bind:value={login.username}>
<div class="error">{ errors.username }</div>
</div>
<div class="form-field">
<input type="password" id="password" placeholder="password" bind:value={login.password}>
<div class="error">{ errors.password }</div>
</div>
<!-- type="" but flat={} cuz type is a string but flat is a bool-->
<!-- <Button type="secondary" flat={true}>Add Poll</Button> -->
<button>Login</button>
</form>
</Card>
</div>
{/if}
</section>
<!-- below this i could say, this is where i might have put an explanation of what you can do on this page but fuck you i didn't -->
<!-- or maybe in the end i will, something like: Fun, Game, Colors, enjoy Friendship, or don't, it's your choice! -->
<Footer />
<style>
/* hearder stuff */
/* Clearly i have yet to master floating stuff... */
/* i need to put box-sizing in here somewhere for the login... */
/* starting again with CSS Grid */
/* .banner{
position: relative;
}
.banner img{
max-width: 100%;
}
.banner h1{
position: absolute;
left: 0;
top: 10px;
}
.banner h2{
position: absolute;
left: 90%;
top: 10px;
}
.banner .welcome{
background-color: #feb614;
color:white;
padding: 30px;
position: absolute;
left: 50%;
top: 50%;
}
.banner .welcome h2{
font-size: 58px;
}
.banner .welcome h2 span{
font-size: 1.3em;
}
.register{
} */
</style>

View File

@@ -0,0 +1,90 @@
<script lang="ts">
import { now } from "svelte/internal";
import Card from "../shared/Card.svelte";
import { createEventDispatcher } from 'svelte';
// import UserStore from './stores/UserStore';
// prolly Typescript-ify
//let fields{question:string, answerA:string, answerB: string} = { question: '', answerA: '', answerB: ''};
let login = { username: '', password: ''};
// let's us track any errors in a submited form
let errors = { username: '', password: ''};
let valid:boolean = false;
const dispatch = createEventDispatcher();
const loginHandler = () => {
valid = true;
if (login.username !== $UserStore.username) {
valid = false;
errors.username = "wrong example username."
} else {
// reseting the value of errors
errors.username = "";
}
if (login.password !== $UserStore.password) {
valid = false;
errors.password = "wrong example password."
} else {
// reseting the value of errors
errors.password = "";
}
if (valid) {
$UserStore.loggedIn = true;
$UserStore.status = 'online';
dispatch('login');
}
};
</script>
<div class="login">
<Card>
<form on:submit|preventDefault={loginHandler}>
<div class="form-field">
<input type="text" id="username" placeholder="username" bind:value={login.username}>
<div class="error">{ errors.username }</div>
</div>
<div class="form-field">
<input type="password" id="password" placeholder="password" bind:value={login.password}>
<div class="error">{ errors.password }</div>
</div>
<!-- type="" but flat={} cuz type is a string but flat is a bool-->
<!-- <Button type="secondary" flat={true}>Add Poll</Button> -->
<button>Login</button>
</form>
</Card>
</div>
<style>
form{
width: 200px;
margin: 0 auto;
text-align: center;
}
.form-field{
margin: 18px auto;
}
input{
width: 100%;
border-radius: 6px;
}
.login{
/* display: grid;
grid-template-columns: 1fr; */
max-width: 350px;
}
.error{
font-weight: bold;
font-size: 12px;
color: #d91b42;
}
</style>

View File

@@ -0,0 +1,414 @@
<script lang="ts">
// import Header from "./Header.svelte";
import Footer from "../components/Footer.svelte";
import Tabs from "../shared/Tabs.svelte";
import Card from "../shared/Card.svelte";
import Canvas from "../components/Canvas.svelte";
import ScrollTo from "../shared/ScrollTo.svelte";
import UserStore from "./UserStore.js";
import { createEventDispatcher } from "svelte";
import {push} from "svelte-spa-router";
let dispatch = createEventDispatcher();
// Tabs
let items: string[] = ['Login', 'Create Account'];
let activeItem: string = 'Login';
const tabChange = (e) => {
activeItem = e.detail;
};
import axios from 'axios';
import { onMount } from 'svelte';
let user = {logedIn: false};
onMount(async () => {
// console.log('PROFIL SVELTE');
const {data} = await axios.get('http://transcendance:8080/api/v2/user');
if (data)
user.logedIn = true;
});
const submit = async() => {
document.body.scrollIntoView();
push
window.location.href = 'http://transcendance:8080/api/v2/auth';
}
const logout = async() => {
await fetch('http://transcendance:8080/api/v2/auth/logout',);
user.logedIn = false;
};
// for toLogin
let bottomHalf;
// console.log(bottomHalf);
// const element = document.body;
// in theory this could be a Store, but for now this will do
// also in future we'll do this with urls
export let pages;
export let currentPage;
// this shit has overstayed it's welcome, fuck having userId all over the place
export let userId;
// maybe we put this in the login Component?
// tmp
let login = { username: '', password: ''};
// let's us track any errors in a submited form
let errors = { username: '', password: ''};
let valid:boolean = false;
const loginHandler = () => {
console.log('hi from loginHandler');
//
// Basic Checks
//
valid = false;
// checkin Username
if (login.username.length < 1)
{
valid = false;
errors.username = 'please enter a username';
} else {
valid = true;
errors.username = '';
}
// Checking Password
if (login.password.length < 1)
{
valid = false;
errors.password = 'please enter your password';
} else {
valid = true;
errors.password = '';
}
//
// Advanded Checks
//
// Comparing to UserStore
let users;
const unsubscribe = UserStore.subscribe(objs => {
users = objs;
console.log('subscribed');
});
// could i do $users.length ? doesn't look like it...
// let len = $users.length;
// userId = 0;
// userId = users.filter(user => user.username === login.username);
// this shit returns an array, it would be nice if it weren't an array
// let user = users.filter(user => user.username === login.username);
let user = users.find(user => user.username === login.username);
console.log(user);
// console.log(user.password);
// all this shit is a bit wordy... maybe a better way to handle this stuff?
// if (userIndex > users.length) {
if (!user) {
valid = false;
errors.username = 'user not found';
// something better?
} else {
valid = true;
errors.username = '';
}
// if (users[userIndex].password !== login.password) {
if (user && user.password !== login.password) {
valid = false;
errors.password = 'Wrong Password';
// Maybe clear the fields?
} else {
valid = true;
errors.password = '';
}
//
// Validation
//
unsubscribe();
if (valid) {
// yea don't modify this here...
currentPage = 'user';
// something like: indicate that userIndex is the one we want...
console.log('valid Credentials');
// making sure we start at the top of the page, way less jarring
// leave for now just in case...
document.body.scrollIntoView();
// may not actually want a dispatch?
// pass data userIndex?
// dispatch('loggedIn');
// from svelte-spa-router
push("/user");
}
};
//
const createAccountHandler = () => {
console.log('hi from accunt handler');
};
</script>
<header class="grid-container">
<!-- <div on:mouseenter={enter} on:mouseleave={leave} class:active > -->
<h1>Potato Pong</h1>
<!-- </div> -->
<nav>
<!-- placeholder links -->
<a href="/">Somewhere</a>
<!-- <a href="/">SomewhereElse</a> -->
{#if !user.logedIn}
<ScrollTo element={bottomHalf}/>
{:else}
<div class="logout" on:click={logout}>Log Out</div>
{/if}
<!-- one of these will be login and it will scroll you down to the login part -->
</nav>
<h2>
<div>Welcome to</div>
<div>Potato Pong</div>
</h2>
<!-- here i want a flashing arrow pointing down to the login part -->
</header>
<!-- <Canvas class=".canvas2"/> -->
<Canvas/>
<section class="register" bind:this={bottomHalf}>
<!-- My beautiful tabs are useless now, whatever, kill your darlings... -->
<!-- i could have a toggle tab to login or create a new account -->
<!-- This shit is kinda unnecessary cuz there is no Create Account option... -->
<Tabs items={items} {activeItem} on:tabChange={tabChange}/>
{#if activeItem === 'Login'}
<div class="card">
<Card>
<h2>Login</h2>
<form on:submit|preventDefault={loginHandler}>
<div class="form-field">
<input type="text" id="username" placeholder="username" bind:value={login.username}>
<div class="error">{ errors.username }</div>
</div>
<div class="form-field">
<input type="password" id="password" placeholder="password" bind:value={login.password}>
<div class="error">{ errors.password }</div>
</div>
<!-- type="" but flat={} cuz type is a string but flat is a bool-->
<!-- <Button type="secondary" flat={true}>Add Poll</Button> -->
<button>Login</button>
</form>
</Card>
</div>
{:else if activeItem = 'Create Account'}
<!-- Create Account -->
<div class="card">
<Card>
<h2>Create Account</h2>
<form on:submit|preventDefault={createAccountHandler}>
<div class="form-field">
<input type="text" id="username" placeholder="username" bind:value={login.username}>
<div class="error">{ errors.username }</div>
</div>
<div class="form-field">
<input type="password" id="password" placeholder="password" bind:value={login.password}>
<div class="error">{ errors.password }</div>
</div>
<!-- type="" but flat={} cuz type is a string but flat is a bool-->
<!-- <Button type="secondary" flat={true}>Add Poll</Button> -->
<button>Login</button>
</form>
</Card>
</div>
{/if}
</section>
<!-- below this i could say, this is where i might have put an explanation of what you can do on this page but fuck you i didn't -->
<!-- or maybe in the end i will, something like: Fun, Game, Colors, enjoy Friendship, or don't, it's your choice! -->
<Footer />
<!-- </div> -->
<style>
/* currently useless */
/* No styles get applied to the canvas from here, maybe i should move them to the Canvas Component... */
/* tho tbh, why bother, i'm gonna change it anyway... */
.canvas{
/* grid-column: 1 / 13;
grid-row: 1 / 3; */
/* don't rely on Z-Index!!!! */
z-index: -1;
position: relative;
width: 100%;
height: 100%;
white-space: nowrap;
/* Tmp? */
/* background-color: #666; */
/* somehow this got rid of they annoying white space under the canvas */
padding-bottom: 0;
margin-bottom: 0px;
overflow: hidden;
}
.canvas2{
z-index: -1;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
white-space: nowrap;
/* Tmp? */
/* background-color: #666; */
/* somehow this got rid of they annoying white space under the canvas */
padding-bottom: 0;
margin-bottom: 0px;
overflow: hidden;
}
/* .canvas .grid-container{ */
.grid-container{
position: absolute;
left: 0;
top: 0;
box-sizing: border-box;
width: 100%;
height: 100%;
white-space: nowrap;
/* padding-bottom: 0; */
margin-bottom: 0px;
overflow: hidden;
padding: 20px 40px;
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 1fr 1fr 1fr 1fr 1fr;
align-items: center;
}
header h1, header nav a{
/* tmp ? well i kinda like it */
color: bisque;
}
header h1{
grid-column: 1 / 7;
grid-row: 1;
/* grid-column: span 6; */
/* tmp? */
padding: 20px;
border: 1px solid bisque;
}
header nav{
/* make it a flexbox? */
grid-column: 7 / 13;
grid-row: 1;
justify-self: end;
/* tmp? */
padding: 20px;
border: 1px solid bisque;
}
header nav a{
margin-left: 10px;
text-decoration: none;
}
/* testing */
header nav a:hover{
font-weight: bold;
background-color: blue;
}
header h2:hover{
background: blue;
}
header h2{
grid-row: 3;
grid-column: 5 / span 4;
justify-self: center;
/* tmp */
border: 1px solid black;
z-index: 3;
}
header h2 div{
font-size: 2em;
}
/* the login / register part */
/* What do i want?
I want it to be the same size as a full screen so you don't see the canvas at all anymore */
/* doesn't work... */
/* body{
background: bisque;
} */
.bottom-half{
/* doesn't quite work... */
background: bisque;
/* also doesn't work... */
/* height: 1vw; */
/* testing */
/* position: absolute; */
}
section.register{
min-height: 400px;
}
.error{
font-size: 0.8em;
font-weight: bold;
color: red;
}
</style>

View File

@@ -0,0 +1,149 @@
<script lang="ts">
// The User Page can have several Flavors ?
// like a HomePage vibe, and an AccountPage vibe or whatever, but we'll still be serving this page just with diff props
import UserStore from "./UserStore";
import Header from "../components/Header.svelte";
import Footer from "../components/Footer.svelte";
import { createEventDispatcher } from "svelte";
import { loginStatus } from '../stores/loginStatusStore';
import { push } from "svelte-spa-router";
let dispatch = createEventDispatcher();
// i fucking hate these vars, the will have to go
export let pages;
export let currentPage;
export let userId;
// This shit is so redundant...
let types = ['home', 'account']
export let currentType = 'account';
// this is also stupid...
let sidebar = true;
// would i prefer to forward this?
let clickedHome = () => {
console.log('clicked home');
// do something...
currentType = 'home';
};
let clickedLogout = async() => {
console.log('clicked logout');
await fetch('http://transcendance:8080/api/v2/auth/logout',);
$loginStatus = false;
// maybe use replace() ?
push('/');
};
// All the variables that will eventually be replaced by the real values
let username = 'Username';
let games = { total: 7, won: 4, lost: 3};
let rank = 'gold or whatever the fuck who cares...';
</script>
<!-- remove ={clickedHome} if you want to forward the event to App.svelte-->
<!-- god this is some gross code... -->
<Header on:clickedHome={clickedHome} currentType="{currentType === 'home' ? 'home' : 'regular'}" on:clickedLogout={clickedLogout}/>
<!-- The Wave -->
<!-- <div class="spacer layer1"></div> -->
<!-- this is the thing that will let me offset -->
<div class='{sidebar ? "main-grid" : "none"}'>
{#if sidebar}
<section class="sidebar">
<p>i am a sidebar</p>
</section>
{/if}
<main class:offset={sidebar}>
<!-- what the fuck do we even want in here? messges, about the user, STATISTICS!!! -->
<!-- <div>some stuff goes here</div> -->
<img class="icon" src="img/default_user_icon.png" alt="default user icon">
<div>{username}</div>
<div>Rank: {rank}</div>
<section class="main-stats">
<h4>Match Statistics</h4>
<p>Total: {games.total}</p>
<p>Victories: {games.won}</p>
<p>Losses: {games.lost}</p>
</section>
</main>
</div>
<Footer />
<style>
/* from Haikei */
/* for any Haikei image */
.spacer{
aspect-ratio: 900/300;
width: 100%;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
}
/* the specific image we use, you need both classes */
.layer1{
background-image: url('/img/wave-haikei.svg');
}
div.main-grid{
display: grid;
grid-template-columns: repeat(12, 1fr);
/* max-height: calc(100vh - 30vh); */
height: 85vh;
}
section.sidebar{
grid-column: 1 / span 2;
background: white;
}
/* The main part */
main{
max-width: 960px;
margin: 40px auto;
text-align: center;
}
main.offset{
grid-column: 3 / span 10;
}
/* Normal CSS stuff */
.icon{
max-width: 150px;
}
/* The variable rich section */
section.main-stats{
max-width: 600px;
margin: 40px auto;
text-align: center;
/* i think i want to use a grid? */
display: grid;
grid-template-columns: repeat(3, 1fr);
/* not sure about this, maybe top should be larger? */
grid-template-rows: repeat(3, 1fr);
}
/* the stuff in the grid*/
section.main-stats h4{
grid-column: 1 / span 3;
}
</style>

View File

@@ -0,0 +1,45 @@
import { writable } from "svelte/store";
// ok yea this doesn't make a lot of sense, what am i trying to do?
// have an array of objects that are all the users?
// or an object that is the one user?
// For now as a placeholder i'll have one user in one obj
// should it not be a const? yea seems like it
// export const users = writable(
const UserStore = writable(
[{
// this is an example user
id: 1,
username: 'chaboi',
email: 'nope@fu.com',
// surely there's a better way to do this!
password: '1234',
// maybe an object listing friends' usernames?
friends: 0,
loggedIn: false,
// i imagine the user uploading their Avatare and it being put somehwere in the DB which could be referenced like a URL
// so if this field is empty then use the default avatar
avatar: '',
// online, offline, gaming
status: 'offline',
},
{
id: 2,
username: 'itsame',
email: 'mario@nintendo.com',
// surely there's a better way to do this!
password: '1234',
// maybe an object listing friends' usernames?
friends: 0,
loggedIn: false,
// i imagine the user uploading their Avatare and it being put somehwere in the DB which could be referenced like a URL
// so if this field is empty then use the default avatar
avatar: '',
// online, offline, gaming
status: 'offline',
}]
);
export default UserStore;
// export default users;

View File

@@ -0,0 +1,54 @@
@font-face {
font-family: 'Monocode-Regular-Demo';
src:url('/fonts/Monocode-Regular-Demo.ttf.woff') format('woff'),
url('Monocode-Regular-Demo.ttf.svg#Monocode-Regular-Demo') format('svg'),
url('Monocode-Regular-Demo.ttf.eot'),
url('Monocode-Regular-Demo.ttf.eot?#iefix') format('embedded-opentype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Air-Conditioner';
src:url('/fonts/Air-Conditioner.ttf.woff') format('woff'),
url('Air-Conditioner.ttf.svg#Air-Conditioner') format('svg'),
url('Air-Conditioner.ttf.eot'),
url('Air-Conditioner.ttf.eot?#iefix') format('embedded-opentype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: '1968-Odyssey-3D';
src:url('/fonts/1968-Odyssey-3D.ttf.woff') format('woff'),
url('1968-Odyssey-3D.ttf.svg#1968-Odyssey-3D') format('svg'),
url('1968-Odyssey-3D.ttf.eot'),
url('1968-Odyssey-3D.ttf.eot?#iefix') format('embedded-opentype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: '1968-Odyssey-Gradient';
src:url('/fonts/1968-Odyssey-Gradient.ttf.woff') format('woff'),
url('1968-Odyssey-Gradient.ttf.svg#1968-Odyssey-Gradient') format('svg'),
url('1968-Odyssey-Gradient.ttf.eot'),
url('1968-Odyssey-Gradient.ttf.eot?#iefix') format('embedded-opentype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'AddFatMan';
src:url('/fonts/AddFatMan.ttf.woff') format('woff'),
url('/fonts/AddFatMan.ttf.svg#AddFatMan') format('svg'),
url('/fonts/AddFatMan.ttf.eot'),
url('/fonts/AddFatMan.ttf.eot?#iefix') format('embedded-opentype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Bondi';
src:url('/fonts/Bondi.ttf.woff') format('woff'),
url('/fonts/Bondi.ttf.svg#Bondi') format('svg'),
url('/fonts/Bondi.ttf.eot'),
url('/fonts/Bondi.ttf.eot?#iefix') format('embedded-opentype');
font-weight: normal;
font-style: normal;
}

View File

@@ -1,89 +0,0 @@
<script>
import { push } from "svelte-spa-router";
let qrCodeImg;
let qrCode = "";
let wrongCode = "";
let maxTry = 3;
const fetchQrCodeImg = (async() => {
await fetch("http://transcendance:8080/api/v2/auth/2fa/generate",
{
method: 'POST',
})
.then(response => {return response.blob()})
.then(blob => {
const url = URL.createObjectURL(blob);
qrCodeImg = url;
});
})()
$: submit = async() => {
const response = await fetch("http://transcendance:8080/api/v2/auth/2fa/turn-on",
{
method : 'POST',
headers : {
"Content-Type": "application/json",
},
body : JSON.stringify({
"twoFaCode" : qrCode,
}),
});
if (response.status === 401)
{
qrCode = "";
wrongCode = `Wrong code, please try again. You have ${maxTry} before end session`;
maxTry--;
}
if (maxTry === 0)
{
await fetch("http://transcendance:8080/auth/logout",
{
method : 'POST',
})
.then(response => response.json())
.then(push("/login"));
}
if (response.status === 200)
{
push("/");
}
}
</script>
<body>
<main class="form-signin w-100 m-auto">
{#await fetchQrCodeImg}
<p>Please Wait...</p>
{:then data}
{#if wrongCode}
<div class="alert alert-danger" role="alert">
{wrongCode}
</div>
{/if}
<img src={qrCodeImg} alt="A QRCodeImg you must scan with google authenticator" id="qrcodeImg" />
<form on:submit|preventDefault={submit}>
<label for="code" class="block text-sm text-gray-600">Code</label>
<input id="code" bind:value={qrCode} type="text" class="block px-1 py-2 mt-2 border-2 border-gray-100 text-gray-800" />
<button type="submit" class="p-2 bg-blue-500 text-white mt-4 px-6">
Send
</button>
</form>
{:catch}
<p>Unable to get QrCodeImg</p>
{/await}
</main>
</body>
<style>
body {
display: flex;
align-items: center;
padding-top: 40px;
padding-bottom: 40px;
}
.form-signin {
max-width: 330px;
padding: 15px;
}
</style>

View File

@@ -1,55 +0,0 @@
<script lang="ts">
import axios from 'axios';
import { onMount } from 'svelte';
import {push} from 'svelte-spa-router';
let user = {logedIn: false};
onMount(async () => {
console.log('PROFIL SVELTE');
const {data} = await axios.get('http://transcendance:8080/api/v2/user');
if (data)
user.logedIn = true;
});
$: submit = async() => {
window.location.href = 'http://transcendance:8080/api/v2/auth';
}
$: logout = async() => {
await fetch('http://transcendance:8080/api/v2/auth/logout',);
user.logedIn = false;
}
console.log(user.logedIn);
</script>
<body>
<main class="form-signin w-100 m-auto">
{#if !user.logedIn}
<button on:click={submit} class="w-100 btn btn-lg btn-primary" type="submit">
Connexion
</button>
{/if}
{#if user.logedIn}
<button on:click={logout} class="w-100 btn btn-lg btn-primary" type="submit">
Deconnexion
</button>
{/if}
</main>
</body>
<style>
body {
display: flex;
align-items: center;
padding-top: 40px;
padding-bottom: 40px;
}
.form-signin {
max-width: 330px;
padding: 15px;
}
</style>

View File

@@ -1,67 +0,0 @@
<script>
import Router, { link } from "svelte-spa-router";
import Login from "../auth/login.svelte";
import Profil from "../profil/profil.svelte";
import UpdateProfil from "../profil/updateProfil.svelte";
const routes = {
"/login": Login,
"/profil": Profil,
"/update-profil": UpdateProfil,
};
</script>
<body>
<main class="d-flex flex-nowrap">
<h1 class="visually-hidden">Sidebars examples</h1>
<div
class="d-flex flex-column flex-shrink-0 p-3 text-bg-dark"
style="width: 280px;"
>
<a href="/" use:link class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-white text-decoration-none">
<span class="fs-4">Sidebar</span>
</a>
<hr />
<ul class="nav nav-pills flex-column mb-auto">
<li class="nav-item">
<a
href="/profil"
use:link
class="nav-link active"
aria-current="page"
>
Profil
</a>
</li>
<li class="nav-item">
<a
href="/update-profil"
use:link
class="nav-link active"
aria-current="page"
>
Update Profile
</a>
</li>
</ul>
<hr />
</div>
</main>
</body>
<Router {routes} />
<style>
body {
min-height: 100vh;
min-height: -webkit-fill-available;
}
main {
height: 100vh;
height: -webkit-fill-available;
max-height: 100vh;
overflow-x: auto;
overflow-y: hidden;
}
</style>

View File

@@ -1,53 +0,0 @@
<script>
import axios from "axios";
import { onMount } from "svelte";
let user = {};
let stats = {};
onMount (async() => {
console.log("PROFIL SVELTE");
const response = await fetch('http://transcendance:8080/api/v2/user',
{
method : 'GET',
}).then(response => response.json());
console.log(response);
user = response;
stats = user.stats;
});
</script>
<body>
<main class="form-signin w-100 m-auto">
<div class="container">
<div class="row">
<div class="col-12">
<h1>Profil</h1>
<ul>
<li>username : {user.username}</li>
<li>stats : Win games {stats.winGame}
Lose games {stats.loseGame}
Draw games {stats.drawGame}
Total games {stats.totalGame}
</li>
</ul>
</div>
</div>
</div>
</main>
</body>
<style>
body {
display: flex;
align-items: center;
padding-top: 40px;
padding-bottom: 40px;
}
.form-signin {
max-width: 330px;
padding: 15px;
}
</style>

View File

@@ -1,120 +0,0 @@
<script>
import { onMount } from "svelte";
let avatarUser, postVar, newAvatar, fileinput;
let usernameSv = "";
let image_urlSv = "";
let uploadAvatarSuccess = false;
let gAuth = false;
let errors = {usernameSv, image_urlSv};
onMount(async () => {
await fetch("http://transcendance:8080/api/v2/user").
then(response => response.json()).
then(data => {
usernameSv = data.username;
gAuth = data.isEnabledTwoFactorAuth;
});
await fetch("http://transcendance:8080/api/v2/user/avatar", {method: "GET"}).
then(response => {return response.blob()}).
then(data => {
const url = URL.createObjectURL(data);
avatarUser = url;
});
});
$: uploadAvatar = async() => {
const data = new FormData();
data.append("file", newAvatar[0]);
console.log(data);
await fetch("http://transcendance:8080/api/v2/user/avatar",
{
method : 'POST',
body : data,
})
.then(uploadAvatarSuccess = true)
.catch(errors.image_urlSv = "Something went wrong." )
}
$: submit = async() => {
errors.usernameSv = "";
errors.image_urlSv ="";
if (usernameSv === undefined || usernameSv.trim() === "") {
errors.usernameSv = "Username is required";
return;
}
console.log(usernameSv);
await fetch("http://transcendance:8080/api/v2/user/",
{
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
"username" : usernameSv,
"isEnabledTwoFactorAuth" : gAuth
})
})
}
</script>
<body>
<main class="form-signin w-100 m-auto">
<div class="p-20">
{#if errors.image_urlSv}
<div class="alert alert-danger" role="alert">
{errors.image_urlSv}
</div>
{/if}
{#if errors.username}
<div class="alert alert-danger" role="alert">
{errors.username}
</div>
{/if}
{#if uploadAvatarSuccess}
<div class="alert alert-danger" role="alert">
You avatar has been successfully uploaded !
</div>
{/if}
<form on:submit|preventDefault={uploadAvatar}>
{#if avatarUser}
<img class="avatar" src={avatarUser} alt="" />
{/if}
<input
type="text"
bind:value={postVar}
placeholder={"choose your file"}
/>
<br />
<input
type="file"
bind:files={newAvatar} />
<br />
<button type="submit" class="p-2 bg-blue-500 text-white mt-4 px-6">
Choose avatar
</button>
</form>
<form on:submit|preventDefault={submit}>
<label for="username" class="block text-sm text-gray-600">Username</label>
<input id="username" type="text" placeholder=${usernameSv} class="block px-1 py-2 mt-2 border-2 border-gray-100 text-gray-800" bind:value={usernameSv} />
<div>
<input type="checkbox" bind:checked={gAuth} id="gAuth" name="gAuth">
<label for="gAuth">Enable google authenticator</label>
</div>
</form>
</div>
</main>
</body>
<style>
body {
display: flex;
align-items: center;
padding-top: 40px;
padding-bottom: 40px;
}
.form-signin {
max-width: 330px;
padding: 15px;
}
</style>

View File

@@ -0,0 +1,39 @@
import NotFound from "../NotFound.svelte";
import ProfilePage from "../ProfilePage.svelte";
import SplashPage from "../SplashPage.svelte";
import TmpTest from '../TmpTest.svelte';
// "/article/:title": Article, // this is how you would do parameters!
// "/": LoginPage,
export const primaryRoutes = {
'/': SplashPage,
'/profile': ProfilePage,
'/profile/*': ProfilePage,
'*': NotFound
};
// export const primaryRoutes = {
// "/": SplashPage,
// "/profile": ProfilePage,
// "/game": GamePage,
// "/chat": ChatPage,
// "*": NotFound
// };
// i might need to add /profile/* and such to make the nested routers work
// ok maybe these need to be in their own files?
// export const gameRoutes = {
// "/": GamePage,
// "*": NotFound
// };
// export const chatRoutes = {
// "/": ChatPage,
// "*": NotFound
// };

View File

@@ -0,0 +1,15 @@
import NotFound from "../NotFound.svelte";
import ProfileDisplay from '../ProfileDisplay.svelte';
import ProfileSettings from '../ProfileSettings.svelte';
// establishing the prefix here very clearly so we can have a coherent repeatable structure
export const prefix = '/profile';
export const profileRoutes = {
'/': ProfileDisplay,
'/settings': ProfileSettings,
'*': NotFound
};
// what if i did /#/profile/:id for like not the user? and then based on that did a fetch?

View File

@@ -0,0 +1,14 @@
<div class="card">
<slot></slot>
</div>
<style>
.card{
background: white;
padding: 20px;
border-radius: 6px;
/* this softens the corners */
box-shadow: 0px 2px 4px rgba(0,0,0,0.1);
}
</style>

View File

@@ -0,0 +1,40 @@
<script lang="ts">
// trying something...
// const element = document.getElementById("bottom-half");
export let element;
// is this too JS for me?
const scrollTo= () => {
element.scrollIntoView({behavior: "smooth"});
console.log('supposed to scroll');
// Maybe eventually i can do this in a more svelte way, on:scroll={someEvent} ... whatever
};
</script>
<!-- <svelte:window bind:scrollY={y}/> -->
<!-- wait actually i don't want this... -->
<!-- <svelte:window on:scroll={handleOnScroll} /> -->
<!-- a div instead? -->
<!-- <button>Login</button> -->
<div class="to-login" on:click={scrollTo}>Login</div>
<style>
.to-login{
display: inline-block;
/* color: bisque; */
color: blue;
margin-left: 10px;
}
.to-login:hover{
font-weight: bold;
color: black;
cursor: pointer;
}
</style>

View File

@@ -0,0 +1,43 @@
<script lang='ts'>
import { createEventDispatcher } from "svelte";
export let items;
export let activeItem;
const dispatch = createEventDispatcher();
</script>
<div class="tabs">
<!-- creates a list, can be done other ways -->
<ul>
{#each items as item}
<li on:click={() => dispatch('tabChange', item)}>
<!-- the class active is attributed if the condition is met -->
<div class:active={activeItem === item}>{item}</div>
</li>
{/each}
</ul>
</div>
<style>
.tabs{
margin-bottom: 40px;
}
ul{
display: flex;
justify-content: center;
padding: 0;
list-style-type: none;
}
li{
margin: 0 16px;
font-size: 18px;
color: #555;
cursor: pointer;
}
.active{
color: #d91b42;
border-bottom: 2px solid #d91b42;
padding-bottom: 8px;
}
</style>

View File

@@ -0,0 +1,16 @@
import { writable } from "svelte/store";
// This is a "Custom Store" see that chapter in the Svelte Tutorial, should be fine
// NVM this is definitely overkill
// function createLogin() {
// const { subscribe, update } = writable(false);
// return {
// subscribe,
// login: () => update(s => s = true),
// logout: () => update(s => s = false),
// }
// }
// export const loginStatus = createLogin();
export const loginStatus = writable(false);