quita la ruta todos que no viene a cuento
parent
99a359719f
commit
09cf8666a8
@ -1,52 +1,52 @@
|
||||
<script>
|
||||
/**
|
||||
* Un objeto con los datos que llegan de la funcion load de +page.js
|
||||
* @typedef {{
|
||||
* slug: string;
|
||||
* templateIndex: number;
|
||||
* templateImage: string;
|
||||
* }}
|
||||
* LoadFunctionData
|
||||
*/
|
||||
|
||||
/** @type LoadFunctionData */ export let data;
|
||||
|
||||
import Form from '$lib/form/Form.svelte';
|
||||
import Preview from '$lib/preview/Preview.svelte';
|
||||
|
||||
const templateIndex = data.templateIndex;
|
||||
const templateImage = data.templateImage;
|
||||
/**
|
||||
* Un objeto con los datos que llegan de la funcion load de +page.js
|
||||
* @typedef {{
|
||||
* slug: string;
|
||||
* templateIndex: number;
|
||||
* templateImage: string;
|
||||
* }}
|
||||
* LoadFunctionData
|
||||
*/
|
||||
|
||||
/** @type LoadFunctionData */ export let data;
|
||||
|
||||
import Form from "$lib/form/Form.svelte";
|
||||
import Preview from "$lib/preview/Preview.svelte";
|
||||
|
||||
const templateIndex = data.templateIndex;
|
||||
const templateImage = data.templateImage;
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Carteles DMD - Plantilla {data.slug}</title>
|
||||
<title>Carteles DMD - Plantilla {data.slug}</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="main">
|
||||
<section class="form"><Form /></section>
|
||||
<section class="form"><Form /></section>
|
||||
|
||||
{#if templateIndex !== undefined}
|
||||
<section class="preview">
|
||||
<Preview {templateIndex} {templateImage} />
|
||||
</section>
|
||||
{/if}
|
||||
{#if templateIndex !== undefined}
|
||||
<section class="preview">
|
||||
<Preview {templateIndex} {templateImage} />
|
||||
</section>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.main {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 616px;
|
||||
grid-gap: 0.5rem;
|
||||
min-height: calc(100vh - 5rem);
|
||||
}
|
||||
|
||||
.form {
|
||||
grid-column: 1/2;
|
||||
background-color: rgb(236, 240, 240);
|
||||
}
|
||||
|
||||
.preview {
|
||||
grid-column: 2/3;
|
||||
background-color: rgb(240, 240, 240);
|
||||
}
|
||||
.main {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 616px;
|
||||
grid-gap: 0.5rem;
|
||||
min-height: calc(100vh - 5rem);
|
||||
}
|
||||
|
||||
.form {
|
||||
grid-column: 1/2;
|
||||
background-color: rgb(236, 240, 240);
|
||||
}
|
||||
|
||||
.preview {
|
||||
grid-column: 2/3;
|
||||
background-color: rgb(240, 240, 240);
|
||||
}
|
||||
</style>
|
||||
|
@ -1,66 +0,0 @@
|
||||
import { error } from '@sveltejs/kit';
|
||||
import { api } from './api';
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* uid: string;
|
||||
* created_at: Date;
|
||||
* text: string;
|
||||
* done: boolean;
|
||||
* pending_delete: boolean;
|
||||
* }} Todo
|
||||
*/
|
||||
|
||||
/** @type {import('./$types').PageServerLoad} */
|
||||
export const load = async ({ locals }) => {
|
||||
// locals.userid comes from src/hooks.js
|
||||
const response = await api('GET', `todos/${locals.userid}`);
|
||||
|
||||
if (response.status === 404) {
|
||||
// user hasn't created a todo list.
|
||||
// start with an empty array
|
||||
return {
|
||||
/** @type {Todo[]} */
|
||||
todos: []
|
||||
};
|
||||
}
|
||||
|
||||
if (response.status === 200) {
|
||||
return {
|
||||
/** @type {Todo[]} */
|
||||
todos: await response.json()
|
||||
};
|
||||
}
|
||||
|
||||
throw error(response.status);
|
||||
};
|
||||
|
||||
/** @type {import('./$types').Actions} */
|
||||
export const actions = {
|
||||
add: async ({ request, locals }) => {
|
||||
const form = await request.formData();
|
||||
|
||||
await api('POST', `todos/${locals.userid}`, {
|
||||
text: form.get('text')
|
||||
});
|
||||
},
|
||||
edit: async ({ request, locals }) => {
|
||||
const form = await request.formData();
|
||||
|
||||
await api('PATCH', `todos/${locals.userid}/${form.get('uid')}`, {
|
||||
text: form.get('text')
|
||||
});
|
||||
},
|
||||
toggle: async ({ request, locals }) => {
|
||||
const form = await request.formData();
|
||||
|
||||
await api('PATCH', `todos/${locals.userid}/${form.get('uid')}`, {
|
||||
done: !!form.get('done')
|
||||
});
|
||||
},
|
||||
delete: async ({ request, locals }) => {
|
||||
const form = await request.formData();
|
||||
|
||||
await api('DELETE', `todos/${locals.userid}/${form.get('uid')}`);
|
||||
}
|
||||
};
|
@ -1,182 +0,0 @@
|
||||
<script>
|
||||
import { enhance } from '$app/forms';
|
||||
import { invalidateAll } from '$app/navigation';
|
||||
import { scale } from 'svelte/transition';
|
||||
import { flip } from 'svelte/animate';
|
||||
|
||||
/** @type {import('./$types').PageData} */
|
||||
export let data;
|
||||
$: todos = data.todos;
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Todos</title>
|
||||
<meta name="description" content="A todo list app" />
|
||||
</svelte:head>
|
||||
|
||||
<div class="todos">
|
||||
<h1>Todos</h1>
|
||||
|
||||
<form
|
||||
class="new"
|
||||
action="/todos?/add"
|
||||
method="post"
|
||||
use:enhance={() => {
|
||||
return ({ form, result }) => {
|
||||
if (result.type === 'success') {
|
||||
form.reset();
|
||||
invalidateAll();
|
||||
}
|
||||
};
|
||||
}}
|
||||
>
|
||||
<input name="text" aria-label="Add todo" placeholder="+ tap to add a todo" />
|
||||
</form>
|
||||
|
||||
{#each todos as todo (todo.uid)}
|
||||
<div
|
||||
class="todo"
|
||||
class:done={todo.done}
|
||||
transition:scale|local={{ start: 0.7 }}
|
||||
animate:flip={{ duration: 200 }}
|
||||
>
|
||||
<form
|
||||
action="/todos?/toggle"
|
||||
method="post"
|
||||
use:enhance={({ data }) => {
|
||||
todo.done = !!data.get('done');
|
||||
}}
|
||||
>
|
||||
<input type="hidden" name="uid" value={todo.uid} />
|
||||
<input type="hidden" name="done" value={todo.done ? '' : 'true'} />
|
||||
<button class="toggle" aria-label="Mark todo as {todo.done ? 'not done' : 'done'}" />
|
||||
</form>
|
||||
|
||||
<form class="text" action="/todos?/edit" method="post" use:enhance>
|
||||
<input type="hidden" name="uid" value={todo.uid} />
|
||||
<input aria-label="Edit todo" type="text" name="text" value={todo.text} />
|
||||
<button class="save" aria-label="Save todo" />
|
||||
</form>
|
||||
|
||||
<form
|
||||
action="/todos?/delete"
|
||||
method="post"
|
||||
use:enhance={() => {
|
||||
todo.pending_delete = true;
|
||||
}}
|
||||
>
|
||||
<input type="hidden" name="uid" value={todo.uid} />
|
||||
<button class="delete" aria-label="Delete todo" disabled={todo.pending_delete} />
|
||||
</form>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.todos {
|
||||
width: 100%;
|
||||
max-width: var(--column-width);
|
||||
margin: var(--column-margin-top) auto 0 auto;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.new {
|
||||
margin: 0 0 0.5rem 0;
|
||||
}
|
||||
|
||||
input {
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
input:focus-visible {
|
||||
border: 1px solid #ff3e00 !important;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.new input {
|
||||
font-size: 28px;
|
||||
width: 100%;
|
||||
padding: 0.5em 1em 0.3em 1em;
|
||||
box-sizing: border-box;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.todo {
|
||||
display: grid;
|
||||
grid-template-columns: 2rem 1fr 2rem;
|
||||
grid-gap: 0.5rem;
|
||||
align-items: center;
|
||||
margin: 0 0 0.5rem 0;
|
||||
padding: 0.5rem;
|
||||
background-color: white;
|
||||
border-radius: 8px;
|
||||
filter: drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.1));
|
||||
transform: translate(-1px, -1px);
|
||||
transition: filter 0.2s, transform 0.2s;
|
||||
}
|
||||
|
||||
.done {
|
||||
transform: none;
|
||||
opacity: 0.4;
|
||||
filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.1));
|
||||
}
|
||||
|
||||
form.text {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.todo input {
|
||||
flex: 1;
|
||||
padding: 0.5em 2em 0.5em 0.8em;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.todo button {
|
||||
width: 2em;
|
||||
height: 2em;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
button.toggle {
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
border-radius: 50%;
|
||||
box-sizing: border-box;
|
||||
background-size: 1em auto;
|
||||
}
|
||||
|
||||
.done .toggle {
|
||||
background-image: url("data:image/svg+xml,%3Csvg width='22' height='16' viewBox='0 0 22 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20.5 1.5L7.4375 14.5L1.5 8.5909' stroke='%23676778' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.delete {
|
||||
background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4.5 5V22H19.5V5H4.5Z' fill='%23676778' stroke='%23676778' stroke-width='1.5' stroke-linejoin='round'/%3E%3Cpath d='M10 10V16.5' stroke='white' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M14 10V16.5' stroke='white' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M2 5H22' stroke='%23676778' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M8 5L9.6445 2H14.3885L16 5H8Z' fill='%23676778' stroke='%23676778' stroke-width='1.5' stroke-linejoin='round'/%3E%3C/svg%3E%0A");
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.delete:hover,
|
||||
.delete:focus {
|
||||
transition: opacity 0.2s;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.save {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
opacity: 0;
|
||||
background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20.5 2H3.5C2.67158 2 2 2.67157 2 3.5V20.5C2 21.3284 2.67158 22 3.5 22H20.5C21.3284 22 22 21.3284 22 20.5V3.5C22 2.67157 21.3284 2 20.5 2Z' fill='%23676778' stroke='%23676778' stroke-width='1.5' stroke-linejoin='round'/%3E%3Cpath d='M17 2V11H7.5V2H17Z' fill='white' stroke='white' stroke-width='1.5' stroke-linejoin='round'/%3E%3Cpath d='M13.5 5.5V7.5' stroke='%23676778' stroke-width='1.5' stroke-linecap='round'/%3E%3Cpath d='M5.99844 2H18.4992' stroke='%23676778' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E%0A");
|
||||
}
|
||||
|
||||
.todo input:focus + .save,
|
||||
.save:focus {
|
||||
transition: opacity 0.2s;
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
@ -1,25 +0,0 @@
|
||||
/*
|
||||
This module is used by the /todos endpoint to
|
||||
make calls to api.svelte.dev, which stores todos
|
||||
for each user.
|
||||
|
||||
(The data on the todo app will expire periodically; no
|
||||
guarantees are made. Don't use it to organise your life.)
|
||||
*/
|
||||
|
||||
const base = 'https://api.svelte.dev';
|
||||
|
||||
/**
|
||||
* @param {string} method
|
||||
* @param {string} resource
|
||||
* @param {Record<string, unknown>} [data]
|
||||
*/
|
||||
export function api(method, resource, data) {
|
||||
return fetch(`${base}/${resource}`, {
|
||||
method,
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
body: data && JSON.stringify(data)
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue