Start of works on frontend

This commit is contained in:
nefrace 2022-12-14 02:27:39 +03:00
parent 0bd63b53c5
commit 77b7719192
62 changed files with 609 additions and 9 deletions

View File

@ -0,0 +1,315 @@
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 100;
font-stretch: normal;
font-style: normal;
src: url('ttf/iosevka-aile-thin.ttf') format('truetype'), url('woff2/iosevka-aile-thin.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 100;
font-stretch: normal;
font-style: oblique;
src: url('ttf/iosevka-aile-thinoblique.ttf') format('truetype'), url('woff2/iosevka-aile-thinoblique.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web Oblique';
font-display: swap;
font-weight: 100;
font-stretch: normal;
src: url('ttf/iosevka-aile-thinoblique.ttf') format('truetype'), url('woff2/iosevka-aile-thinoblique.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 100;
font-stretch: normal;
font-style: italic;
src: url('ttf/iosevka-aile-thinitalic.ttf') format('truetype'), url('woff2/iosevka-aile-thinitalic.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 200;
font-stretch: normal;
font-style: normal;
src: url('ttf/iosevka-aile-extralight.ttf') format('truetype'), url('woff2/iosevka-aile-extralight.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 200;
font-stretch: normal;
font-style: oblique;
src: url('ttf/iosevka-aile-extralightoblique.ttf') format('truetype'), url('woff2/iosevka-aile-extralightoblique.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web Oblique';
font-display: swap;
font-weight: 200;
font-stretch: normal;
src: url('ttf/iosevka-aile-extralightoblique.ttf') format('truetype'), url('woff2/iosevka-aile-extralightoblique.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 200;
font-stretch: normal;
font-style: italic;
src: url('ttf/iosevka-aile-extralightitalic.ttf') format('truetype'), url('woff2/iosevka-aile-extralightitalic.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 300;
font-stretch: normal;
font-style: normal;
src: url('ttf/iosevka-aile-light.ttf') format('truetype'), url('woff2/iosevka-aile-light.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 300;
font-stretch: normal;
font-style: oblique;
src: url('ttf/iosevka-aile-lightoblique.ttf') format('truetype'), url('woff2/iosevka-aile-lightoblique.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web Oblique';
font-display: swap;
font-weight: 300;
font-stretch: normal;
src: url('ttf/iosevka-aile-lightoblique.ttf') format('truetype'), url('woff2/iosevka-aile-lightoblique.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 300;
font-stretch: normal;
font-style: italic;
src: url('ttf/iosevka-aile-lightitalic.ttf') format('truetype'), url('woff2/iosevka-aile-lightitalic.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 400;
font-stretch: normal;
font-style: normal;
src: url('ttf/iosevka-aile-regular.ttf') format('truetype'), url('woff2/iosevka-aile-regular.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 400;
font-stretch: normal;
font-style: oblique;
src: url('ttf/iosevka-aile-oblique.ttf') format('truetype'), url('woff2/iosevka-aile-oblique.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web Oblique';
font-display: swap;
font-weight: 400;
font-stretch: normal;
src: url('ttf/iosevka-aile-oblique.ttf') format('truetype'), url('woff2/iosevka-aile-oblique.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 400;
font-stretch: normal;
font-style: italic;
src: url('ttf/iosevka-aile-italic.ttf') format('truetype'), url('woff2/iosevka-aile-italic.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 500;
font-stretch: normal;
font-style: normal;
src: url('ttf/iosevka-aile-medium.ttf') format('truetype'), url('woff2/iosevka-aile-medium.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 500;
font-stretch: normal;
font-style: oblique;
src: url('ttf/iosevka-aile-mediumoblique.ttf') format('truetype'), url('woff2/iosevka-aile-mediumoblique.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web Oblique';
font-display: swap;
font-weight: 500;
font-stretch: normal;
src: url('ttf/iosevka-aile-mediumoblique.ttf') format('truetype'), url('woff2/iosevka-aile-mediumoblique.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 500;
font-stretch: normal;
font-style: italic;
src: url('ttf/iosevka-aile-mediumitalic.ttf') format('truetype'), url('woff2/iosevka-aile-mediumitalic.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 600;
font-stretch: normal;
font-style: normal;
src: url('ttf/iosevka-aile-semibold.ttf') format('truetype'), url('woff2/iosevka-aile-semibold.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 600;
font-stretch: normal;
font-style: oblique;
src: url('ttf/iosevka-aile-semiboldoblique.ttf') format('truetype'), url('woff2/iosevka-aile-semiboldoblique.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web Oblique';
font-display: swap;
font-weight: 600;
font-stretch: normal;
src: url('ttf/iosevka-aile-semiboldoblique.ttf') format('truetype'), url('woff2/iosevka-aile-semiboldoblique.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 600;
font-stretch: normal;
font-style: italic;
src: url('ttf/iosevka-aile-semibolditalic.ttf') format('truetype'), url('woff2/iosevka-aile-semibolditalic.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 700;
font-stretch: normal;
font-style: normal;
src: url('ttf/iosevka-aile-bold.ttf') format('truetype'), url('woff2/iosevka-aile-bold.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 700;
font-stretch: normal;
font-style: oblique;
src: url('ttf/iosevka-aile-boldoblique.ttf') format('truetype'), url('woff2/iosevka-aile-boldoblique.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web Oblique';
font-display: swap;
font-weight: 700;
font-stretch: normal;
src: url('ttf/iosevka-aile-boldoblique.ttf') format('truetype'), url('woff2/iosevka-aile-boldoblique.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 700;
font-stretch: normal;
font-style: italic;
src: url('ttf/iosevka-aile-bolditalic.ttf') format('truetype'), url('woff2/iosevka-aile-bolditalic.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 800;
font-stretch: normal;
font-style: normal;
src: url('ttf/iosevka-aile-extrabold.ttf') format('truetype'), url('woff2/iosevka-aile-extrabold.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 800;
font-stretch: normal;
font-style: oblique;
src: url('ttf/iosevka-aile-extraboldoblique.ttf') format('truetype'), url('woff2/iosevka-aile-extraboldoblique.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web Oblique';
font-display: swap;
font-weight: 800;
font-stretch: normal;
src: url('ttf/iosevka-aile-extraboldoblique.ttf') format('truetype'), url('woff2/iosevka-aile-extraboldoblique.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 800;
font-stretch: normal;
font-style: italic;
src: url('ttf/iosevka-aile-extrabolditalic.ttf') format('truetype'), url('woff2/iosevka-aile-extrabolditalic.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 900;
font-stretch: normal;
font-style: normal;
src: url('ttf/iosevka-aile-heavy.ttf') format('truetype'), url('woff2/iosevka-aile-heavy.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 900;
font-stretch: normal;
font-style: oblique;
src: url('ttf/iosevka-aile-heavyoblique.ttf') format('truetype'), url('woff2/iosevka-aile-heavyoblique.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web Oblique';
font-display: swap;
font-weight: 900;
font-stretch: normal;
src: url('ttf/iosevka-aile-heavyoblique.ttf') format('truetype'), url('woff2/iosevka-aile-heavyoblique.woff2') format('woff2');
}
@font-face {
font-family: 'Iosevka Aile Web';
font-display: swap;
font-weight: 900;
font-stretch: normal;
font-style: italic;
src: url('ttf/iosevka-aile-heavyitalic.ttf') format('truetype'), url('woff2/iosevka-aile-heavyitalic.woff2') format('woff2');
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,11 +1,30 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="styles/main.css" />
<script src="js/nashboard.js"></script>
<script src="js/mainpage.js"></script>
<title>NashBoard</title>
</head>
<body>
Hello world!
</body>
</head>
<template id="booktag">
<span></span>
</template>
<template id="bookmark">
<div class="card">
<h3 id="bookmark_name"></h3>
<a id="bookmark_link" href=""></a>
<p id="bookmark_tags" class="tags"></p>
</div>
</template>
<body>
<div class="wrapper">
<h1>Dashboard protorype</h1>
<div id="bookmarks"></div>
</div>
</body>
</html>

9
static/js/loginpage.js Normal file
View File

@ -0,0 +1,9 @@
async function handleLogin(event) {
event.preventDefault();
const username = document.getElementById("username").value;
const password = document.getElementById("password").value;
const result = await login(username, password);
if (result) {
window.location.href = "/";
}
}

30
static/js/mainpage.js Normal file
View File

@ -0,0 +1,30 @@
window.addEventListener("load", async () => {
console.log("loading...");
const rootFolder = await getFolder();
const bm = document.getElementById("bookmarks");
if (!rootFolder.success) {
bm.textContent = "Нет закладок";
return;
}
const template = document.querySelector("#bookmark");
const tagtempl = document.querySelector("#booktag");
if (!template) {
return;
}
for (let b of rootFolder.folder.ChildBookmarks) {
const clone = template.content.cloneNode(true);
clone.querySelector("#bookmark_name").textContent = b.Name;
const link = clone.querySelector("#bookmark_link");
link.setAttribute("href", b.Url);
link.textContent = b.Url;
for (let tag of b.Tags) {
const t = tagtempl.content.cloneNode(true);
const el = t.querySelector("span");
el.addEventListener("onclick", () => alert(tag));
el.textContent = "#" + tag;
clone.querySelector("#bookmark_tags").appendChild(t);
}
bm.appendChild(clone);
}
});

57
static/js/nashboard.js Normal file
View File

@ -0,0 +1,57 @@
const baseUrl = "/api/";
function getSession() {
return localStorage.getItem("SessionID");
}
function request(url, method = "GET", data) {
let headers = [{ "Content-Type": "application/json" }];
const token = getSession();
if (token) headers.push({ SessionID: token });
let body = null;
if (method != "GET") {
body = JSON.stringify(data);
}
const r = new Request(baseUrl + url, {
method,
body,
headers: {
"Content-Type": "application/json",
SessionID: token,
},
});
return r;
}
function get(request) {}
async function login(username, password) {
const r = request("auth/login", "POST", { username, password });
try {
const result = await fetch(r);
if (result.status == 200) {
const token = await result.json();
localStorage.setItem("SessionID", token);
return true;
}
console.error({ status: result.status, body: await result.json() });
return false;
} catch (err) {
console.error(err);
return false;
}
}
async function getFolder(id) {
let url = "f";
if (id) url = `f/{id}`;
const r = request(url);
try {
const result = await fetch(r);
const folder = await result.json();
return { success: true, folder };
} catch (err) {
console.error(err);
return { success: false, err };
}
}

36
static/login.html Normal file
View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="styles/main.css" />
<script src="js/nashboard.js"></script>
<script src="js/loginpage.js"></script>
<title>Document</title>
</head>
<body>
<div class="wrapper">
<div class="panel">
<h1>Login</h1>
<form onsubmit="handleLogin(event)">
<input
type="text"
autocomplete="username"
placeholder="User"
name="username"
id="username"
/>
<input
type="password"
autocomplete="current-password"
placeholder="Password"
name="password"
id="password"
/>
<input class="accent" type="submit" value="Go" />
</form>
</div>
</div>
</body>
</html>

23
static/register.html Normal file
View File

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles/main.css">
<title>Document</title>
</head>
<body>
<div class="wrapper">
<div class="panel">
<h1>Login</h1>
<form action="#">
<input type="text" autocomplete="username" placeholder="User" name="username" id=password>
<input type="password" autocomplete="new-password" placeholder="Password" name="password" id="password">
<input type="password" autocomplete="new-password" placeholder="Confirm" name="password2" id="password2">
<input class="accent" type="submit" value="Go">
</form>
</div>
</div>
</body>
</html>

111
static/styles/main.css Normal file
View File

@ -0,0 +1,111 @@
@import url("../fonts/iosevka-aile.css");
:root {
--col-gr-100: #012;
--col-gr-200: #234;
--col-gr-300: #456;
--col-gr-400: #678;
--col-gr-500: #89a;
--col-gr-600: #abc;
--col-gr-700: #cde;
--col-gr-800: #def;
--col-acc-1: #d15c5c;
--col-acc-2: #f36d6d;
--col-acc-0: #993d3d;
--col-bg-1: var(--col-gr-600);
--col-bg-2: var(--col-gr-700);
--col-bg-3: var(--col-gr-800);
}
h1,
h2,
h3,
h4,
h5,
h6 {
padding: 0;
margin: 0;
}
body {
min-height: 100vh;
color: var(--col-main);
background-color: var(--col-bg-1);
font-family: "Iosevka Aile Web";
box-sizing: border-box;
font-size: 1.3rem;
margin: 0;
padding: 0;
}
.wrapper {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.panel {
display: flex;
flex-direction: column;
border-radius: 1em;
background-color: var(--col-bg-2);
box-shadow: 2px 2px 100px #1115;
text-align: center;
}
#bookmarks {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
.card {
display: flex;
flex-direction: column;
border-radius: 1em;
background-color: var(--col-bg-2);
box-shadow: 2px 2px 100px #1115;
text-align: left;
padding: 1em;
margin: 1em;
}
form {
display: flex;
flex-direction: column;
margin: 20px;
}
input {
background-color: var(--col-bg-3);
border: none;
border-radius: 5px;
padding: 1em 1em;
font-size: 1em;
margin: 1em 0;
}
input[type="submit"],
button,
.btn {
background-color: var(--col-acc-1);
transition: background-color 150ms ease;
color: white;
}
input[type="submit"]:hover,
button:hover,
.btn:hover {
background-color: var(--col-acc-2);
}
input[type="submit"]:focus,
button:focus,
.btn:focus {
background-color: var(--col-acc-0);
}
.accent {
background-color: var(--col-acc-1);
color: white;
}