2025-02-22
This commit is contained in:
parent
5d5918f0d7
commit
2212f4fc14
15 changed files with 175 additions and 264 deletions
|
|
@ -1,8 +1,8 @@
|
|||
<script setup lang="ts">
|
||||
import "@/styles/main.css";
|
||||
import { Transition } from "vue";
|
||||
import { RouterView } from "vue-router";
|
||||
import SidebarView from "@/views/SidebarView.vue";
|
||||
import { RouterView } from "vue-router";
|
||||
|
||||
import MainHeader from "./components/MainHeader.vue";
|
||||
</script>
|
||||
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
<MainHeader></MainHeader>
|
||||
|
||||
<RouterView v-slot="{ Component, route }">
|
||||
<Transition name="fade" mode="out-in">
|
||||
<Transition mode="out-in" name="fade">
|
||||
<component :is="Component" :key="route.path" />
|
||||
</Transition>
|
||||
</RouterView>
|
||||
|
|
|
|||
|
|
@ -1,22 +1,20 @@
|
|||
<script setup lang="ts">
|
||||
import A11yDialog from "a11y-dialog";
|
||||
import { useTemplateRef } from "vue";
|
||||
import { watchEffect } from "vue";
|
||||
import { ref } from "vue";
|
||||
import { computed } from "vue";
|
||||
import type { ComputedRef } from "vue";
|
||||
|
||||
const props = defineProps<{
|
||||
dialogId: string;
|
||||
toggled: boolean;
|
||||
}>();
|
||||
defineEmits<{
|
||||
(e: "dialog-hidden", dialogId: string): void;
|
||||
}>();
|
||||
import A11yDialog from "a11y-dialog";
|
||||
import { computed, ref, useTemplateRef, watchEffect } from "vue";
|
||||
|
||||
const dialogTitleId: ComputedRef<string> = computed(() => `${props.dialogId}-title`);
|
||||
const { dialogId, isToggled } = defineProps<{
|
||||
/** ID de la modale. */
|
||||
dialogId: string;
|
||||
/** Est-ce que la modale est activée ou non. */
|
||||
isToggled: boolean;
|
||||
}>();
|
||||
defineEmits<(e: "dialog-hidden", dialogId: string) => void>();
|
||||
|
||||
const dialogTitleId: ComputedRef<string> = computed(() => `${dialogId}-title`);
|
||||
const dialogContainer = useTemplateRef<HTMLDivElement>("dialog");
|
||||
let dialog = ref<A11yDialog>();
|
||||
const dialog = ref<A11yDialog>();
|
||||
|
||||
const closeDialog = () => dialog.value?.hide();
|
||||
|
||||
|
|
@ -24,7 +22,7 @@
|
|||
if (dialogContainer.value) {
|
||||
dialog.value = new A11yDialog(dialogContainer.value);
|
||||
}
|
||||
if (props.toggled) {
|
||||
if (isToggled) {
|
||||
dialog.value?.show();
|
||||
}
|
||||
});
|
||||
|
|
@ -32,15 +30,15 @@
|
|||
|
||||
<template>
|
||||
<div
|
||||
aria-hidden="true" :aria-labelledby="dialogTitleId" class="dialog"
|
||||
:id="dialogId" ref="dialog" @hide="$emit('dialog-hidden', dialogId)"
|
||||
:id="dialogId" ref="dialog" aria-hidden="true"
|
||||
:aria-labelledby="dialogTitleId" class="dialog" @hide="$emit('dialog-hidden', dialogId)"
|
||||
>
|
||||
<div class="dialog-content box" role="document">
|
||||
<header class="invert">
|
||||
<h2 :id="dialogTitleId">
|
||||
<slot name="title"></slot>
|
||||
</h2>
|
||||
<button @click="closeDialog" class="integrated" type="button">X</button>
|
||||
<button class="integrated" type="button" @click="closeDialog">X</button>
|
||||
</header>
|
||||
|
||||
<main class="box">
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
<nav id="primary-navigation">
|
||||
<ul>
|
||||
<li><RouterLink to="/">Accueil</RouterLink></li>
|
||||
<li><RouterLink to="/search">Recherche</RouterLink></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</aside>
|
||||
|
|
|
|||
64
src/components/SearchMediaDialog.vue
Normal file
64
src/components/SearchMediaDialog.vue
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<script setup lang="ts">
|
||||
import { useTemplateRef } from "vue";
|
||||
|
||||
import ImposterBox from "./ImposterBox.vue";
|
||||
|
||||
const { isToggled, toggleDialog } = defineProps<{
|
||||
/** Est-ce que la modale est activée ou non. */
|
||||
isToggled: boolean;
|
||||
/** Fonction déclenchant l'activation ou désactivation de la modale. */
|
||||
toggleDialog: () => void;
|
||||
}>();
|
||||
defineEmits<(e: "dialog-hidden", dialogId: string) => void>();
|
||||
|
||||
const form = useTemplateRef<HTMLFormElement>("form");
|
||||
|
||||
const resetAndClose = () => {
|
||||
form.value?.reset();
|
||||
toggleDialog();
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ImposterBox dialog-id="add-media" :is-toggled="isToggled" @dialog-hidden="resetAndClose">
|
||||
<template #title>Ajouter un média</template>
|
||||
<template #content>
|
||||
<form ref="form" class="stack">
|
||||
<fieldset class="cluster">
|
||||
<legend>Type du média</legend>
|
||||
<div class="field">
|
||||
<input
|
||||
id="film" checked name="media-type"
|
||||
type="radio" value="film"
|
||||
>
|
||||
<label for="film">Film</label>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<input
|
||||
id="series" name="media-type" type="radio"
|
||||
value="series"
|
||||
>
|
||||
<label for="series">Série</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<div class="field stack">
|
||||
<label for="media-title">Titre</label> <input id="media-title" type="text">
|
||||
</div>
|
||||
<div class="field stack">
|
||||
<label for="media-release-year">Année de sortie</label> <input id="media-release-year" type="number">
|
||||
</div>
|
||||
|
||||
<div class="cluster buttons">
|
||||
<button class="invert" type="submit">
|
||||
Rechercher
|
||||
</button>
|
||||
<button type="reset">
|
||||
Réinitialiser
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
</ImposterBox>
|
||||
</template>
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
import type { Config } from "drizzle-kit";
|
||||
|
||||
const DrizzleKitConfig: Config = { dialect: "sqlite", out: "./src/db/drizzle", schema: "./src/db/schemas.ts" };
|
||||
|
||||
export default DrizzleKitConfig;
|
||||
2
src/db/schemas.ts
Normal file
2
src/db/schemas.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
export * from "./schemas/entries";
|
||||
export * from "./schemas/works";
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import ImposterBox from "@/components/ImposterBox.vue";
|
||||
import type { Ref } from "vue";
|
||||
|
||||
import SearchMediaDialog from "@/components/SearchMediaDialog.vue";
|
||||
import { onMounted, ref } from "vue";
|
||||
|
||||
const toggleDialogStateRef = (stateRef: Ref<boolean, boolean>) => () => {
|
||||
|
|
@ -16,54 +17,14 @@
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<section class="cluster" id="buttons">
|
||||
<button @click="toggleAddMediaDialog" id="add-media-button" type="button">🬤 Ajouter un média</button>
|
||||
<section id="buttons" class="cluster">
|
||||
<button id="add-media-button" type="button" @click="toggleAddMediaDialog">🬤 Ajouter un média</button>
|
||||
<button id="" type="button">🬗 Rechercher une entrée</button>
|
||||
</section>
|
||||
|
||||
<section class="stack" id="last-watched-media">
|
||||
<section id="last-watched-media" class="stack">
|
||||
<h2>Derniers médias regardés</h2>
|
||||
</section>
|
||||
|
||||
<ImposterBox @dialog-hidden="toggleAddMediaDialog" :toggled="isAddMediaToggled" dialog-id="add-media">
|
||||
<template v-slot:title>Ajouter un média</template>
|
||||
<template v-slot:content>
|
||||
<form class="stack">
|
||||
<fieldset class="cluster">
|
||||
<legend>Type du média</legend>
|
||||
<div class="field">
|
||||
<input
|
||||
id="film" checked name="media-type"
|
||||
type="radio" value="film"
|
||||
>
|
||||
<label for="film">Film</label>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<input
|
||||
id="series" name="media-type" type="radio"
|
||||
value="series"
|
||||
>
|
||||
<label for="series">Série</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<div class="field stack">
|
||||
<label for="media-title">Titre</label> <input id="media-title" type="text">
|
||||
</div>
|
||||
<div class="field stack">
|
||||
<label for="media-release-year">Année de sortie</label> <input id="media-release-year" type="number">
|
||||
</div>
|
||||
|
||||
<div class="cluster buttons">
|
||||
<button class="invert" type="submit">
|
||||
Rechercher
|
||||
</button>
|
||||
<button type="reset">
|
||||
Réinitialiser
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
</ImposterBox>
|
||||
<SearchMediaDialog :is-toggled="isAddMediaToggled" :toggle-dialog="toggleAddMediaDialog"></SearchMediaDialog>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<section class="stack" id="404">
|
||||
<section id="404" class="stack">
|
||||
<h2>404</h2>
|
||||
</section>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -43,6 +43,47 @@
|
|||
list-style: none;
|
||||
}
|
||||
|
||||
:where(input[type="text"], input[type="number"]) {
|
||||
padding: var(--s-4);
|
||||
}
|
||||
|
||||
:where(input[type="radio"]) {
|
||||
aspect-ratio: 1/1;
|
||||
border: 1px solid var(--color-primary);
|
||||
background: var(--color-secondary);
|
||||
border-radius: 50%;
|
||||
inline-size: var(--s-1);
|
||||
block-size: var(--s-1);
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
background: var(--color-primary);
|
||||
border-radius: inherit;
|
||||
content: "";
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
inline-size: var(--s-2);
|
||||
block-size: var(--s-2);
|
||||
}
|
||||
|
||||
+ label {
|
||||
padding-left: var(--s-2);
|
||||
}
|
||||
}
|
||||
|
||||
:where(input[type="radio"]:checked) {
|
||||
&::after {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
:where(fieldset > legend) {
|
||||
margin-block-end: var(--s0);
|
||||
}
|
||||
|
||||
:where(a) {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,13 +13,13 @@
|
|||
|
||||
.dialog-content {
|
||||
position: relative; /* 2 */
|
||||
min-inline-size: 40ch;
|
||||
max-inline-size: 80ch;
|
||||
margin: auto; /* 1 */
|
||||
padding: initial;
|
||||
border: 1px solid var(--color-primary);
|
||||
background-color: var(--color-secondary);
|
||||
box-shadow: 0.5rem 0.5rem 0 0 var(--color-primary);
|
||||
animation: fade-in 100ms 10ms both;
|
||||
|
||||
header {
|
||||
overflow: hidden;
|
||||
|
|
@ -41,15 +41,3 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.dialog-overlay, .dialog-content {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue