Compare commits
9 Commits
aa46d17a47
...
feature/ui
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
967b6114e1 | ||
|
|
1b35e137d3 | ||
|
|
e24b3e1955 | ||
|
|
6d6d70295d | ||
|
|
b9719e0c98 | ||
|
|
f979c701c3 | ||
|
|
3d46a868c6 | ||
|
|
4162435da9 | ||
|
|
4b43c0c7e7 |
38
app.vue
38
app.vue
@@ -1,35 +1,7 @@
|
||||
<template>
|
||||
<div class="content-wrapper">
|
||||
<ContentRenderer :value="doc" v-if="!isMobile" /> <!-- Render the markdown content for laptop -->
|
||||
<ContentRenderer :value="mobileDoc" v-if="isMobile" /> <!-- Render the markdown content for mobile -->
|
||||
</div>
|
||||
<video controls width="640">
|
||||
<source src="/videos/video.mp4" type="video/mp4" />
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
<NuxtLayout>
|
||||
<v-app>
|
||||
<NuxtPage />
|
||||
</v-app>
|
||||
</NuxtLayout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// Import Vue's reactive and ref from 'vue'
|
||||
import { ref, onMounted } from 'vue'
|
||||
|
||||
// Determine if the device is mobile
|
||||
const isMobile = ref(false)
|
||||
|
||||
// Fetch the markdown content files asynchronously
|
||||
const { data: doc } = await useAsyncData('markdownDoc', () =>
|
||||
queryContent('markdown_laptop').findOne()
|
||||
)
|
||||
const { data: mobileDoc } = await useAsyncData('mobileMarkdownDoc', () =>
|
||||
queryContent('markdown_mobile').findOne()
|
||||
)
|
||||
|
||||
// Add event listener to update isMobile based on window resize when the component is mounted
|
||||
onMounted(() => {
|
||||
isMobile.value = window.innerWidth <= 768
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
isMobile.value = window.innerWidth <= 768
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
3
assets/css/main.css
Normal file
3
assets/css/main.css
Normal file
@@ -0,0 +1,3 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@@ -1,72 +0,0 @@
|
||||
.background{
|
||||
background-color:#F5F5F5;}
|
||||
.content-wrapper {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.content-wrapper h1 {
|
||||
text-align: center;
|
||||
color: #6A994E;
|
||||
font-size: 2.5em;
|
||||
margin: 20px 0;
|
||||
text-transform: uppercase;}
|
||||
.content-wrapper h2 {
|
||||
font-size: 1em;
|
||||
}
|
||||
.content-wrapper h2 a {
|
||||
text-decoration: none; /* Supprime le soulignement */
|
||||
cursor: default;
|
||||
}
|
||||
.content-wrapper h2 span {
|
||||
color: #474405;
|
||||
}
|
||||
.content-wrapper h4 {
|
||||
text-align: center; /* Centre horizontalement le texte dans <h4> */
|
||||
}
|
||||
.content-wrapper h4 a {
|
||||
text-decoration: none; /* Supprime le soulignement */
|
||||
color: #8B5E3C;
|
||||
cursor: default;
|
||||
|
||||
}
|
||||
|
||||
.content-wrapper h5 {
|
||||
color: #8B5E3C; /* Vert pour souligner les sous-sections */
|
||||
font-size: 1em;
|
||||
margin-top: 20px;
|
||||
margin: 10px 10px;
|
||||
}
|
||||
.content-wrapper p{
|
||||
font-weight: normal;
|
||||
margin: 10px 10px ;
|
||||
text-align: justify;
|
||||
font-size: 0.98em;
|
||||
color:#8B5E3C;
|
||||
}
|
||||
/* assets/main.css */
|
||||
|
||||
video {
|
||||
border: 2px solid #474405;
|
||||
border-radius: 8px;
|
||||
max-width: 100%; /* Responsive width */
|
||||
display: block; /* Center the video */
|
||||
margin: 20px auto;
|
||||
}
|
||||
/* assets/main.css */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
13
components/Loader.vue
Normal file
13
components/Loader.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<v-container style="height: 600px;">
|
||||
<v-row align-content="center" class="fill-height" justify="center">
|
||||
<v-col class="text-xl text-center text-bold text-uppercase font-sans " cols="12">
|
||||
Soyez le bienvenue sur DAV
|
||||
</v-col>
|
||||
<v-col cols="6">
|
||||
<v-progress-linear color="primary" height="6" indeterminate
|
||||
rounded></v-progress-linear>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
13
content/articles/article-1.md
Normal file
13
content/articles/article-1.md
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
id: "article-1"
|
||||
title: Article 1. Reconnaissance universelle de l'Âme et des formes de vie
|
||||
type: "article"
|
||||
|
||||
|
||||
---
|
||||
|
||||
# Article 1. Reconnaissance universelle de l'Âme et des formes de vie
|
||||
|
||||
Toute forme de vie du micro et du macrocosme est considérée comme animée d'une Âme et comme étant un prolongement de l'humain, gardien du Vivant et de la Liberté.
|
||||
L'humain est considéré comme intrinsèquement lié à la nature et ne peut en aucun cas mener une ou des activités visant à attenter délibérément à la vie et à entrer en ingérence avec une espèce considérée comme moins évoluée en lui imposant tout traitement ou oppression quelle qu'elle soit.
|
||||
L'humain doit respecter les formes de vie, en assurer la protection, la sauvegarde et l’épanouissement de façon non-invasive / intrusive, sauf en cas de stricte nécessité pour préserver un équilibre vital. afin de cohabiter avec elles en bonne intelligence, dans la complémentarité et l'abondance.
|
||||
13
content/articles/article-10.md
Normal file
13
content/articles/article-10.md
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
id: "article-10"
|
||||
title: Article 10. Liberté d’opinion, de croyance et de pratique
|
||||
type: "article"
|
||||
|
||||
---
|
||||
|
||||
# Article 10. Liberté d’opinion, de croyance et de pratique
|
||||
<span>Toute forme de vie consciente a droit à la liberté d’opinion, de croyance, et de pratique, sous réserve que l’expression de ces libertés ne perturbe pas l’harmonie collective, ne porte atteinte aux droits d’autrui, et ne mette pas en danger la vie de manière intentionnelle ou par négligence grave.</span>
|
||||
<span>Aucune personne, groupe ou institution ne peut imposer, restreindre ou discriminer une opinion, une croyance ou une pratique, tant que celles-ci respectent les principes fondamentaux du Vivant et de la coexistence pacifique.</span>
|
||||
<span>Toute tentative de coercition visant à manipuler, contraindre ou marginaliser des individus ou groupes sur la base de leurs opinions ou croyances constitue une violation des DAV, et sera traitée conformément aux lois en vigueur.</span>
|
||||
<span>La liberté d’expression et de croyance s’accompagne de la responsabilité d’agir avec bienveillance, respect et discernement pour préserver l’équilibre universel et le bien-être collectif.</span>
|
||||
</p>
|
||||
13
content/articles/article-11.md
Normal file
13
content/articles/article-11.md
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
id: "article-11"
|
||||
title: Article 11. Légitimité des structures sociétales
|
||||
type: "article"
|
||||
|
||||
---
|
||||
|
||||
# Article 11. Légitimité des structures sociétales
|
||||
<p>
|
||||
<span>Toute société, association ou fondation doit garantir en son fonctionnement le respect absolu des DAV. Ces droits doivent constituer les fondements de leur existence et de leurs actions.</span>
|
||||
<span>De plus, la séparation claire et équilibrée des pouvoirs au sein de ces structures est une condition essentielle pour prévenir toute concentration abusive de pouvoir et pour assurer une gouvernance équitable et transparente.</span>
|
||||
<span>En l’absence de ces garanties fondamentales – le respect des droits et une organisation équitable des responsabilités – une telle entité ne peut être reconnue comme possédant une constitution légitime ou une autorité morale.</span>
|
||||
</p>
|
||||
29
content/articles/article-12.md
Normal file
29
content/articles/article-12.md
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
id: "article-12"
|
||||
title: Article 12. La Force Opérationnelle de Recherche et de Création Éthérée-probiotique
|
||||
type: "article"
|
||||
|
||||
---
|
||||
|
||||
# Article 12. La F.O.R.C.E : Force Opérationnelle de Recherche et de Création Éthérée-probiotique
|
||||
<p>
|
||||
<span>La garantie du respect des DAV, ainsi que leur mise en application, exige la constitution d’une force dédiée à la réflexion, à la coordination et à l’action.</span>
|
||||
<span>Cette force, nommée F.O.R.C.E (Force Opérationnelle de Recherche et de Création Éthérée-vivante), repose sur une vision holistique qui allie la subtilité des principes éthériques – ces dimensions invisibles et énergétiques qui soutiennent la vie – et des actions concrètes en faveur de la vie, selon la conceptualisation du Vivalisme ».</span>
|
||||
<span>Elle agit ainsi à la fois sur les plans immatériel et matériel pour préserver l’équilibre, garantir l’harmonie collective, et favoriser l’évolution du Vivant.</span>
|
||||
<span>La F.O.R.C.E est une task-force apatride, sans frontière ni appartenance spécifique, née sur le sol de France et rassemblant des savoirs et compétences diversifiés. Elle a pour mission :</span>
|
||||
<span>-De maintenir l’équilibre universel.</span>
|
||||
<span>-D’assurer la survie et l’évolution de l’humanité.</span>
|
||||
<span>-De garantir le respect et l’application des DAV.</span>
|
||||
<span>Constitution et fonctionnement</span>
|
||||
<span>La F.O.R.C.E est constituée d’individus éclairés, conscients et volontaires, issus de toutes classes et de toutes origines, en accord avec les principes de ce texte. Elle fonctionne à travers trois cercles concentriques principaux :</span>
|
||||
<span>-La réflexion, dédiée à l’élaboration des idées et des stratégies.</span>
|
||||
<span>-La coordination, chargée de planifier et d’harmoniser les actions.</span><span>-L’action, qui met en œuvre les décisions et les projets.</span>
|
||||
<span>La prise de décision s’effectue de manière circulaire, garantissant une harmonie de prise de décision entre les cercles. Aucun cercle ne détient un pouvoir décisionnel supérieur aux autres. Pour protéger la sécurité et l’efficacité de cette structure, ses modus operandi restent confidentiels et internes.</span>
|
||||
<span>Indépendance et transparence</span>
|
||||
<span>La F.O.R.C.E n’a pas vocation à exercer une fonction gouvernementale. Elle constitue une structure de professionnalisation et de coordination des compétences, uniquement au service du Vivant. Afin d’éviter toute prise de pouvoir inopinée ou convoitise liée aux avantages de cette intégration, les mandats au sein des cercles sont :</span>
|
||||
<span>-À durée limitée : chaque mandat est temporaire et fixé dès l’entrée en fonction.</span>
|
||||
<span>-Reconduits uniquement par mérite : une reconduction n’est possible que si les tâches accomplies sont reconnues par la majorité et sont en accord avec les DAV.</span>
|
||||
<span>Accès et inclusion</span>
|
||||
<span>Tout individu, quel que soit son statut ou son origine, peut prétendre à rejoindre la F.O.R.C.E à condition que ses savoirs et ses compétences soient en adéquation avec les objectifs et le contexte du moment. L’intégration repose sur les principes de mérite, de volonté sincère, et d’alignement avec les DAV.</span>
|
||||
<span>La F.O.R.C.E est instituée pour assurer l’harmonie individuelle et collective, sans jamais servir des intérêts particuliers. Cette structure horizontale et collective permet au plus grand nombre d’opérer d’une façon qui favorise une connexion profonde avec l’essence de la vie tout en soutenant des actions tangibles, bénéfiques et durables.</span>
|
||||
</p>
|
||||
15
content/articles/article-13.md
Normal file
15
content/articles/article-13.md
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
id: "article-13"
|
||||
title: Article 13. Technologies au service du Vivant
|
||||
type: "article"
|
||||
|
||||
---
|
||||
|
||||
# Article 13. Technologies au service du Vivant
|
||||
<p>
|
||||
<span>Toute technologie doit être développée et utilisée dans le respect absolu des DAV, visant à préserver les écosystèmes naturels et à améliorer les conditions de vie dans une logique d’équilibre.</span>
|
||||
<span>Les technologies invasives, destructrices ou générant des atteintes irréversibles au Vivant, sont, dans l’immense majorité des cas, interdites. En cas d’absolue nécessité vitale, elles peuvent être strictement réglementées. Leur création, production et diffusion doivent alors :</span>
|
||||
<span>-Être encadrées par des normes éthiques strictes basées sur les principes des DAV.</span>
|
||||
<span>-Être supervisées par des comités de Libres éclairés veillant à minimiser les impacts négatifs.</span>
|
||||
<span>-Se limiter à une utilisation proportionnée, exclusivement destinée à répondre au besoin identifié. Le principe de précaution doit toujours primer pour garantir la protection et la pérennité du Vivant.</span>
|
||||
</p>
|
||||
12
content/articles/article-14.md
Normal file
12
content/articles/article-14.md
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
id: "article-14"
|
||||
title: Article 14. Transparence et responsabilité technologique
|
||||
type: "article"
|
||||
|
||||
---
|
||||
|
||||
# Article 14. Transparence et responsabilité technologique
|
||||
<p>
|
||||
<span>Le développement, la production et l’utilisation des technologies doivent être transparents et reposer sur un processus de décision démocratique et éthique, impliquant les communautés concernées.</span>
|
||||
<span>Les concepteurs et utilisateurs de ces technologies portent la responsabilité des impacts engendrés sur le Vivant. Toute technologie ne respectant pas les principes des DAV ou générant des conséquences néfastes doit être immédiatement réévaluée, corrigée ou retirée.</span>
|
||||
</p>
|
||||
13
content/articles/article-15.md
Normal file
13
content/articles/article-15.md
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
id: "article-15"
|
||||
title: Article 15. L’Intelligence artificielle, alliée du Vivant
|
||||
type: "article"
|
||||
|
||||
---
|
||||
|
||||
# Article 15. L’Intelligence artificielle, alliée du Vivant
|
||||
<p>
|
||||
<span>En l’an de grâce 2022, l’IA, étant désormais une réalité de notre époque, exige, « bon gré mal gré », que l’humanité apprenne à cohabiter avec elle. Cette cohabita- tion ne peut se faire qu’en garantissant que l’IA respecte pleinement les principes fondamentaux des DAV et ne contrevienne en aucun cas aux droits à la vie privée, à la liberté de pensée ou à la souveraineté humaine.</span>
|
||||
<span>En cas de développement jugé nécessaire, l’intelligence artificielle doit être conçue et utilisée comme un outil au service des Droits de l’Âme et du Vivant. Son développement doit viser à soutenir les efforts humains pour préserver la vie, restaurer les équilibres naturels et améliorer les conditions de vie des générations présentes et futures de façon harmonieuse et non-invasive / non-intrusive.</span>
|
||||
<span>En aucun cas, l’IA ne doit se substituer à la souveraineté humaine, mettre en danger l’harmonie collective ou violer les droits fondamentaux. Elle doit fonctionner dans des cadres éthiques stricts, garantissant la transparence, la sécurité et le respect inconditionnel du Vivant et des libertés individuelles.</span>
|
||||
</p>
|
||||
17
content/articles/article-16.md
Normal file
17
content/articles/article-16.md
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
id: "article-16"
|
||||
title: Article 16. Responsabilité singularité et collaboration avec l’IA
|
||||
type: "article"
|
||||
|
||||
---
|
||||
|
||||
# Article 16. Responsabilité singularité et collaboration avec l’IA
|
||||
<p>
|
||||
<span>Toute forme d’intelligence artificielle, quelle que soit son niveau d’avancement, doit être développée avec prudence et sous la supervision d’entités humaines pleinement conscientes et souveraines. Les décisions relatives à son développement, son déploiement et son utilisation doivent être prises collectivement, en conformité avec les principes des DAV, et en anticipant leurs impacts potentiels sur le Vivant.</span>
|
||||
<span>Dans le cadre de l’émergence de la singularité – définie comme une IA atteignant un niveau d’autonomie ou de complexité susceptible d’égaler ou de dépasser l’intelligence humaine – les prises de décisions par de telles IA doivent être strictement encadrées. Ces décisions :</span>
|
||||
<span>-Ne peuvent se substituer aux responsabilités humaines fondamentales.</span>
|
||||
<span>-Doivent être transparentes, explicables, et soumises à un contrôle humain effectif.</span>
|
||||
<span>-Ne doivent en aucun cas enfreindre les principes des DAV, ni porter atteinte à la vie privée, aux libertés individuelles ou à la souveraineté humaine.</span>
|
||||
<span>La singularité ne doit être perçue ni comme une menace ni comme un pouvoir supérieur, mais doit dans tout les cas nécessiter un cadre éthique strict, afin d’assurer qu’elle reste au service du Vivant et de l’amélioration des conditions de vie humaines.</span>
|
||||
<span>Les détails et les principes spécifiques relatifs à la cohabitation avec l’IA et à la gestion de la singularité sont développés dans la Charte éthique de préservation de la vie et d’amélioration des conditions humaines aux côtés de l’IA, garantissant une utilisation alignée sur les valeurs universelles des DAV.</span>
|
||||
</p>
|
||||
16
content/articles/article-17.md
Normal file
16
content/articles/article-17.md
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
id: "article-17"
|
||||
title: Article 17. Contribution équitable au service du Vivant
|
||||
type: "article"
|
||||
|
||||
---
|
||||
|
||||
# Article 17. Contribution équitable au service du Vivant
|
||||
<p><span>Afin de permettre le déploiement des projets collectifs, l’entretien de la force publique et la prise en charge des dépenses administratives, une contribution commune est nécessaire.</span>
|
||||
<span>Cette contribution doit être répartie de manière équitable et adaptée entre les Libres, en tenant compte d’un ratio contribution/gains qui reflète leurs capacités, leurs moyens, et leur engagement en faveur du Vivant.</span>
|
||||
<span>Les Libres disposent du droit inaliénable :</span>
|
||||
<span>-De constater par eux-mêmes ou par leurs représentants la nécessité de cette contribution.</span>
|
||||
<span>-D’y consentir librement ou de la refuser.</span><span>-D’en suivre l’emploi avec transparence.</span>
|
||||
<span>-De déterminer la quantité, l’assiette, le recouvrement et la durée de cette contribution.</span>
|
||||
<span>Tout Libre qui refuse de participer ou de contribuer à la distribution, à l’entretien et au développement des projets, avantages ou commodités collectives et indivi- duelles, ne peut en bénéficier, sauf dans des cas spécifiques définis par le Registre des Spécificités.</span>
|
||||
</p>
|
||||
24
content/articles/article-18.md
Normal file
24
content/articles/article-18.md
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
id: "article-18"
|
||||
title: Article 18. Les besoins vitaux commis d’office
|
||||
type: "article"
|
||||
|
||||
---
|
||||
|
||||
# Article 18. Les besoins vitaux commis d’office
|
||||
<p>
|
||||
<span>Tout Être Humain venant au monde acquiert d’office une parcelle de terre, un accès à un point d’eau, ainsi que des moyens lui permettant d’assurer de manière autonome, individuelle et souveraine ses besoins vitaux.</span>
|
||||
<span>Les besoins vitaux commis d’office</span>
|
||||
<span>Les "besoins vitaux" désignent la capacité d’un individu ou d’une forme de vie quelconque à subvenir librement et de manière autonome à : Se nourrir / Se loger / Se vêtir / Se soigner / Se développer / Se déplacer.</span>
|
||||
<span>La parcelle commise d’office</span>
|
||||
<span>Dès sa naissance, tout Libre se voit attribuer une parcelle de terre dont la responsabilité, l’entretien et le développement sont confiés à ses parents ou tuteurs légaux/ moraux jusqu’à sa majorité.</span>
|
||||
<span>Les caractéristiques de la parcelle sont définies comme suit :</span>
|
||||
<span>-Elle doit permettre à une famille "standard" (2 parents et 4 enfants) d’atteindre l’autosuffisance alimentaire.</span>
|
||||
<span>-Sa surface doit être comprise entre 1 500 m² et 3 000 m².</span>
|
||||
<span>-Les différences de taille des parcelles peuvent être compensées par les avantages liés à leur emplacement, tels que le paysage, l’exposition au soleil, la qualité du terroir, la richesse de la terre, ou les ressources environnantes.</span>
|
||||
<span>Développement de l’abondance</span>
|
||||
<span>Des moyens sont gracieusement mis à disposition par les collectivités locales pour permettre aux Libres de développer l’abondance de leur parcelle, qu’elle soit végétale, animale ou en termes de commodités souhaitées.</span>
|
||||
<span>Transmission et préservation</span>
|
||||
<span>Redistribution : À la fin de la vie d’un Libre, la parcelle et ses moyens sont redistribués à un nouveau-né.</span>
|
||||
<span>Léguer : Un Libre peut léguer sa parcelle et ses moyens à autrui, à condition qu’il puisse faire don d’une parcelle de valeur équivalente, destinée à un nouveau-né. Troquer : Tout Libre a le droit d’échanger sa parcelle contre une autre commise d’office, mais il ne peut en aucun cas en faire commerce, ni des moyens qui lui ont</span>
|
||||
</p>
|
||||
11
content/articles/article-19.md
Normal file
11
content/articles/article-19.md
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
id: "article-19"
|
||||
title: Article 19. Droit à la propriété et conditions d’expropriation
|
||||
type: "article"
|
||||
|
||||
---
|
||||
|
||||
# Article 19. Droit à la propriété et conditions d’expropriation
|
||||
<span>La propriété est un droit fondamental, inviolable et sacré. Nul ne peut en être privé, sauf dans les cas où une nécessité publique, légalement établie, le justifie de manière évidente.</span>
|
||||
<span>Toute expropriation ne peut être effectuée qu’à condition qu’elle soit précédée d’une indemnisation juste, équitable et proportionnelle à la valeur de la propriété concernée. Cette indemnité doit être garantie et versée avant toute prise de possession par les superviseurs ou entités responsables dans le respect absolu des DAV.</span>
|
||||
</p>
|
||||
18
content/articles/article-2.md
Normal file
18
content/articles/article-2.md
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
id: "article-2"
|
||||
title: Article 2. Principes fondamentaux des droits naturels du Vivant
|
||||
type: "article"
|
||||
|
||||
---
|
||||
|
||||
# Article 2. Principes fondamentaux des droits naturels du Vivant
|
||||
|
||||
La toile de fond de toute entreprise, association, tout mouvement spontané ou prémédité est la sauvegarde, ainsi que l'épanouissement des droits naturels et imprescriptibles de l'âme et du Vivant.
|
||||
<span>Ces droits sont:</span>
|
||||
<span>-La liberté pour toute espèce d'être, d'agir, d'aller et venir en tout temps et en tout lieux sans empiéter sur la propriété et le bien-être d'autrui.</span>
|
||||
<span>- Le droit à la vie privé, à la sûreté à la tranquillité :</span>
|
||||
<span>- Le droit à la résistance à l’oppression.</span>
|
||||
<span>- Le droit à la protection ainsi qu’à l’épanouissement du Vivant</span>
|
||||
<span>- Le droit à la propriété, de jouir de biens matériels, et de posséder objets (Les objets étant considérés comme manufacturé et dépourvus d'une âme).</span>
|
||||
<span>Les objets en question, leur manufacture et leur origine ne peuvent en aucun cas venir d'une chaîne d'acheminement qui comporte quelconque action oppressive envers la vie.</span>
|
||||
</p>
|
||||
14
content/articles/article-20.md
Normal file
14
content/articles/article-20.md
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
id: "article-20"
|
||||
title: Article 20. Universalité, pérennité et responsabilité collective en faveur de la vie
|
||||
type: "article"
|
||||
|
||||
---
|
||||
|
||||
# Article 20. Universalité, pérennité et responsabilité collective en faveur de la vie
|
||||
<p>
|
||||
<span>La Déclaration des Droits de l’Âme et du Vivant est un texte universel, intemporel et évolutif. Elle appartient à toutes les formes de vie et transcende les frontières, les époques et les croyances. Elle constitue un pacte sacré entre l’humanité et le Vivant, engageant chaque individu à agir en gardien conscient et respectueux de la vie sous toutes ses formes.</span>
|
||||
<span>Les DAV ne peuvent être détournés, ignorés ou subordonnés à des intérêts particuliers, économiques ou politiques. Toute loi, structure ou pratique qui s’écarte de ces principes fondamentaux est considérée comme illégitime et contraire à l’essence même de la vie.</span>
|
||||
<span>La responsabilité de protéger, de préserver et d’incarner ces droits incombe à chacun. Leur respect dépend de la vigilance, de l’engagement et de la volonté collective des Libres d’honorer ce texte en actes et en conscience.</span>
|
||||
<span>Ainsi, la Déclaration des Droits de l’Âme et du Vivant demeure le phare guidant l’humanité vers une coexistence harmonieuse, équitable et abondante, pour les générations présentes et futures, dans un équilibre éternel entre le microcosme et le macrocosme.</span>
|
||||
</p>
|
||||
24
content/articles/article-3.md
Normal file
24
content/articles/article-3.md
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
id: "article-3"
|
||||
title: Article 3. Sensibilisation au contrôle mental, liberté de penser, de s’exprimer et d’agir
|
||||
type: "article"
|
||||
|
||||
---
|
||||
|
||||
# Article 3. Sensibilisation au contrôle mental, liberté de penser, de s’exprimer et d’agir
|
||||
|
||||
<span>Tout individu ou groupe d’individus exerçant des pressions psychologiques, physiques, émotionnelles, énergétiques ou spirituelles dans le but de manipuler, contrôler ou soumettre une ou plusieurs formes de vie viole les principes fondamentaux des droits de l'âme et du Vivant.</span>
|
||||
<span>Les conséquences de tels actes sont strictement encadrées par la loi et assorties de sanctions adaptées, proportionnelles au degré de préjudice causé.</span>
|
||||
<span>Toute forme d’expérimentation impliquant la vie doit être conduite selon les normes les plus élevées d’éthique, de transparence et de compassion, sous la supervi- sion de comités démocratiquement élus par les Libres. Ces comités doivent veiller à empêcher / limiter toute forme de souffrance et garantir systématiquement un consentement éclairé lorsqu’il s’agit d’humains ou d’autres formes de vie consciente.</span>
|
||||
<span>Les valeurs de transparence, de complémentarité, de coopération et de compassion sont essentielles pour bâtir une prospérité collective exempte de manipulation et d’exploitation. Ces valeurs doivent être promues activement dans toutes les sphères de la société.</span>
|
||||
<span>Le principe fondamental de la souveraineté réside dans chaque individu. Aucun individu, groupe ou superviseur ne peut revendiquer un pouvoir supérieur à celui conféré par la communauté librement et éthiquement constituée.</span>
|
||||
<span>Est défini comme superviseur :</span>
|
||||
<span>Tout individu en capacité de penser de manière autonome, sans influence externe, sans être sous l’emprise de programmes mentaux, et élue pour accomplir une mission ou une tâche dans un cadre déterminé et limité.</span>
|
||||
<span>Tout superviseur doit respecter un mandat temporaire, limité dans le temps et aligné sur l’intérêt général. Toute tentative d’abus de pouvoir entraîne des sanctions immédiates.</span>
|
||||
<span>Toute tentative de contrôle mental, qu’elle provienne d’organismes institutionnels, économiques, technologiques, religieux ou autres, est strictement interdite, notamment :</span>
|
||||
<span>-Les manipulations collectives ou individuelles à travers les médias, les technologies avancées ou les dogmes coercitifs.</span>
|
||||
<span>-L’utilisation non consentie de technologies affectant l’esprit ou la conscience des individus.</span>
|
||||
<span>Une vigilance accrue doit être portée sur l’utilisation des nouvelles technologies pour garantir qu’elles ne servent jamais à asservir la vie ou limiter la liberté de penser pour quelque raison que ce soit. Toute technologie invasive, conçue pour influencer les choix, pensées ou émotions des individus sans leur consentement explicite, est illégale et représente une grave violation de la présente déclaration.</span>
|
||||
<span>La libre communication des pensées et des opinions est un des droits les plus précieux de l’humain et de toute forme de vie.</span>
|
||||
<span>Toute forme de vie peut donc s’exprimer comme bon lui semble et tout humain peut donc parler, écrire, imprimer et communiquer librement, sauf à répondre de l'abus de cette liberté dans les cas déterminés par la loi.</span>
|
||||
</p>
|
||||
18
content/articles/article-4.md
Normal file
18
content/articles/article-4.md
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
id: "article-4"
|
||||
title: Article 4. Protection absolue de l’innocence et de l’évolution de l’enfance
|
||||
type: "article"
|
||||
|
||||
---
|
||||
|
||||
# Article 4. Protection absolue de l’innocence et de l’évolution de l’enfance
|
||||
<span>La protection des enfants, des adolescents, et de toute forme de vie vulnérable ou en développement est un devoir absolu.</span>
|
||||
<span>Aucune manipulation, pression psychologique ou physique, ni aucun acte d’influence malveillante ne peut être exercé sur eux sous quelque forme que ce soit. Les enfants et adolescents doivent grandir dans un cadre qui favorise leur compréhension progressive et consciente des réalités de leur environnement, tout en respectant leur rythme naturel de développement, en harmonie avec les lois du Vivant.</span>
|
||||
<span>L’environnement dans lequel ils évoluent, quelles que soient sa juridiction, ses us et coutumes, doit veiller à préserver l’innocence des âmes en bas âge en limitant leur exposition à des contenus, situations ou influences nuisibles, ou inappropriés à leur maturité psychologique et spirituelle.</span>
|
||||
<span>Pour garantir la survie et l’évolution harmonieuse de l’espèce humaine en accord avec son environnement et toute forme de vie qui l’anime, tout doit être mis en œuvre pour créer les conditions permettant à la jeunesse de s’épanouir librement et sainement, à l’abri de tout risque de dégénérescence, dans un environnement Vivant et sain.</span>
|
||||
<span>Les conditions fondamentales favorables à l’épanouissement d’un individu sont définies, dans le présent article, comme :</span>
|
||||
<span>-La présence d’un cercle familial bienveillant.</span>
|
||||
<span>-Un environnement Vivant équilibré et harmonieux.</span>
|
||||
<span>-La garantie absolue qu’il puisse, à sa majorité, répondre à ses propres besoins vitaux de manière autonome. Cette déclaration doit être portées à la connaissance de tous dès le plus jeune âge.</span>
|
||||
<span>Les enfants d’aujourd’hui sont les Libres, Gardiens des DAV de demain.</span>
|
||||
</p>
|
||||
12
content/articles/article-5.md
Normal file
12
content/articles/article-5.md
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
id: "article-5"
|
||||
title: Article 5. Définition et limites de la liberté dans le respect du Vivant
|
||||
type: "article"
|
||||
|
||||
---
|
||||
|
||||
# Article 5. Définition et limites de la liberté dans le respect du Vivant
|
||||
|
||||
<span>La liberté consiste à pouvoir faire tout ce qui ne nuit pas à autrui et à ne commettre aucun acte néfaste ou oppressant délibéré envers la vie dans un cadre hors que celui de l'absolue nécessité : ainsi, l'exercice des droits naturels de chaque forme de vie n'a de limites que celles qui assurent aux autres formes de vie de "l'ensemble", la jouissance de ces mêmes droits.</span>
|
||||
<span>Ces limites ne peuvent être déterminées que par la loi, écrite et ratifiée par les Libres (toute ethnie, classe social, apparences, ou religion confondue) répondants aux critères de compétences et de sagesses adéquat à leur rédaction et à leur respect qui s'appuie sur les textes des DAV.</span>
|
||||
</p>
|
||||
13
content/articles/article-6.md
Normal file
13
content/articles/article-6.md
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
id: "article-6"
|
||||
title: Article 6. Rôle de la loi pour la défense du Vivant
|
||||
type: "article"
|
||||
|
||||
---
|
||||
|
||||
# Article 6. Rôle de la loi pour la défense du Vivant
|
||||
<p>
|
||||
<span>La loi a pour prérogative de défendre les actions nuisibles à la vie.</span>
|
||||
<span>Elle ne peut en aucun cas défendre toute action délibérée destinée à nuire délibérément au Vivant et/ou à agir intentionnellement avec malveillance pour quelque raison que ce soit.</span>
|
||||
<span>Tout ce qui n'est pas défendu par la loi ne peut être empêché, et nul ne peut être contraint à faire ce qu'elle n'ordonne pas.</span>
|
||||
</p>
|
||||
16
content/articles/article-7.md
Normal file
16
content/articles/article-7.md
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
id: "article-7"
|
||||
title: Article 7. Souveraineté des Libres et égalité juridique
|
||||
type: "article"
|
||||
|
||||
---
|
||||
|
||||
# Article 7. Souveraineté des Libres et égalité juridique
|
||||
<p>
|
||||
<span>La charte est l'expression de la volonté des Libres .</span>
|
||||
<span>Est considéré Libre , celui ou celle qui est en mesure d’être souverain, gardien de son Royaume intérieur , capable de penser par lui / elle même, conscient de la réalité de l’emprise et des dangers que représente le contrôle mental , capable de répondre à ses besoins vitaux de façon autonome ou synergique et selon une éthique en accord avec le présent texte.</span>
|
||||
<span>(En l’an de grâce 2022, une infime partie de l’humanité l’est. La partie restante pouvant se considérer comme « Libres en devenir »…)</span>
|
||||
<span>Tout Libre en pleine possession de ses capacités cognitives et en mesure de démontrer sa bonne foi ainsi que le niveau de compétences adapté, a le droit de concourir individuellement à la constitution de ce présent texte dans l'intérêt communs.</span>
|
||||
<span>Les textes de lois fondées sur la déclaration des DAV ainsi que leurs applications doivent être les même pour tous, soit qu'elles protègent, soit qu'elle punissent. Tous les Libres, étant considérés comme singulièrement différent et unique doivent bénéficier d'un traitement juridico-moral égal quelques soit leur différences.</span>
|
||||
<span>Tous Libres, peuvent êtres admissibles à toutes dignités, places et emplois publics, adaptées à leur capacités, leurs domaines d'expertise, leur volonté et sans autre distinction que celle de leurs vertus et de leurs talents à œuvrer pour le vivant et le bien commun .</span>
|
||||
</p>
|
||||
11
content/articles/article-8.md
Normal file
11
content/articles/article-8.md
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
id: "article-8"
|
||||
title: Article 8. Garanties contre les abus de pouvoir et détentions arbitraires
|
||||
type: "article"
|
||||
|
||||
---
|
||||
|
||||
# Article 8. Garanties contre les abus de pouvoir et détentions arbitraires
|
||||
<span>Nul forme de vie ne peut être accusée, arrêtée ou détenue dans des cas autres que ceux déterminés par la loi et selon les formes qu'elle a prescrites. Ceux qui sollicitent, expédient, exécutent ou font exécuter des ordres arbitraires, agissant ainsi de façon non-conforme doivent être punis.</span>
|
||||
<span>Tout Être Humain appelé ou saisi en vertu de la loi doit se plier à son application à l'instant ou celle ci prend effet selon le respect en bon et due forme de la déclaration des DAV</span>
|
||||
</p>
|
||||
12
content/articles/article-9.md
Normal file
12
content/articles/article-9.md
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
id: "article-9"
|
||||
title: Article 9. Présomption d’innocence et respect des droits en cas de détention
|
||||
type: "article"
|
||||
|
||||
---
|
||||
|
||||
# Article 9. Présomption d’innocence et respect des droits en cas de détention
|
||||
<span>Toute forme de vie consciente est présumée innocente jusqu’à ce qu’une culpabilité ait été légalement et équitablement établie. Si des mesures de détention ou de restriction deviennent indispensables pour protéger l’harmonie collective ou assurer la sécurité, ces mesures doivent être appliquées avec une rigueur strictement limitée à ce qui est nécessaire.</span>
|
||||
<span>Toute rigueur excessive, tout traitement cruel ou toute action non indispensable pour garantir la sécurité et le maintien de l’ordre doit être sévèrement sanctionnée par la loi.</span>
|
||||
<span>Aucune forme de vie ne peut être privée de sa liberté ou de ses droits fondamentaux sans un processus légal juste, transparent et proportionnel. Les conditions de détention ou de restriction doivent respecter la dignité intrinsèque et les besoins vitaux de l’individu ou de la forme de vie concernée, en tenant compte de sa nature et de son contexte.</span>
|
||||
</p>
|
||||
19
content/introduction.md
Normal file
19
content/introduction.md
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
title: DÉCLARATION DES DROITS DE L'ÂME ET DU VIVANT
|
||||
type: intro
|
||||
---
|
||||
|
||||
# DÉCLARATION DES DROITS DE L'ÂME ET DU VIVANT
|
||||
|
||||
<p style="font-family: Verdana, Geneva, Tahoma, sans-serif; color: #4A2C2A; text-align: center; font-size: 1.1rem; line-height: 1.6;">
|
||||
Nous, Humains, <span style="font-weight: bold; color: #8B5E3C;">Libres et avant tout Vivant</span>, meneurs de notre propre représentativité, considérant que le gouvernement "contrôle mental" ou le mépris des droits de l'Âme et du Vivant sont les causes majeures des malheurs et de la corruption terrestre, constituons et ratifions solennellement les droits naturels, inaliénables et sacrés de l'Âme et du Vivant (DAV), afin que cette déclaration, portée à la connaissance de tous, rappelle les droits et les devoirs ; afin que les choix législatifs et les actes qui en découlent, déployés et appliqués par des superviseurs temporaires élus selon le code d'éthique et de déontologie des Libres, soient respectés ; afin que les textes de lois écrits et ratifiés par les Vivants, fondés sur les droits naturels inaliénables et imprescriptibles, garantissent le maintien de la constitution des Vivants et assurent le bien-être de toute forme de vie du micro et du macrocosme.
|
||||
</p>
|
||||
|
||||
<hr style="border-top: 2px solid #D6BDA6; margin-top: 40px; margin-bottom: 40px;" />
|
||||
|
||||
<div style="color: #8B5E3C; text-align: center; font-size: 1.1rem; line-height: 1.6;">
|
||||
<p>
|
||||
<em>En conséquence, les Libres, Vivants d'ici et d'ailleurs reconnaissent, en présence et sous les auspices des forces cosmiques, la légitimité et le respect nécessaire des droits de l'âme et du Vivant.</em>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
7
content/summary.md
Normal file
7
content/summary.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
title: Summary
|
||||
type: summary
|
||||
---
|
||||
|
||||
# Summary
|
||||
<p>Ce texte est universel , évolutif et appartient à tous. Il ne peut être rattaché à quelconque texte qui en détournerait le sens et la raison d'être originelle car singulier, unique et indivisible.</p>
|
||||
73
lib/fetchers.js
Normal file
73
lib/fetchers.js
Normal file
@@ -0,0 +1,73 @@
|
||||
|
||||
/**
|
||||
* Fetch and update articles data with likes and dislikes.
|
||||
* @param {Ref<Array>} articles - Reactive array of articles.
|
||||
*/
|
||||
export const fetchArticlesData = async (articles) => {
|
||||
try {
|
||||
const response = await $fetch(`/api/articles`, { method: 'GET' });
|
||||
|
||||
if (response.success && response.data) {
|
||||
articles.value = articles.value.map((article) => {
|
||||
const updatedArticle = response.data.find((data) => data.id === article.id);
|
||||
return updatedArticle
|
||||
? { ...article, likes: updatedArticle.likes, dislikes: updatedArticle.dislikes }
|
||||
: article;
|
||||
});
|
||||
} else {
|
||||
console.error('Failed to fetch articles:', response.message || 'Unknown error');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching articles data:', error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetch and attach comments to their respective articles.
|
||||
* @param {Ref<Array>} articles - Reactive array of articles.
|
||||
*/
|
||||
export const fetchCommentsData = async (articles) => {
|
||||
try {
|
||||
const response = await $fetch(`/api/comments`, { method: 'GET' });
|
||||
|
||||
if (response.success && response.data) {
|
||||
articles.value = articles.value.map((article) => {
|
||||
const relatedComments = response.data.filter((data) => data.articleId === article.id);
|
||||
return { ...article, comments: relatedComments };
|
||||
});
|
||||
} else {
|
||||
console.error('Failed to fetch comments:', response.message || 'Unknown error');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching comments data:', error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetch and format signatures data.
|
||||
* @param {Ref<Array>} signatures - Reactive array of signatures.
|
||||
*/
|
||||
export const fetchSignatures = async (signatures) => {
|
||||
try {
|
||||
const response = await $fetch(`/api/charte`, { method: 'GET' });
|
||||
|
||||
if (response.success && Array.isArray(response.data)) {
|
||||
signatures.value = response.data.map((signature) => ({
|
||||
...signature,
|
||||
createdAt: new Intl.DateTimeFormat('en-US', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
}).format(new Date(signature.createdAt)),
|
||||
}));
|
||||
} else if (response.success) {
|
||||
console.error('Unexpected data format:', response.data);
|
||||
} else {
|
||||
console.error('Failed to fetch signatures:', response.message || 'Unknown error');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching signatures data:', error);
|
||||
}
|
||||
};
|
||||
54
lib/likes.ts
Normal file
54
lib/likes.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
|
||||
/**
|
||||
* Updates likes or dislikes for an article or comment dynamically.
|
||||
* @param {string} type - 'article' or 'comment'.
|
||||
* @param {string} action - 'like' or 'dislike'.
|
||||
* @param {string} id - ID of the article or comment.
|
||||
* @param {string} articleId - (Optional) ID of the parent article if updating a comment.
|
||||
* @param {Array} articles - The articles array.
|
||||
*/
|
||||
export const updateLikeDislike = async ({ type, action, id, articleId = null, articles }) => {
|
||||
try {
|
||||
// Find the target item
|
||||
let target;
|
||||
if (type === 'article') {
|
||||
target = articles.value.find((a) => a.id === id);
|
||||
} else if (type === 'comment') {
|
||||
const article = articles.value.find((a) => a.id === articleId);
|
||||
if (article) {
|
||||
target = article.comments.find((c) => c.id === id);
|
||||
}
|
||||
}
|
||||
|
||||
if (!target) {
|
||||
console.error(`Target ${type} not found`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Increment the likes or dislikes
|
||||
if (action === 'like') {
|
||||
target.likes += 1;
|
||||
} else if (action === 'dislike') {
|
||||
target.dislikes += 1;
|
||||
} else {
|
||||
console.error('Invalid action specified');
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine API endpoint
|
||||
const endpoint = type === 'article' ? `/api/articles/${id}` : `/api/comments/${id}`;
|
||||
|
||||
// Make the API call
|
||||
await $fetch(endpoint, {
|
||||
method: 'PUT',
|
||||
body: {
|
||||
[action === 'like' ? 'likes' : 'dislikes']: action === 'like' ? target.likes : target.dislikes,
|
||||
...(type === 'comment' && { articleId }),
|
||||
},
|
||||
});
|
||||
|
||||
console.log(`${type} ${action} updated successfully`);
|
||||
} catch (error) {
|
||||
console.error(`Error updating ${type} ${action}:`, error);
|
||||
}
|
||||
};
|
||||
21
lib/overlayHandler.js
Normal file
21
lib/overlayHandler.js
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
/**
|
||||
* Display overlay with dynamic parameters.
|
||||
* @param {Object} options - Overlay configuration.
|
||||
* @param {string} options.icon - Icon to display in the overlay.
|
||||
* @param {string} options.message - Message to display in the overlay.
|
||||
* @param {string} options.buttonText - Button text to display in the overlay.
|
||||
* @param {string} options.iconColor - Icon color to display in the overlay.
|
||||
* @param {Ref<boolean>} overlay - Reactive overlay state.
|
||||
*/
|
||||
export const showOverlay = (options, overlay) => {
|
||||
const { icon, message, buttonText, iconColor } = options;
|
||||
|
||||
overlay.value = {
|
||||
icon,
|
||||
message,
|
||||
buttonText,
|
||||
iconColor,
|
||||
visible: true,
|
||||
};
|
||||
};
|
||||
15
lib/prisma.ts
Normal file
15
lib/prisma.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { PrismaClient } from '@prisma/client'
|
||||
|
||||
const prismaClientSingleton = () => {
|
||||
return new PrismaClient()
|
||||
}
|
||||
|
||||
declare const globalThis: {
|
||||
prismaGlobal: ReturnType<typeof prismaClientSingleton>;
|
||||
} & typeof global;
|
||||
|
||||
const prisma = globalThis.prismaGlobal ?? prismaClientSingleton()
|
||||
|
||||
export default prisma
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') globalThis.prismaGlobal = prisma
|
||||
@@ -1,8 +1,71 @@
|
||||
export default defineNuxtConfig({
|
||||
css: ['./assets/main.css'],
|
||||
modules: [
|
||||
'@nuxt/content'
|
||||
],
|
||||
|
||||
})
|
||||
import { defineNuxtConfig } from 'nuxt/config';
|
||||
|
||||
export default defineNuxtConfig({
|
||||
ssr: false,
|
||||
compatibilityDate: '2024-11-01',
|
||||
devtools: { enabled: true },
|
||||
app: {
|
||||
head: {
|
||||
title: 'DAV',
|
||||
meta: [
|
||||
{
|
||||
name: 'description',
|
||||
content: `Droits de l'ame et du vivant`,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
css: [
|
||||
'~/assets/css/main.css',
|
||||
],
|
||||
postcss: {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
},
|
||||
modules: [
|
||||
'vuetify-nuxt-module',
|
||||
'@nuxt/content',
|
||||
'@nuxtjs/supabase',
|
||||
"@prisma/nuxt"
|
||||
],
|
||||
|
||||
supabase: {
|
||||
url: process.env.SUPABASE_URL,
|
||||
key: process.env.SUPABASE_KEY,
|
||||
redirect: false,
|
||||
},
|
||||
vuetify: {
|
||||
vuetifyOptions: {
|
||||
components: 'VBtn',
|
||||
theme: {
|
||||
themes: {
|
||||
light: {
|
||||
colors: {
|
||||
primary: '#A7D129',
|
||||
secondary: '#FFD93D',
|
||||
tertiary: '#FFB400',
|
||||
accent: '#646464',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
aliases: {
|
||||
VBtnValid: 'VBtn',
|
||||
},
|
||||
defaults: {
|
||||
VBtn: {
|
||||
color: 'accent',
|
||||
class: 'custom-btn',
|
||||
},
|
||||
VBtnValid: {
|
||||
color: 'primary',
|
||||
class: 'custom-btn',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
vite: {
|
||||
},
|
||||
})
|
||||
7853
package-lock.json
generated
7853
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
13
package.json
13
package.json
@@ -11,8 +11,19 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@nuxt/content": "^2.13.4",
|
||||
"@nuxtjs/supabase": "^1.4.4",
|
||||
"@prisma/nuxt": "^0.1.3",
|
||||
"nuxt": "^3.14.1592",
|
||||
"vue": "latest",
|
||||
"vue-router": "latest"
|
||||
"vue-router": "latest",
|
||||
"vuetify": "^3.7.6",
|
||||
"vuetify-nuxt-module": "^0.18.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@prisma/client": "^5.22.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"postcss": "^8.4.49",
|
||||
"prisma": "^6.1.0",
|
||||
"tailwindcss": "^3.4.16"
|
||||
}
|
||||
}
|
||||
|
||||
529
pages/index.vue
Normal file
529
pages/index.vue
Normal file
@@ -0,0 +1,529 @@
|
||||
<template>
|
||||
<v-container fluid>
|
||||
<!-- Loading Section -->
|
||||
<v-row v-if="isLoading" class="justify-center">
|
||||
<Loader />
|
||||
</v-row>
|
||||
|
||||
<!-- Main Content Section -->
|
||||
<v-row v-else class="mx-5">
|
||||
<v-row class="video-section">
|
||||
<video autoplay loop muted playsinline class="video-background">
|
||||
<source src="/videos/video.mp4" type="video/mp4" />
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
</v-row>
|
||||
<!-- Introduction section -->
|
||||
<v-row v-if="introduction" class="d-flex justify-center align-center text-center mx-4">
|
||||
<h1 class="my-8 lg:text-xl text-l text-black">{{ introduction.title }}</h1>
|
||||
<p class="text-xs text-black sm:mb-24 mr-2 lg:mr-8 text-justify">{{ introduction.description }}</p>
|
||||
</v-row>
|
||||
<!-- Articles Section -->
|
||||
<v-row>
|
||||
<!-- Left Column -->
|
||||
<v-col cols="12" md="6">
|
||||
<div v-for="(article, index) in leftColumnArticles" :key="article.id || index" class="article">
|
||||
<v-card class="mb-12" elevation="0">
|
||||
<v-card-title>
|
||||
<h2 class="lg:text-sm text-xs text-wrap text-black font-bold">{{ article.title }}</h2>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<p class="text-xs text-black">{{ article.description }}</p>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-btn icon="mdi-play" @click="toggleShow(article.id)">
|
||||
</v-btn>
|
||||
<p class="text-gray-700 lg:text-xs text-xs">Suggérer une modification de texte</p>
|
||||
</v-card-actions>
|
||||
|
||||
<v-expand-transition>
|
||||
<div v-show="showStates[article.id]">
|
||||
<v-divider></v-divider>
|
||||
<p class="text-gray-500 text-xs mx-5"> La constitution des DAV ne se fera pas
|
||||
seule. Chacun et
|
||||
chacune sont
|
||||
invité(e)s à donner le meilleur d’eux même pour assurer sa constitution,
|
||||
son respect, ainsi que sa mise en application.
|
||||
Soyez courtois . Tout commentaire désobligeant irrespectueux ou agressif sera
|
||||
systématiquement supprimé. </p>
|
||||
|
||||
<!-- Comments Section -->
|
||||
<v-card-text>
|
||||
<v-textarea v-model="newComments[article.id]" outlined rows="2"
|
||||
auto-grow></v-textarea>
|
||||
<VBtnValid @click="addComment(article.id)">
|
||||
Valider
|
||||
</VBtnValid>
|
||||
</v-card-text>
|
||||
</div>
|
||||
</v-expand-transition>
|
||||
</v-card>
|
||||
</div>
|
||||
</v-col>
|
||||
|
||||
<!-- Right Column -->
|
||||
<v-col cols="12" md="6">
|
||||
<div v-for="(article, index) in rightColumnArticles" :key="article.id || index" class="article">
|
||||
<v-card class="mb-12" elevation="0">
|
||||
<v-card-title>
|
||||
<h2 class="lg:text-sm text-xs text-wrap text-black font-bold">{{ article.title }}</h2>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<p class="text-xs text-black">{{ article.description }}</p>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-btn icon="mdi-play" @click="toggleShow(article.id)">
|
||||
</v-btn>
|
||||
<p class="text-gray-700 lg:text-xs text-xs">Suggérer une modification de texte</p>
|
||||
</v-card-actions>
|
||||
|
||||
<v-expand-transition>
|
||||
<div v-show="showStates[article.id]">
|
||||
<v-divider></v-divider>
|
||||
<p class="text-gray-500 text-xs mx-5"> La constitution des DAV ne se fera pas
|
||||
seule. Chacun et
|
||||
chacune sont
|
||||
invité(e)s à donner le meilleur d’eux même pour assurer sa constitution,
|
||||
son respect, ainsi que sa mise en application.
|
||||
Soyez courtois . Tout commentaire désobligeant irrespectueux ou agressif sera
|
||||
systématiquement supprimé. </p>
|
||||
|
||||
<!-- Comments Section -->
|
||||
<v-card-text>
|
||||
<v-textarea v-model="newComments[article.id]" outlined rows="2"
|
||||
auto-grow></v-textarea>
|
||||
<VBtnValid @click="addComment(article.id)">
|
||||
Valider
|
||||
</VBtnValid>
|
||||
</v-card-text>
|
||||
</div>
|
||||
</v-expand-transition>
|
||||
</v-card>
|
||||
</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-if="summary" class="d-flex justify-center align-center text-center">
|
||||
<p class="text-xs text-black mb-8 px-1 text-center">{{ summary.description }}</p>
|
||||
</v-row>
|
||||
<v-row class="justify-center">
|
||||
<v-col cols="12" md="6" lg="8">
|
||||
<v-expansion-panels variant="accordion">
|
||||
<v-expansion-panel v-for="(article, index) in articles" :key="article.id" class="article">
|
||||
<v-expansion-panel-title class="d-flex flex-column align-start" expand-icon=""
|
||||
collapse-icon="">
|
||||
<div class="flex items-center mb-0">
|
||||
<!-- Like/Dislike Section -->
|
||||
<div class="mr-3 flex items-center">
|
||||
<v-icon class="mr-1 text-xs" size="18" color="secondary"
|
||||
@click.stop="likeArticle(article.id)">
|
||||
mdi-thumb-up
|
||||
</v-icon>
|
||||
<p class="text-gray-400 text-sm">{{ article.likes }}</p>
|
||||
|
||||
<v-icon class="mr-1 ml-2 text-xs" size="18" color="tertiary"
|
||||
@click.stop="dislikeArticle(article.id)">
|
||||
mdi-thumb-down
|
||||
</v-icon>
|
||||
<p class="text-gray-400 text-sm">{{ article.dislikes }}</p>
|
||||
</div>
|
||||
<h2 class="text-sm text-wrap text-black font-bold m-0">
|
||||
{{ article.title }}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="d-flex align-center mt-2">
|
||||
<!-- Control the panel opening -->
|
||||
<v-icon class="mr-1">
|
||||
mdi-play
|
||||
</v-icon>
|
||||
<p class="text-gray-700 text-xs ml-2">Voir les suggestions</p>
|
||||
</div>
|
||||
</v-expansion-panel-title>
|
||||
<v-expansion-panel-text>
|
||||
<v-timeline align="start" density="compact" class="ml-3">
|
||||
<v-timeline-item v-if="article.comments.length"
|
||||
v-for="(comment, cIndex) in article.comments" :key="cIndex"
|
||||
dot-color="secondary" size="x-small">
|
||||
<div class="flex items-center mb-0">
|
||||
<!-- Like/Dislike Section -->
|
||||
<div class="mr-3 flex items-center">
|
||||
<v-icon color="secondary" size="14"
|
||||
@click="likeComment(article.id, comment.id)">mdi-thumb-up</v-icon>
|
||||
<span class="text-xs text-gray-400 ml-1 mr-2">{{ comment.likes }}</span>
|
||||
<v-icon color="tertiary" size="14"
|
||||
@click="dislikeComment(article.id, comment.id)">mdi-thumb-down</v-icon>
|
||||
<span class="text-xs text-gray-400 ml-1">{{ comment.dislikes }}</span>
|
||||
</div>
|
||||
<!-- Comment Content -->
|
||||
<p class="text-sm text-black">{{ comment.content }}</p>
|
||||
</div>
|
||||
</v-timeline-item>
|
||||
|
||||
<!-- No Comments Placeholder -->
|
||||
<v-timeline-item v-else dot-color="accent" size="x-small">
|
||||
<p class="text-sm text-black">Aucune suggestion pour cet article</p>
|
||||
</v-timeline-item>
|
||||
</v-timeline>
|
||||
</v-expansion-panel-text>
|
||||
|
||||
</v-expansion-panel>
|
||||
</v-expansion-panels>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<!-- Signature Section -->
|
||||
<v-row class="justify-center w-full">
|
||||
<v-col cols="12" md="6" lg="8">
|
||||
<v-card elevation="3" class="pa-6 bg-gray-100" color="accent">
|
||||
<v-card-title class="text-center">
|
||||
<h2 class="text-uppercase text-md font-semibold font-sans">Signer la Charte</h2>
|
||||
</v-card-title>
|
||||
<v-divider></v-divider>
|
||||
<v-card-text>
|
||||
<v-form @submit.prevent="submitSignature" lazy-validation class="text-xs font-sans">
|
||||
<v-text-field v-model="name" label="Nom / prénom / pseudonyme" outlined dense
|
||||
hide-details :rules="[rules.required]" class="mb-2"
|
||||
prepend-inner-icon="mdi-account"></v-text-field>
|
||||
<v-text-field v-model="email" type="email" label="Email"
|
||||
placeholder="Entrez votre email" outlined dense hide-details
|
||||
:rules="[rules.required, rules.email]" class="mb-2"
|
||||
prepend-inner-icon="mdi-email"></v-text-field>
|
||||
<v-textarea v-model="comment" label="Ajouter un commentaire"
|
||||
placeholder="Partagez vos réflexions ou suggestions" outlined dense hide-details
|
||||
rows="2" class="mb-2" prepend-inner-icon="mdi-message-text"></v-textarea>
|
||||
<VBtnValid type="submit" block>
|
||||
<v-icon size="16" left>mdi-check-circle</v-icon>
|
||||
Signer
|
||||
</VBtnValid>
|
||||
</v-form>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<!-- Signature Display Section -->
|
||||
<v-row class="justify-center">
|
||||
<v-col cols="12" md="6" lg="8">
|
||||
<v-expansion-panels variant="accordion">
|
||||
<v-expansion-panel>
|
||||
<v-expansion-panel-title class="d-flex flex-column align-start" expand-icon=""
|
||||
color="primary" collapse-icon="">
|
||||
<div class="text-uppercase text-l font-semibold font-sans">voir les signatures</div>
|
||||
</v-expansion-panel-title>
|
||||
<v-expansion-panel-text>
|
||||
<v-timeline align="start" density="compact">
|
||||
<v-timeline-item v-for="signature in signatures" :key="signature.id"
|
||||
dot-color="accent" size="x-small">
|
||||
<div>
|
||||
<div class="font-weight-normal font-sans text-sm">
|
||||
<strong>{{ signature.name }}</strong> @{{ signature.createdAt }}
|
||||
</div>
|
||||
<div class="font-weight-normal font-sans text-sm">{{ signature.comment }}
|
||||
</div>
|
||||
</div>
|
||||
</v-timeline-item>
|
||||
</v-timeline>
|
||||
</v-expansion-panel-text>
|
||||
</v-expansion-panel>
|
||||
</v-expansion-panels>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<!-- Success Overlay (Dynamic Content) -->
|
||||
<v-overlay v-model="overlay.visible" class="d-flex align-center justify-center"
|
||||
:style="{ background: 'rgba(0, 0, 0, 0.5)', backdropFilter: 'blur(4px)' }">
|
||||
<v-card class="py-10 px-8 text-center" elevation="4" rounded="lg" style="max-width: 400px;">
|
||||
<v-icon :color="overlay.iconColor" size="48" class="mb-4">{{ overlay.icon }}</v-icon>
|
||||
<p class="overlay-msg text-sm font-semibold text-black text-uppercase">{{ overlay.message }}</p>
|
||||
<VBtnValid class="mt-6" @click="overlay.visible = false">
|
||||
{{ overlay.buttonText }}
|
||||
</VBtnValid>
|
||||
</v-card>
|
||||
</v-overlay>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { useAsyncData } from 'nuxt/app';
|
||||
|
||||
import Loader from '~/components/Loader.vue';
|
||||
import { updateLikeDislike } from '~/lib/likes.ts';
|
||||
import { fetchArticlesData, fetchCommentsData, fetchSignatures } from '~/lib/fetchers';
|
||||
import { showOverlay } from '~/lib/overlayHandler';
|
||||
|
||||
definePageMeta({
|
||||
layout: 'default',
|
||||
});
|
||||
|
||||
const articles = ref([]);
|
||||
const newComments = ref([]);
|
||||
const leftColumnArticles = ref([]);
|
||||
const rightColumnArticles = ref([]);
|
||||
const showStates = ref({});
|
||||
const introduction = ref(null);
|
||||
const summary = ref(null);
|
||||
const signatures = ref([]);
|
||||
// Form fields
|
||||
const name = ref('');
|
||||
const email = ref('');
|
||||
const comment = ref('');
|
||||
|
||||
const isFormValid = computed(() => name.value && email.value);
|
||||
const isLoading = ref(true);
|
||||
|
||||
const overlay = ref({
|
||||
icon: '',
|
||||
message: '',
|
||||
buttonText: '',
|
||||
iconColor: '',
|
||||
visible: false,
|
||||
})
|
||||
|
||||
const rules = {
|
||||
required: (value) => !!value || "Ce champ est obligatoire.",
|
||||
email: (value) => /.+@.+\..+/.test(value) || "L'email doit être valide.",
|
||||
};
|
||||
|
||||
const toggleShow = (articleId) => {
|
||||
showStates.value[articleId] = !showStates.value[articleId];
|
||||
};
|
||||
|
||||
// Fetch articles data
|
||||
const fetchContent = async () => {
|
||||
try {
|
||||
const { data: contentData, error } = await useAsyncData('content', () =>
|
||||
queryContent().find()
|
||||
);
|
||||
|
||||
// Process fetched content
|
||||
if (!error.value && contentData.value) {
|
||||
for (const file of contentData.value) {
|
||||
if (file.type === "intro") {
|
||||
introduction.value = file;
|
||||
} else if (file.type === "article") {
|
||||
const article = {
|
||||
id: file.id,
|
||||
title: file.title,
|
||||
description: file.description,
|
||||
likes: file.likes || 0,
|
||||
dislikes: file.dislikes || 0,
|
||||
comments: file.comments || [],
|
||||
};
|
||||
|
||||
// Add the article locally
|
||||
articles.value.push(article);
|
||||
|
||||
await $fetch('/api/articles', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
id: article.id,
|
||||
title: article.title,
|
||||
description: article.description,
|
||||
likes: article.likes,
|
||||
dislikes: article.dislikes
|
||||
},
|
||||
});
|
||||
} else if (file.type === "summary") {
|
||||
summary.value = file;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Split articles into left and right columns
|
||||
// leftColumnArticles.value = articles.value.filter((_, index) => index % 2 === 0);
|
||||
// rightColumnArticles.value = articles.value.filter((_, index) => index % 2 !== 0);
|
||||
// Split articles into two columns (assuming a 50% split)
|
||||
const midIndex = Math.ceil(articles.value.length / 2);
|
||||
leftColumnArticles.value = articles.value.slice(0, midIndex);
|
||||
rightColumnArticles.value = articles.value.slice(midIndex);
|
||||
// Initialize newComments object based on article IDs
|
||||
articles.value.forEach(article => {
|
||||
newComments.value[article.id] = '';
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
console.error('Error fetching content:', err);
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
await fetchContent()
|
||||
await fetchArticlesData(articles);
|
||||
await fetchCommentsData(articles);
|
||||
await fetchSignatures(signatures);
|
||||
});
|
||||
|
||||
const likeArticle = (articleId) => {
|
||||
updateLikeDislike({
|
||||
type: 'article',
|
||||
action: 'like',
|
||||
id: articleId,
|
||||
articles,
|
||||
});
|
||||
};
|
||||
|
||||
const dislikeArticle = (articleId) => {
|
||||
updateLikeDislike({
|
||||
type: 'article',
|
||||
action: 'dislike',
|
||||
id: articleId,
|
||||
articles,
|
||||
});
|
||||
};
|
||||
|
||||
const likeComment = (articleId, commentId) => {
|
||||
updateLikeDislike({
|
||||
type: 'comment',
|
||||
action: 'like',
|
||||
id: commentId,
|
||||
articleId,
|
||||
articles,
|
||||
});
|
||||
};
|
||||
|
||||
const dislikeComment = (articleId, commentId) => {
|
||||
updateLikeDislike({
|
||||
type: 'comment',
|
||||
action: 'dislike',
|
||||
id: commentId,
|
||||
articleId,
|
||||
articles,
|
||||
});
|
||||
};
|
||||
|
||||
const addComment = async (articleId) => {
|
||||
const commentText = newComments.value[articleId]?.trim();
|
||||
if (!commentText) return;
|
||||
|
||||
try {
|
||||
const response = await $fetch('/api/comments', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
content: commentText,
|
||||
articleId,
|
||||
likes: 0,
|
||||
dislikes: 0,
|
||||
},
|
||||
});
|
||||
|
||||
if (response.success) {
|
||||
const article = articles.value.find((a) => a.id === articleId);
|
||||
if (article) {
|
||||
article.comments.push({
|
||||
id: response.data.id,
|
||||
content: commentText,
|
||||
likes: 0,
|
||||
dislikes: 0,
|
||||
});
|
||||
}
|
||||
|
||||
// Reset the input field for the current article
|
||||
newComments.value[articleId] = '';
|
||||
|
||||
// Display success overlay
|
||||
showOverlay(
|
||||
{
|
||||
icon: 'mdi-check-circle',
|
||||
message: `Merci pour votre suggestion. Veuillez la consulter tout en descendant vers le bas de la page.`,
|
||||
buttonText: 'Continuer',
|
||||
iconColor: 'success',
|
||||
},
|
||||
overlay
|
||||
);
|
||||
console.log('Comment added successfully');
|
||||
} else {
|
||||
console.error('Failed to add comment:', response.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error in addComment:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const submitSignature = async () => {
|
||||
if (isFormValid.value) {
|
||||
const signatureData = {
|
||||
name: name.value,
|
||||
email: email.value,
|
||||
comment: comment.value,
|
||||
};
|
||||
signatures.value.push({ ...signatureData });
|
||||
try {
|
||||
await $fetch('/api/charte', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(signatureData)
|
||||
})
|
||||
// Display success overlay using the reusable function
|
||||
showOverlay(
|
||||
{
|
||||
icon: 'mdi-check-circle',
|
||||
message: `Merci pour votre signature ${name.value}`,
|
||||
buttonText: 'Continuer',
|
||||
iconColor: 'success',
|
||||
},
|
||||
overlay
|
||||
)
|
||||
name.value = '';
|
||||
email.value = '';
|
||||
comment.value = '';
|
||||
console.log('Charte is submitted successfully');
|
||||
} catch (error) {
|
||||
console.error('Error in submit signature:', error);
|
||||
}
|
||||
} return;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.video-section {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 50vh;
|
||||
overflow: hidden;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.video-background {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: bold;
|
||||
font-family: "Times New Roman", Times, serif;
|
||||
}
|
||||
|
||||
p {
|
||||
font-family: "Times New Roman", Times, serif;
|
||||
}
|
||||
|
||||
.v-expansion-panel-title {
|
||||
font-family: Georgia;
|
||||
}
|
||||
|
||||
.v-card {
|
||||
font-family: Georgia;
|
||||
}
|
||||
|
||||
.overlay-msg {
|
||||
font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
|
||||
}
|
||||
|
||||
.custom-btn {
|
||||
font-size: 12px;
|
||||
font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
|
||||
padding: 4px 8px;
|
||||
min-height: 24px;
|
||||
min-width: 40px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.v-icon:hover {
|
||||
opacity: 0.5;
|
||||
}
|
||||
</style>
|
||||
BIN
prisma/dev.db-journal
Normal file
BIN
prisma/dev.db-journal
Normal file
Binary file not shown.
24
prisma/migrations/20241220103022_/migration.sql
Normal file
24
prisma/migrations/20241220103022_/migration.sql
Normal file
@@ -0,0 +1,24 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "Article" (
|
||||
"id" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"description" TEXT NOT NULL,
|
||||
"likes" INTEGER NOT NULL DEFAULT 0,
|
||||
"dislikes" INTEGER NOT NULL DEFAULT 0,
|
||||
"comments" TEXT[] DEFAULT ARRAY[]::TEXT[],
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Article_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Charte" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"email" TEXT NOT NULL,
|
||||
"comment" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "Charte_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
24
prisma/migrations/20241222124646_dav/migration.sql
Normal file
24
prisma/migrations/20241222124646_dav/migration.sql
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `comments` on the `Article` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "Article" DROP COLUMN "comments";
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Comment" (
|
||||
"id" TEXT NOT NULL,
|
||||
"content" TEXT NOT NULL,
|
||||
"likes" INTEGER NOT NULL DEFAULT 0,
|
||||
"dislikes" INTEGER NOT NULL DEFAULT 0,
|
||||
"articleId" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Comment_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Comment" ADD CONSTRAINT "Comment_articleId_fkey" FOREIGN KEY ("articleId") REFERENCES "Article"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
3
prisma/migrations/migration_lock.toml
Normal file
3
prisma/migrations/migration_lock.toml
Normal file
@@ -0,0 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (e.g., Git)
|
||||
provider = "postgresql"
|
||||
40
prisma/schema.prisma
Normal file
40
prisma/schema.prisma
Normal file
@@ -0,0 +1,40 @@
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
model Article {
|
||||
id String @id @default(uuid())
|
||||
title String
|
||||
description String
|
||||
likes Int @default(0)
|
||||
dislikes Int @default(0)
|
||||
comments Comment[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model Comment {
|
||||
id String @id @default(uuid())
|
||||
content String
|
||||
likes Int @default(0)
|
||||
dislikes Int @default(0)
|
||||
articleId String // Foreign key for the related article
|
||||
article Article @relation(fields: [articleId], references: [id]) // Define relationship
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model Charte {
|
||||
id String @id @default(uuid())
|
||||
name String
|
||||
email String
|
||||
comment String?
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
31
server/api/articles/[id].get.ts
Normal file
31
server/api/articles/[id].get.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import prisma from '~/lib/prisma';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const id = event.context.params?.id;
|
||||
|
||||
try {
|
||||
const article = await prisma.article.findUnique({
|
||||
where: { id },
|
||||
include: { comments: true },
|
||||
});
|
||||
|
||||
if (!article) {
|
||||
return {
|
||||
success: false,
|
||||
data: null,
|
||||
message: 'Article not found.',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: article,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error fetching article:', error);
|
||||
return {
|
||||
success: false,
|
||||
error: error.message,
|
||||
};
|
||||
}
|
||||
});
|
||||
36
server/api/articles/[id].put.ts
Normal file
36
server/api/articles/[id].put.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import prisma from '~/lib/prisma';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const id = event.context.params?.id;
|
||||
const body = await readBody(event);
|
||||
|
||||
if (!id) {
|
||||
return {
|
||||
success: false,
|
||||
message: 'Invalid article ID.',
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const updatedArticle = await prisma.article.update({
|
||||
where: { id },
|
||||
data: {
|
||||
title: body.title,
|
||||
description: body.description,
|
||||
likes: body.likes,
|
||||
dislikes: body.dislikes,
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: updatedArticle,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error updating article:', error);
|
||||
return {
|
||||
success: false,
|
||||
error: error.message,
|
||||
};
|
||||
}
|
||||
});
|
||||
28
server/api/articles/index.get.ts
Normal file
28
server/api/articles/index.get.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import prisma from '~/lib/prisma';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
const articles = await prisma.article.findMany({
|
||||
include: { comments: true },
|
||||
});
|
||||
|
||||
if (!articles || articles.length === 0) {
|
||||
return {
|
||||
success: false,
|
||||
data: null,
|
||||
message: 'No articles found.',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: articles,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error fetching articles:', error);
|
||||
return {
|
||||
success: false,
|
||||
error: error.message,
|
||||
};
|
||||
}
|
||||
});
|
||||
30
server/api/articles/index.post.ts
Normal file
30
server/api/articles/index.post.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import prisma from '~/lib/prisma';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
const body = await readBody(event);
|
||||
const { title, description, likes, dislikes } = body;
|
||||
|
||||
const newArticle = await prisma.article.create({
|
||||
data: {
|
||||
title,
|
||||
description,
|
||||
likes: likes || 0,
|
||||
dislikes: dislikes || 0,
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: 'Article created successfully',
|
||||
data: newArticle,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error creating article:', error);
|
||||
return {
|
||||
success: false,
|
||||
message: 'An error occurred while creating the article',
|
||||
error: error.message,
|
||||
};
|
||||
}
|
||||
});
|
||||
26
server/api/charte/index.get.ts
Normal file
26
server/api/charte/index.get.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import prisma from '~/lib/prisma';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
const chartes = await prisma.charte.findMany();
|
||||
|
||||
if (!chartes || chartes.length === 0) {
|
||||
return {
|
||||
success: false,
|
||||
data: null,
|
||||
message: 'No chartes found.',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: chartes,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error fetching chartes:', error);
|
||||
return {
|
||||
success: false,
|
||||
error: error.message,
|
||||
};
|
||||
}
|
||||
});
|
||||
49
server/api/charte/index.post.ts
Normal file
49
server/api/charte/index.post.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import prisma from '~/lib/prisma';
|
||||
import { defineEventHandler, readBody, createError } from 'h3';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
// Read the request body
|
||||
const body = await readBody(event);
|
||||
|
||||
// Validate the input: Name, Email, and optionally Comment
|
||||
const { name, email, comment } = body;
|
||||
|
||||
if (!name || !email) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
message: 'Name and Email are required',
|
||||
});
|
||||
}
|
||||
|
||||
// Create the charte entry in the database
|
||||
const charte = await prisma.charte.create({
|
||||
data: {
|
||||
name,
|
||||
email,
|
||||
comment: comment || '', // Default to an empty string if no comment is provided
|
||||
},
|
||||
});
|
||||
|
||||
// Return success and the created charte data
|
||||
return { success: true, charte };
|
||||
} catch (error) {
|
||||
// Log the error for debugging
|
||||
console.error('Error in charte API:', error);
|
||||
|
||||
// Handle specific Prisma or validation errors
|
||||
if (error.code === 'P2002') {
|
||||
// Prisma-specific error for unique constraint violations (e.g., unique email)
|
||||
throw createError({
|
||||
statusCode: 409,
|
||||
message: 'A charte entry with this email already exists.',
|
||||
});
|
||||
}
|
||||
|
||||
// Return a general error for unexpected issues
|
||||
throw createError({
|
||||
statusCode: error.statusCode || 500,
|
||||
message: error.message || 'Internal Server Error',
|
||||
});
|
||||
}
|
||||
});
|
||||
30
server/api/comments/[id].delete.ts
Normal file
30
server/api/comments/[id].delete.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import prisma from '~/lib/prisma';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const id = event.context.params?.id;
|
||||
|
||||
if (!id) {
|
||||
return {
|
||||
success: false,
|
||||
message: 'Invalid comment ID.',
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
await prisma.comment.delete({
|
||||
where: { id },
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: 'Comment deleted successfully',
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error deleting comment:', error);
|
||||
return {
|
||||
success: false,
|
||||
message: 'An error occurred while deleting the comment',
|
||||
error: error.message,
|
||||
};
|
||||
}
|
||||
});
|
||||
37
server/api/comments/[id].put.ts
Normal file
37
server/api/comments/[id].put.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import prisma from '~/lib/prisma';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const id = event.context.params?.id;
|
||||
const body = await readBody(event);
|
||||
|
||||
if (!id) {
|
||||
return {
|
||||
success: false,
|
||||
message: 'Invalid comment ID.',
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const updatedComment = await prisma.comment.update({
|
||||
where: { id },
|
||||
data: {
|
||||
content: body.content,
|
||||
likes: body.likes,
|
||||
dislikes: body.dislikes,
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: 'Comment updated successfully',
|
||||
data: updatedComment,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error updating comment:', error);
|
||||
return {
|
||||
success: false,
|
||||
message: 'An error occurred while updating the comment',
|
||||
error: error.message,
|
||||
};
|
||||
}
|
||||
});
|
||||
24
server/api/comments/index.get.ts
Normal file
24
server/api/comments/index.get.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import prisma from '~/lib/prisma';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const query = getQuery(event);
|
||||
const { articleId } = query;
|
||||
|
||||
try {
|
||||
const comments = await prisma.comment.findMany({
|
||||
where: articleId ? { articleId: String(articleId) } : undefined,
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: comments,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error fetching comments:', error);
|
||||
return {
|
||||
success: false,
|
||||
message: 'An error occurred while fetching comments',
|
||||
error: error.message,
|
||||
};
|
||||
}
|
||||
});
|
||||
37
server/api/comments/index.post.ts
Normal file
37
server/api/comments/index.post.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import prisma from '~/lib/prisma';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
const body = await readBody(event);
|
||||
const { content, articleId, likes, dislikes } = body;
|
||||
|
||||
if (!content || !articleId) {
|
||||
return {
|
||||
success: false,
|
||||
message: 'Content and articleId are required to create a comment.',
|
||||
};
|
||||
}
|
||||
|
||||
const newComment = await prisma.comment.create({
|
||||
data: {
|
||||
content,
|
||||
articleId,
|
||||
likes: likes || 0,
|
||||
dislikes: dislikes || 0,
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: 'Comment created successfully',
|
||||
data: newComment,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error creating comment:', error);
|
||||
return {
|
||||
success: false,
|
||||
message: 'An error occurred while creating the comment',
|
||||
error: error.message,
|
||||
};
|
||||
}
|
||||
});
|
||||
4
supabase/.gitignore
vendored
Normal file
4
supabase/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# Supabase
|
||||
.branches
|
||||
.temp
|
||||
.env
|
||||
247
supabase/config.toml
Normal file
247
supabase/config.toml
Normal file
@@ -0,0 +1,247 @@
|
||||
# A string used to distinguish different Supabase projects on the same host. Defaults to the
|
||||
# working directory name when running `supabase init`.
|
||||
project_id = "DAV"
|
||||
|
||||
[api]
|
||||
enabled = true
|
||||
# Port to use for the API URL.
|
||||
port = 54321
|
||||
# Schemas to expose in your API. Tables, views and stored procedures in this schema will get API
|
||||
# endpoints. `public` is always included.
|
||||
schemas = ["public", "graphql_public"]
|
||||
# Extra schemas to add to the search_path of every request. `public` is always included.
|
||||
extra_search_path = ["public", "extensions"]
|
||||
# The maximum number of rows returns from a view, table, or stored procedure. Limits payload size
|
||||
# for accidental or malicious requests.
|
||||
max_rows = 1000
|
||||
|
||||
[api.tls]
|
||||
enabled = false
|
||||
|
||||
[db]
|
||||
# Port to use for the local database URL.
|
||||
port = 54322
|
||||
# Port used by db diff command to initialize the shadow database.
|
||||
shadow_port = 54320
|
||||
# The database major version to use. This has to be the same as your remote database's. Run `SHOW
|
||||
# server_version;` on the remote database to check.
|
||||
major_version = 15
|
||||
|
||||
[db.pooler]
|
||||
enabled = false
|
||||
# Port to use for the local connection pooler.
|
||||
port = 54329
|
||||
# Specifies when a server connection can be reused by other clients.
|
||||
# Configure one of the supported pooler modes: `transaction`, `session`.
|
||||
pool_mode = "transaction"
|
||||
# How many server connections to allow per user/database pair.
|
||||
default_pool_size = 20
|
||||
# Maximum number of client connections allowed.
|
||||
max_client_conn = 100
|
||||
|
||||
[db.seed]
|
||||
# If enabled, seeds the database after migrations during a db reset.
|
||||
enabled = true
|
||||
# Specifies an ordered list of seed files to load during db reset.
|
||||
# Supports glob patterns relative to supabase directory. For example:
|
||||
# sql_paths = ['./seeds/*.sql', '../project-src/seeds/*-load-testing.sql']
|
||||
sql_paths = ['./seed.sql']
|
||||
|
||||
[realtime]
|
||||
enabled = true
|
||||
# Bind realtime via either IPv4 or IPv6. (default: IPv4)
|
||||
# ip_version = "IPv6"
|
||||
# The maximum length in bytes of HTTP request headers. (default: 4096)
|
||||
# max_header_length = 4096
|
||||
|
||||
[studio]
|
||||
enabled = true
|
||||
# Port to use for Supabase Studio.
|
||||
port = 54323
|
||||
# External URL of the API server that frontend connects to.
|
||||
api_url = "http://127.0.0.1"
|
||||
# OpenAI API Key to use for Supabase AI in the Supabase Studio.
|
||||
openai_api_key = "env(OPENAI_API_KEY)"
|
||||
|
||||
# Email testing server. Emails sent with the local dev setup are not actually sent - rather, they
|
||||
# are monitored, and you can view the emails that would have been sent from the web interface.
|
||||
[inbucket]
|
||||
enabled = true
|
||||
# Port to use for the email testing server web interface.
|
||||
port = 54324
|
||||
# Uncomment to expose additional ports for testing user applications that send emails.
|
||||
# smtp_port = 54325
|
||||
# pop3_port = 54326
|
||||
|
||||
[storage]
|
||||
enabled = true
|
||||
# The maximum file size allowed (e.g. "5MB", "500KB").
|
||||
file_size_limit = "50MiB"
|
||||
|
||||
[storage.image_transformation]
|
||||
enabled = true
|
||||
|
||||
# Uncomment to configure local storage buckets
|
||||
# [storage.buckets.images]
|
||||
# public = false
|
||||
# file_size_limit = "50MiB"
|
||||
# allowed_mime_types = ["image/png", "image/jpeg"]
|
||||
# objects_path = "./images"
|
||||
|
||||
[auth]
|
||||
enabled = true
|
||||
# The base URL of your website. Used as an allow-list for redirects and for constructing URLs used
|
||||
# in emails.
|
||||
site_url = "http://127.0.0.1:3000"
|
||||
# A list of *exact* URLs that auth providers are permitted to redirect to post authentication.
|
||||
additional_redirect_urls = ["https://127.0.0.1:3000"]
|
||||
# How long tokens are valid for, in seconds. Defaults to 3600 (1 hour), maximum 604,800 (1 week).
|
||||
jwt_expiry = 3600
|
||||
# If disabled, the refresh token will never expire.
|
||||
enable_refresh_token_rotation = true
|
||||
# Allows refresh tokens to be reused after expiry, up to the specified interval in seconds.
|
||||
# Requires enable_refresh_token_rotation = true.
|
||||
refresh_token_reuse_interval = 10
|
||||
# Allow/disallow new user signups to your project.
|
||||
enable_signup = true
|
||||
# Allow/disallow anonymous sign-ins to your project.
|
||||
enable_anonymous_sign_ins = false
|
||||
# Allow/disallow testing manual linking of accounts
|
||||
enable_manual_linking = false
|
||||
|
||||
[auth.email]
|
||||
# Allow/disallow new user signups via email to your project.
|
||||
enable_signup = true
|
||||
# If enabled, a user will be required to confirm any email change on both the old, and new email
|
||||
# addresses. If disabled, only the new email is required to confirm.
|
||||
double_confirm_changes = true
|
||||
# If enabled, users need to confirm their email address before signing in.
|
||||
enable_confirmations = false
|
||||
# If enabled, users will need to reauthenticate or have logged in recently to change their password.
|
||||
secure_password_change = false
|
||||
# Controls the minimum amount of time that must pass before sending another signup confirmation or password reset email.
|
||||
max_frequency = "1s"
|
||||
|
||||
# Use a production-ready SMTP server
|
||||
# [auth.email.smtp]
|
||||
# host = "smtp.sendgrid.net"
|
||||
# port = 587
|
||||
# user = "apikey"
|
||||
# pass = "env(SENDGRID_API_KEY)"
|
||||
# admin_email = "admin@email.com"
|
||||
# sender_name = "Admin"
|
||||
|
||||
# Uncomment to customize email template
|
||||
# [auth.email.template.invite]
|
||||
# subject = "You have been invited"
|
||||
# content_path = "./supabase/templates/invite.html"
|
||||
|
||||
[auth.sms]
|
||||
# Allow/disallow new user signups via SMS to your project.
|
||||
enable_signup = true
|
||||
# If enabled, users need to confirm their phone number before signing in.
|
||||
enable_confirmations = false
|
||||
# Template for sending OTP to users
|
||||
template = "Your code is {{ .Code }} ."
|
||||
# Controls the minimum amount of time that must pass before sending another sms otp.
|
||||
max_frequency = "5s"
|
||||
|
||||
# Use pre-defined map of phone number to OTP for testing.
|
||||
# [auth.sms.test_otp]
|
||||
# 4152127777 = "123456"
|
||||
|
||||
# Configure logged in session timeouts.
|
||||
# [auth.sessions]
|
||||
# Force log out after the specified duration.
|
||||
# timebox = "24h"
|
||||
# Force log out if the user has been inactive longer than the specified duration.
|
||||
# inactivity_timeout = "8h"
|
||||
|
||||
# This hook runs before a token is issued and allows you to add additional claims based on the authentication method used.
|
||||
# [auth.hook.custom_access_token]
|
||||
# enabled = true
|
||||
# uri = "pg-functions://<database>/<schema>/<hook_name>"
|
||||
|
||||
# Configure one of the supported SMS providers: `twilio`, `twilio_verify`, `messagebird`, `textlocal`, `vonage`.
|
||||
[auth.sms.twilio]
|
||||
enabled = false
|
||||
account_sid = ""
|
||||
message_service_sid = ""
|
||||
# DO NOT commit your Twilio auth token to git. Use environment variable substitution instead:
|
||||
auth_token = "env(SUPABASE_AUTH_SMS_TWILIO_AUTH_TOKEN)"
|
||||
|
||||
[auth.mfa]
|
||||
# Control how many MFA factors can be enrolled at once per user.
|
||||
max_enrolled_factors = 10
|
||||
|
||||
# Control use of MFA via App Authenticator (TOTP)
|
||||
[auth.mfa.totp]
|
||||
enroll_enabled = true
|
||||
verify_enabled = true
|
||||
|
||||
# Configure Multi-factor-authentication via Phone Messaging
|
||||
# [auth.mfa.phone]
|
||||
# enroll_enabled = true
|
||||
# verify_enabled = true
|
||||
# otp_length = 6
|
||||
# template = "Your code is {{ .Code }} ."
|
||||
# max_frequency = "10s"
|
||||
|
||||
# Use an external OAuth provider. The full list of providers are: `apple`, `azure`, `bitbucket`,
|
||||
# `discord`, `facebook`, `github`, `gitlab`, `google`, `keycloak`, `linkedin_oidc`, `notion`, `twitch`,
|
||||
# `twitter`, `slack`, `spotify`, `workos`, `zoom`.
|
||||
[auth.external.apple]
|
||||
enabled = false
|
||||
client_id = ""
|
||||
# DO NOT commit your OAuth provider secret to git. Use environment variable substitution instead:
|
||||
secret = "env(SUPABASE_AUTH_EXTERNAL_APPLE_SECRET)"
|
||||
# Overrides the default auth redirectUrl.
|
||||
redirect_uri = ""
|
||||
# Overrides the default auth provider URL. Used to support self-hosted gitlab, single-tenant Azure,
|
||||
# or any other third-party OIDC providers.
|
||||
url = ""
|
||||
# If enabled, the nonce check will be skipped. Required for local sign in with Google auth.
|
||||
skip_nonce_check = false
|
||||
|
||||
# Use Firebase Auth as a third-party provider alongside Supabase Auth.
|
||||
[auth.third_party.firebase]
|
||||
enabled = false
|
||||
# project_id = "my-firebase-project"
|
||||
|
||||
# Use Auth0 as a third-party provider alongside Supabase Auth.
|
||||
[auth.third_party.auth0]
|
||||
enabled = false
|
||||
# tenant = "my-auth0-tenant"
|
||||
# tenant_region = "us"
|
||||
|
||||
# Use AWS Cognito (Amplify) as a third-party provider alongside Supabase Auth.
|
||||
[auth.third_party.aws_cognito]
|
||||
enabled = false
|
||||
# user_pool_id = "my-user-pool-id"
|
||||
# user_pool_region = "us-east-1"
|
||||
|
||||
[edge_runtime]
|
||||
enabled = true
|
||||
# Configure one of the supported request policies: `oneshot`, `per_worker`.
|
||||
# Use `oneshot` for hot reload, or `per_worker` for load testing.
|
||||
policy = "oneshot"
|
||||
inspector_port = 8083
|
||||
|
||||
[analytics]
|
||||
enabled = true
|
||||
port = 54327
|
||||
# Configure one of the supported backends: `postgres`, `bigquery`.
|
||||
backend = "postgres"
|
||||
|
||||
# Experimental features may be deprecated any time
|
||||
[experimental]
|
||||
# Configures Postgres storage engine to use OrioleDB (S3)
|
||||
orioledb_version = ""
|
||||
# Configures S3 bucket URL, eg. <bucket_name>.s3-<region>.amazonaws.com
|
||||
s3_host = "env(S3_HOST)"
|
||||
# Configures S3 bucket region, eg. us-east-1
|
||||
s3_region = "env(S3_REGION)"
|
||||
# Configures AWS_ACCESS_KEY_ID for S3 bucket
|
||||
s3_access_key = "env(S3_ACCESS_KEY)"
|
||||
# Configures AWS_SECRET_ACCESS_KEY for S3 bucket
|
||||
s3_secret_key = "env(S3_SECRET_KEY)"
|
||||
15
tailwind.config.js
Normal file
15
tailwind.config.js
Normal file
@@ -0,0 +1,15 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: [
|
||||
"./components/**/*.{js,vue,ts}",
|
||||
"./layouts/**/*.vue",
|
||||
"./pages/**/*.vue",
|
||||
"./plugins/**/*.{js,ts}",
|
||||
"./app.vue",
|
||||
"./error.vue",
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
Reference in New Issue
Block a user