FitLog/src/routes/+page.svelte
itsscb c13c0e3323
All checks were successful
Build and Deploy Svelte App / build-and-deploy (push) Successful in 2m5s
feat: add style to buttons
2025-04-14 21:44:12 +02:00

226 lines
3.8 KiB
Svelte

<script lang="ts">
import { onMount } from "svelte";
import type { WorkoutEntry } from "$lib/types";
import { getWorkouts, saveWorkouts } from "$lib/storage";
import { Save, Trash2 } from "@lucide/svelte";
let workouts: WorkoutEntry[] = $state([]);
let date = $state("");
let workout_type = $state("");
let duration_minutes = $state(0);
let selected_cell: `${number}:${number}` | undefined = $state(undefined);
onMount(() => {
const today = new Date();
date = today.toISOString().split("T")[0];
workouts = getWorkouts();
});
function deleteRow(index: number) {
workouts = workouts.toSpliced(index, 1); // modern way to remove immutably
saveWorkouts(workouts);
}
function updateRow(index: number) {
alert(`Update row #${index + 1}`);
}
function on_save() {
const workout: WorkoutEntry = {
date: date,
workout_type: workout_type,
duration_minutes: duration_minutes,
};
workouts.push(workout);
saveWorkouts(workouts);
}
</script>
<h1>FitLog <i>(0.0.3)</i></h1>
<form onsubmit={on_save}>
<table>
<thead>
<tr>
<th>Date</th>
<th>Workout</th>
<th>Minutes</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input
type="date"
bind:value={date}
placeholder="Enter date"
required
/>
</td>
<td
><input
type="text"
bind:value={workout_type}
placeholder="Enter workout type"
required
/></td
>
<td
><input
type="number"
bind:value={duration_minutes}
placeholder="Enter duration in Minutes"
min="15"
step="15"
required
/>
</td>
<td>
<button type="submit" class="button button-save">
<Save color="green" />
</button>
</td>
</tr>
{#if workouts.length < 1}
<tr
><td colspan="4" style="text-align: center;"
><p>No entries.. yet!</p></td
></tr
>
{:else}
{#each workouts as wk, i}
<tr>
<td>{wk.date}</td>
<td>{wk.workout_type}</td>
<td>{wk.duration_minutes}</td>
<td>
<a
class="button button-delete"
role="button"
tabindex={i}
onclick={(e) => {
e.stopPropagation();
e.preventDefault();
deleteRow(i);
}}
>
<Trash2 color="red" />
</a>
</td>
</tr>
{/each}
{/if}
</tbody>
</table>
</form>
<style>
:global body {
background-color: #222;
color: white;
}
table {
width: 100%;
border-collapse: collapse;
border-radius: 12px;
overflow: hidden;
}
thead {
background-color: #2d89ef;
color: #fff;
}
th,
td {
text-align: left;
padding: 16px;
}
tr:nth-child(even) {
background-color: #f2f2f2;
color: #000;
}
tbody tr:hover {
background-color: #c2c2c2;
color: #000;
}
th {
font-size: 1rem;
}
td {
font-size: 0.95rem;
}
.button {
width: 3rem;
height: 2rem;
cursor: pointer;
border-radius: 5px;
background-color: white;
border: solid;
border-width: 2px;
}
.button-delete {
display: flex;
justify-content: center;
text-align: center;
align-items: center;
vertical-align: middle;
border-color: red;
color: red;
}
.button-save {
background-color: white;
border-color: green;
color: green;
}
.button-save:hover {
background-color: green;
border-color: green;
}
.button-delete:hover {
background-color: red;
border-color: red;
}
:global .button:hover svg {
stroke: white;
}
input[type="text"] {
width: 100%;
padding: 8px;
box-sizing: border-box;
font-size: 0.9rem;
border: 1px solid #ccc;
border-radius: 6px;
}
input:focus {
outline: none;
border-color: #2d89ef;
box-shadow: 0 0 0 2px rgba(45, 137, 239, 0.2);
}
input[type="date"],
input[type="number"] {
width: 100%;
padding: 8px;
font-size: 0.9rem;
border: 1px solid #ccc;
border-radius: 6px;
box-sizing: border-box;
}
</style>