frontend of sidebar
This commit is contained in:
parent
84aa9b3e22
commit
18c94bd7a0
|
@ -4,6 +4,7 @@
|
|||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="/img/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/index.css" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<script lang="ts">
|
||||
export const projectId: number = 0;
|
||||
</script>
|
||||
|
||||
{#if Number.isNaN(projectId)}
|
||||
<p>Invalid number</p>
|
||||
{:else}
|
||||
<p>Hello on dashboard {projectId}!</p>
|
||||
{/if}
|
|
@ -0,0 +1,82 @@
|
|||
<script lang="ts">
|
||||
import { projects } from "../stores/projects";
|
||||
|
||||
let newProject = false;
|
||||
let editProject: number | undefined = undefined;
|
||||
|
||||
function handleKeydown(event: KeyboardEvent, id: number | undefined = undefined) {
|
||||
if (event.key === 'Enter' && event.target) {
|
||||
if(id !== undefined){
|
||||
projects.edit({
|
||||
id: id,
|
||||
title: (event.target as HTMLInputElement).value
|
||||
})
|
||||
editProject = undefined;
|
||||
} else {
|
||||
createNewProject((event.target as HTMLInputElement).value);
|
||||
newProject = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createNewProject(value: string) {
|
||||
projects.add({
|
||||
title: value,
|
||||
id: undefined
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<link rel="stylesheet" type="text/css" href="/css/sidebar.css" />
|
||||
</svelte:head>
|
||||
|
||||
<div id="sidebar" class="sidebar">
|
||||
<div class="logo">
|
||||
<a href="/">
|
||||
<img src="img/icon.svg" alt="">
|
||||
<span class="title">Focus</span>
|
||||
<span class="version">v0.0.1</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="boards">
|
||||
{#await projects.init()}
|
||||
<p>Loading ...</p>
|
||||
{:then}
|
||||
<h2>Projects</h2>
|
||||
<ul>
|
||||
{#each $projects as project}
|
||||
<li>
|
||||
{#if editProject === project.id}
|
||||
<input
|
||||
type="text"
|
||||
on:keydown={(e) => handleKeydown(e, project.id)}
|
||||
value={project.title}
|
||||
class="edit-input"
|
||||
/>
|
||||
{:else}
|
||||
<a href="/{project.id}">{project.title}</a><span class="edit-icon" on:click={() => editProject = project.id}>️
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="18" viewBox="0 0 576 512"><path d="M402.6 83.2l90.2 90.2c3.8 3.8 3.8 10 0 13.8L274.4 405.6l-92.8 10.3c-12.4 1.4-22.9-9.1-21.5-21.5l10.3-92.8L388.8 83.2c3.8-3.8 10-3.8 13.8 0zm162-22.9l-48.8-48.8c-15.2-15.2-39.9-15.2-55.2 0l-35.4 35.4c-3.8 3.8-3.8 10 0 13.8l90.2 90.2c3.8 3.8 10 3.8 13.8 0l35.4-35.4c15.2-15.3 15.2-40 0-55.2zM384 346.2V448H64V128h229.8c3.2 0 6.2-1.3 8.5-3.5l40-40c7.6-7.6 2.2-20.5-8.5-20.5H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V306.2c0-10.7-12.9-16-20.5-8.5l-40 40c-2.2 2.3-3.5 5.3-3.5 8.5z" fill="#aaa"/></svg>
|
||||
</span>
|
||||
{/if}
|
||||
</li>
|
||||
{/each}
|
||||
{#if newProject}
|
||||
<li>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Enter project title"
|
||||
on:keydown={handleKeydown}
|
||||
style="padding: 8px; border: 1px solid #ccc; border-radius: 4px; width: 100%;" />
|
||||
</li>
|
||||
{/if}
|
||||
</ul>
|
||||
{:catch error}
|
||||
<p>Something went wrong: {error.message}</p>
|
||||
{/await}
|
||||
</div>
|
||||
<div class="bottom-links">
|
||||
<span on:click={() => newProject = true}>New project</span>
|
||||
<span>Settings</span>
|
||||
</div>
|
||||
</div>
|
|
@ -1,33 +1,6 @@
|
|||
<script>
|
||||
import { projects } from "../stores/projects";
|
||||
import Sidebar from "../components/sidebar.svelte";
|
||||
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<link rel="stylesheet" type="text/css" href="/css/index.css" />
|
||||
</svelte:head>
|
||||
|
||||
{#await projects.init()}
|
||||
<p>Loading ...</p>
|
||||
{:then}
|
||||
<div id="sidebar" class="sidebar">
|
||||
<div class="logo">
|
||||
<img src="img/icon.svg" alt="">
|
||||
<span class="title">Focus</span>
|
||||
<span class="version">v0.0.1</span>
|
||||
</div>
|
||||
<div class="boards">
|
||||
<h2>Projects</h2>
|
||||
<ul>
|
||||
{#each $projects as project}
|
||||
<!-- <li><a href="/{{project.id}}">{{project.title}}</a></li> -->
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bottom-links">
|
||||
<a href="#">Add board</a>
|
||||
<a href="#">Settings</a>
|
||||
</div>
|
||||
</div>
|
||||
{:catch error}
|
||||
<p>Something went wrong: {error.message}</p>
|
||||
{/await}
|
||||
<Sidebar />
|
|
@ -0,0 +1,10 @@
|
|||
<script lang="ts">
|
||||
import Project from "../../components/project.svelte";
|
||||
import Sidebar from "../../components/sidebar.svelte";
|
||||
import { page } from '$app/stores';
|
||||
|
||||
let projectId: number = +$page.params.project;
|
||||
</script>
|
||||
|
||||
<Sidebar />
|
||||
<Project {projectId} />
|
|
@ -6,23 +6,51 @@ export const projects = getProjects();
|
|||
const backend = 'http://127.0.0.1:3000'
|
||||
|
||||
interface Project {
|
||||
id: number,
|
||||
id: number | undefined,
|
||||
title: string,
|
||||
}
|
||||
|
||||
function getProjects() {
|
||||
const { subscribe, set, update } = writable([]);
|
||||
const { subscribe, set, update } = writable([] as Project[]);
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
init: async () => {
|
||||
const response = await axios.get(`${backend}/api/projects`)
|
||||
console.log(response.data)
|
||||
const response = await axios.get(`${backend}/api/projects`);
|
||||
|
||||
if(response.status < 303) {
|
||||
const projects: Project[] = response.data;
|
||||
const data: Project[] = response.data;
|
||||
|
||||
return projects;
|
||||
set(data);
|
||||
|
||||
return data;
|
||||
}
|
||||
},
|
||||
add: async (project: Project) => {
|
||||
const response = await axios.post(`${backend}/api/project`, project);
|
||||
|
||||
if(response.status < 303) {
|
||||
project.id = response.data["id"];
|
||||
update((oldProjects) => {
|
||||
oldProjects.push(project)
|
||||
return oldProjects;
|
||||
});
|
||||
}
|
||||
},
|
||||
edit: async (project: Project) => {
|
||||
const response = await axios.put(`${backend}/api/project/${project.id}`, project)
|
||||
|
||||
|
||||
if(response.status < 303) {
|
||||
update((oldProjects: Project[]) => {
|
||||
for(let p of oldProjects){
|
||||
if(p.id === project.id){
|
||||
p.title = project.title;
|
||||
}
|
||||
}
|
||||
|
||||
return oldProjects;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,71 +3,6 @@ body {
|
|||
font-family: "Open sans", sans-serif;
|
||||
color: white;
|
||||
background-color: #2b2e30;
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
width: 240px;
|
||||
background-color: #262a2b;
|
||||
color: white;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#sidebar .logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#sidebar .logo img {
|
||||
max-height: 30px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
#sidebar .logo .title {
|
||||
padding-right: 10px;
|
||||
}
|
||||
#sidebar .logo .version {
|
||||
font-size: 0.8em;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
#sidebar .boards h2 {
|
||||
padding-left: 10px;
|
||||
font-size: 0.9em;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#sidebar .boards ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#sidebar .boards ul li a {
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
display: block;
|
||||
padding: 5px 10px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
#sidebar .boards ul li a:hover {
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
#sidebar .bottom-links {
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
#sidebar .bottom-links a {
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
display: block;
|
||||
padding: 10px;
|
||||
font-size: 0.9em;
|
||||
border-top: 1px solid #444;
|
||||
padding: 0;
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
#sidebar {
|
||||
width: 240px;
|
||||
background-color: #262a2b;
|
||||
color: white;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#sidebar .logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#sidebar .logo img {
|
||||
max-height: 30px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
#sidebar .logo .title {
|
||||
padding-right: 10px;
|
||||
}
|
||||
#sidebar .logo .version {
|
||||
font-size: 0.8em;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
#sidebar .boards h2 {
|
||||
padding-left: 10px;
|
||||
font-size: 0.9em;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#sidebar .boards ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#sidebar a {
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#sidebar .boards ul li:hover {
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
#sidebar .bottom-links {
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
#sidebar .bottom-links span {
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
display: block;
|
||||
padding: 10px;
|
||||
font-size: 0.9em;
|
||||
border-top: 1px solid #444;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#sidebar li {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
#sidebar .edit-icon {
|
||||
visibility: hidden;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#sidebar li:hover .edit-icon {
|
||||
visibility: visible;
|
||||
}
|
Loading…
Reference in New Issue