Created the first routes

This commit is contained in:
Jeroen De Meerleer 2023-03-18 18:07:38 +01:00
parent 4f67f866e3
commit f9bfc4b281
Signed by: JeroenED
GPG Key ID: 28CCCB8F62BFADD6
32 changed files with 4374 additions and 0 deletions

13
.eslintignore Normal file
View File

@ -0,0 +1,13 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock

20
.eslintrc.cjs Normal file
View File

@ -0,0 +1,20 @@
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
plugins: ['svelte3', '@typescript-eslint'],
ignorePatterns: ['*.cjs'],
overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
settings: {
'svelte3/typescript': () => require('typescript')
},
parserOptions: {
sourceType: 'module',
ecmaVersion: 2020
},
env: {
browser: true,
es2017: true,
node: true
}
};

12
.gitignore vendored Normal file
View File

@ -0,0 +1,12 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
.idea/

1
.npmrc Normal file
View File

@ -0,0 +1 @@
engine-strict=true

13
.prettierignore Normal file
View File

@ -0,0 +1,13 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock

9
.prettierrc Normal file
View File

@ -0,0 +1,9 @@
{
"useTabs": true,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100,
"plugins": ["prettier-plugin-svelte"],
"pluginSearchDirs": ["."],
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
}

77
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,77 @@
{
"tailwindCSS.classAttributes": [
"class",
"accent",
"active",
"background",
"badge",
"border",
"borderColor",
"borderWidth",
"button",
"buttonBack",
"buttonClasses",
"buttonComplete",
"buttonNext",
"buttonTextNext",
"buttonTextPrevious",
"chips",
"color",
"cursor",
"display",
"element",
"fill",
"flex",
"gap",
"gridColumns",
"height",
"hover",
"invalid",
"justify",
"meter",
"padding",
"regionBody",
"regionCaption",
"regionCaret",
"regionCone",
"regionContent",
"regionControl",
"regionDefault",
"regionFoot",
"regionHead",
"regionHeader",
"regionIcon",
"regionInterface",
"regionInterfaceText",
"regionLabel",
"regionLead",
"regionLegend",
"regionList",
"regionNavigation",
"regionPage",
"regionPanel",
"regionRowHeadline",
"regionRowMain",
"regionTrail",
"rounded",
"select",
"shadow",
"slotDefault",
"slotFooter",
"slotHeader",
"slotLead",
"slotMessage",
"slotMeta",
"slotPageContent",
"slotPageFooter",
"slotPageHeader",
"slotSidebarLeft",
"slotSidebarRight",
"slotTrail",
"space",
"spacing",
"text",
"track",
"width"
]
}

3813
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

42
package.json Normal file
View File

@ -0,0 +1,42 @@
{
"name": "blackbirdchess-client-web",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"test": "playwright test",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"test:unit": "vitest",
"lint": "prettier --plugin-search-dir . --check . && eslint .",
"format": "prettier --plugin-search-dir . --write ."
},
"devDependencies": {
"@playwright/test": "^1.28.1",
"@skeletonlabs/skeleton": "^1.0.0",
"@sveltejs/adapter-auto": "^2.0.0",
"@sveltejs/kit": "^1.5.0",
"@tailwindcss/forms": "^0.5.3",
"@typescript-eslint/eslint-plugin": "^5.45.0",
"@typescript-eslint/parser": "^5.45.0",
"autoprefixer": "^10.4.7",
"eslint": "^8.28.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-svelte3": "^4.0.0",
"postcss": "^8.4.14",
"prettier": "^2.8.0",
"prettier-plugin-svelte": "^2.8.1",
"svelte": "^3.54.0",
"svelte-check": "^3.0.1",
"tailwindcss": "^3.1.5",
"tslib": "^2.4.1",
"typescript": "^4.9.3",
"vite": "^4.0.0",
"vitest": "^0.25.3",
"postcss-load-config": "^4.0.1",
"svelte-preprocess": "^4.10.7"
},
"type": "module"
}

11
playwright.config.ts Normal file
View File

@ -0,0 +1,11 @@
import type { PlaywrightTestConfig } from '@playwright/test';
const config: PlaywrightTestConfig = {
webServer: {
command: 'npm run build && npm run preview',
port: 4173
},
testDir: 'tests'
};
export default config;

6
postcss.config.cjs Normal file
View File

@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {}
}
};

10
src/app.d.ts vendored Normal file
View File

@ -0,0 +1,10 @@
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
// and what to do when importing types
declare namespace App {
// interface Locals {}
// interface PageData {}
// interface Error {}
// interface Platform {}
}

12
src/app.html Normal file
View File

@ -0,0 +1,12 @@
<!DOCTYPE html >
<html lang="en" class="dark">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width" />
%sveltekit.head%
</head>
<body data-theme="skeleton">
<div style="display: contents" class="h-full overflow-hidden">%sveltekit.body%</div>
</body>
</html>

10
src/app.pcss Normal file
View File

@ -0,0 +1,10 @@
/*Write your global styles here, in PostCSS syntax */
@import "/static/scss/icons.scss";
@tailwind base;
/*place global styles here */
html,
body {
@apply h-full overflow-hidden;
}
@tailwind components;
@tailwind utilities;

7
src/index.test.ts Normal file
View File

@ -0,0 +1,7 @@
import { describe, it, expect } from 'vitest';
describe('sum test', () => {
it('adds 1 + 2 to equal 3', () => {
expect(1 + 2).toBe(3);
});
});

11
src/routes/+layout.svelte Normal file
View File

@ -0,0 +1,11 @@
<script lang="ts">
import '../app.pcss';
// The ordering of these imports is critical to your app working properly
import '@skeletonlabs/skeleton/themes/theme-skeleton.css';
// If you have source.organizeImports set to true in VSCode, then it will auto change this ordering
import '@skeletonlabs/skeleton/styles/all.css';
// Most of your app wide CSS should be put in this file
import '../app.pcss';
</script>
<slot />

88
src/routes/+page.svelte Normal file
View File

@ -0,0 +1,88 @@
<div class="container h-full mx-auto flex justify-center items-center flex-col">
<h1 class="my-3">Blackbird Chess</h1>
{#if message.visible}
<aside class="alert variant-filled-error">
<!-- Icon -->
<div><i class="text-2xl icon icon-exclamation-triangle"></i></div>
<!-- Message -->
<p class="alert-message">{message.text}</p>
<!-- Actions -->
<div class="alert-actions">
<i on:click={closeWarning} class="icon icon-close"></i>
</div>
</aside>
{/if}
<form name="login-server" class="flex flex-col">
<label class="label my-3">
<span>Please select the server to login:</span>
<input
type="url"
name="server"
id="login-server-url"
class="input"
bind:value={serverurl}>
</label>
<button type="button" id="login-server-submit" class="btn variant-filled-primary my-3" on:click={handleSelectServer}>Submit</button>
</form>
</div>
<style lang="scss">
</style>
<script lang="js">
import { urls, server } from "../stores.js";
import {goto} from "$app/navigation";
let message = {
visible: false,
text: '',
class: 'error'
};
var serverurl = '';
function handleSelectServer() {
if(!isValidHttpUrl(serverurl)) {
serverurl = 'https://' + serverurl;
if(!isValidHttpUrl(serverurl)) {
return unavailableServer('This server is not a Blackbird Chess Server')
}
}
console.log("Selected server: " + serverurl);
fetch(serverurl + urls.capabilities)
.then((response) => {
if (!response.ok) return unavailableServer('This server is not a Blackbird Chess Server')
return response.json()
})
.then((data) => {
if(!data.login) return unavailableServer('This server is unavailable for login currently');
server.update(n => serverurl);
goto('/login')
})
.catch((error) => {
return unavailableServer('This server is not a Blackbird Chess Server')
});
}
function isValidHttpUrl(string) {
let url;
try {
url = new URL(string);
} catch (_) {
return false;
}
return url.protocol === "http:" || url.protocol === "https:";
}
function unavailableServer(error) {
console.log(error);
message.text = error;
message.class = 'error'
message.visible = true;
}
function closeWarning() {
message.visible = false;
}
</script>

View File

@ -0,0 +1,11 @@
<script lang="ts">
import '../../app.pcss';
// The ordering of these imports is critical to your app working properly
import '@skeletonlabs/skeleton/themes/theme-skeleton.css';
// If you have source.organizeImports set to true in VSCode, then it will auto change this ordering
import '@skeletonlabs/skeleton/styles/all.css';
// Most of your app wide CSS should be put in this file
import '../../app.pcss';
</script>
<slot />

View File

@ -0,0 +1,71 @@
<div class="container h-full mx-auto flex justify-center items-center flex-col">
<h1 class="my-3">Blackbird Chess</h1>
{#if message.visible}
<aside class="alert variant-filled-error">
<!-- Icon -->
<div><i class="text-2xl icon icon-exclamation-triangle"></i></div>
<!-- Message -->
<p class="alert-message">{message.text}</p>
<!-- Actions -->
<div class="alert-actions">
<i on:click={closeWarning} class="icon icon-close"></i>
</div>
</aside>
{/if}
<form name="login-server" class="flex flex-col">
<label class="label my-3">
<span>Username:</span>
<input type="email" name="email" id="login-email" class="input" bind:value={email}>
</label>
<label class="label my-3">
<span>Password:</span>
<input type="password" name="password" id="login-password" class="input" bind:value={email}>
</label>
<button type="button" id="login-server-submit" class="btn variant-filled-primary my-3" on:click={handleLogin}>Submit</button>
</form>
</div>
<style lang="scss">
</style>
<script lang="js">
import { urls, server } from "../../stores.js";
import { goto } from '$app/navigation';
import { onMount } from 'svelte';
let message = {
visible: false,
text: '',
class: 'error'
};
var email = '';
var password = '';
var serverurl
server.subscribe(value => {
serverurl = value;
});
onMount(async () => {
if(serverurl == null) {
goto('/')
}
});
function handleLogin() {
unavailableServer('To be implemented')
}
function unavailableServer(error) {
console.log(error);
message.text = error;
message.class = 'error'
message.visible = true;
}
function closeWarning() {
message.visible = false;
}
</script>

8
src/stores.js Normal file
View File

@ -0,0 +1,8 @@
import { writable } from 'svelte/store';
export const urls = {
capabilities: "/capabilities",
login: "/login"
}
export const server = writable(null);

BIN
static/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
static/fonts/icomoon.eot Normal file

Binary file not shown.

12
static/fonts/icomoon.svg Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>
<font id="icomoon" horiz-adv-x="1024">
<font-face units-per-em="1024" ascent="960" descent="-64" />
<missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" horiz-adv-x="512" d="" />
<glyph unicode="&#xf00d;" glyph-name="close, remove, times" horiz-adv-x="805" d="M741.714 195.428c0-14.286-5.714-28.571-16-38.857l-77.714-77.714c-10.286-10.286-24.571-16-38.857-16s-28.571 5.714-38.857 16l-168 168-168-168c-10.286-10.286-24.571-16-38.857-16s-28.571 5.714-38.857 16l-77.714 77.714c-10.286 10.286-16 24.571-16 38.857s5.714 28.571 16 38.857l168 168-168 168c-10.286 10.286-16 24.571-16 38.857s5.714 28.571 16 38.857l77.714 77.714c10.286 10.286 24.571 16 38.857 16s28.571-5.714 38.857-16l168-168 168 168c10.286 10.286 24.571 16 38.857 16s28.571-5.714 38.857-16l77.714-77.714c10.286-10.286 16-24.571 16-38.857s-5.714-28.571-16-38.857l-168-168 168-168c10.286-10.286 16-24.571 16-38.857z" />
<glyph unicode="&#xf071;" glyph-name="exclamation-triangle, warning" d="M585.143 165.143v108.571c0 10.286-8 18.857-18.286 18.857h-109.714c-10.286 0-18.286-8.571-18.286-18.857v-108.571c0-10.286 8-18.857 18.286-18.857h109.714c10.286 0 18.286 8.571 18.286 18.857zM584 378.857l10.286 262.286c0 3.429-1.714 8-5.714 10.857-3.429 2.857-8.571 6.286-13.714 6.286h-125.714c-5.143 0-10.286-3.429-13.714-6.286-4-2.857-5.714-8.571-5.714-12l9.714-261.143c0-7.429 8.571-13.143 19.429-13.143h105.714c10.286 0 18.857 5.714 19.429 13.143zM576 912.571l438.857-804.571c12.571-22.286 12-49.714-1.143-72s-37.143-36-62.857-36h-877.714c-25.714 0-49.714 13.714-62.857 36s-13.714 49.714-1.143 72l438.857 804.571c12.571 23.429 37.143 38.286 64 38.286s51.429-14.857 64-38.286z" />
</font></defs></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
static/fonts/icomoon.ttf Normal file

Binary file not shown.

BIN
static/fonts/icomoon.woff Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
{"IcoMoonType":"selection","icons":[{"icon":{"paths":["M741.714 755.429c0 14.286-5.714 28.571-16 38.857l-77.714 77.714c-10.286 10.286-24.571 16-38.857 16s-28.571-5.714-38.857-16l-168-168-168 168c-10.286 10.286-24.571 16-38.857 16s-28.571-5.714-38.857-16l-77.714-77.714c-10.286-10.286-16-24.571-16-38.857s5.714-28.571 16-38.857l168-168-168-168c-10.286-10.286-16-24.571-16-38.857s5.714-28.571 16-38.857l77.714-77.714c10.286-10.286 24.571-16 38.857-16s28.571 5.714 38.857 16l168 168 168-168c10.286-10.286 24.571-16 38.857-16s28.571 5.714 38.857 16l77.714 77.714c10.286 10.286 16 24.571 16 38.857s-5.714 28.571-16 38.857l-168 168 168 168c10.286 10.286 16 24.571 16 38.857z"],"width":804.5714285714286,"attrs":[],"isMulticolor":false,"isMulticolor2":false,"tags":["close","remove","times"],"defaultCode":61453,"grid":14},"attrs":[],"properties":{"name":"close, remove, times","id":17,"order":2,"prevSize":28,"code":61453},"setIdx":0,"setId":0,"iconIdx":17},{"icon":{"paths":["M585.143 785.714v-108.571c0-10.286-8-18.857-18.286-18.857h-109.714c-10.286 0-18.286 8.571-18.286 18.857v108.571c0 10.286 8 18.857 18.286 18.857h109.714c10.286 0 18.286-8.571 18.286-18.857zM584 572l10.286-262.286c0-3.429-1.714-8-5.714-10.857-3.429-2.857-8.571-6.286-13.714-6.286h-125.714c-5.143 0-10.286 3.429-13.714 6.286-4 2.857-5.714 8.571-5.714 12l9.714 261.143c0 7.429 8.571 13.143 19.429 13.143h105.714c10.286 0 18.857-5.714 19.429-13.143zM576 38.286l438.857 804.571c12.571 22.286 12 49.714-1.143 72s-37.143 36-62.857 36h-877.714c-25.714 0-49.714-13.714-62.857-36s-13.714-49.714-1.143-72l438.857-804.571c12.571-23.429 37.143-38.286 64-38.286s51.429 14.857 64 38.286z"],"width":1024,"attrs":[],"isMulticolor":false,"isMulticolor2":false,"tags":["exclamation-triangle","warning"],"defaultCode":61553,"grid":14},"attrs":[],"properties":{"name":"exclamation-triangle, warning","id":107,"order":3,"prevSize":28,"code":61553},"setIdx":0,"setId":0,"iconIdx":107}],"height":1024,"metadata":{"name":"icomoon"},"preferences":{"showGlyphs":true,"showQuickUse":true,"showQuickUse2":true,"showSVGs":true,"fontPref":{"prefix":"icon-","metadata":{"fontFamily":"icomoon"},"metrics":{"emSize":1024,"baseline":6.25,"whitespace":50},"embed":false},"imagePref":{"prefix":"icon-","png":true,"useClassSelector":true,"color":0,"bgColor":16777215,"classSelector":".icon"},"historySize":50,"showCodes":true,"gridSize":16}}

42
static/scss/icons.scss Normal file
View File

@ -0,0 +1,42 @@
@font-face {
font-family: 'icomoon';
src: url('/fonts/icomoon.eot?74go0w');
src: url('/fonts/icomoon.eot?74go0w#iefix') format('embedded-opentype'),
url('/fonts/icomoon.ttf?74go0w') format('truetype'),
url('/fonts/icomoon.woff?74go0w') format('woff'),
url('/fonts/icomoon.svg?74go0w#icomoon') format('svg');
font-weight: normal;
font-style: normal;
font-display: block;
}
[class^="icon-"], [class*=" icon-"] {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: 'icomoon' !important;
speak: never;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-close:before {
content: "\f00d";
}
.icon-remove:before {
content: "\f00d";
}
.icon-times:before {
content: "\f00d";
}
.icon-exclamation-triangle:before {
content: "\f071";
}
.icon-warning:before {
content: "\f071";
}

24
svelte.config.js Normal file
View File

@ -0,0 +1,24 @@
import preprocess from 'svelte-preprocess';
import adapter from '@sveltejs/adapter-auto';
import { vitePreprocess } from '@sveltejs/kit/vite';
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
// for more information about preprocessors
preprocess: [
vitePreprocess(),
preprocess({
postcss: true
})
],
kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter()
}
};
export default config;

15
tailwind.config.cjs Normal file
View File

@ -0,0 +1,15 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: 'class',
content: [
'./src/**/*.{html,js,svelte,ts}',
require('path').join(require.resolve('@skeletonlabs/skeleton'), '../**/*.{html,js,svelte,ts}')
],
theme: {
extend: {}
},
plugins: [
...require('@skeletonlabs/skeleton/tailwind/skeleton.cjs')(),
require('@tailwindcss/forms')
]
};

6
tests/test.ts Normal file
View File

@ -0,0 +1,6 @@
import { expect, test } from '@playwright/test';
test('index page has expected h1', async ({ page }) => {
await page.goto('/');
await expect(page.getByRole('heading', { name: 'Welcome to SvelteKit' })).toBeVisible();
});

17
tsconfig.json Normal file
View File

@ -0,0 +1,17 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true
}
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
//
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in
}

12
vite.config.ts Normal file
View File

@ -0,0 +1,12 @@
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vitest/config';
export default defineConfig({
plugins: [sveltekit()],
test: {
include: ['src/**/*.{test,spec}.{js,ts}']
},
server: {
port: 5174
}
});