Added API .env and removed "Menu" from navbar
This commit is contained in:
1
.env.development
Normal file
1
.env.development
Normal file
@@ -0,0 +1 @@
|
|||||||
|
VITE_API_URL = "http://localhost:3000"
|
||||||
1
.env.production
Normal file
1
.env.production
Normal file
@@ -0,0 +1 @@
|
|||||||
|
VITE_API_URL = "https://api-deputes.alexcreates.fr"
|
||||||
@@ -5,7 +5,7 @@ import Navbar from "./components/navbar/Navbar.vue";
|
|||||||
<template>
|
<template>
|
||||||
<div id="wrapper">
|
<div id="wrapper">
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<div id="content">
|
<div class="flex justify-center items-center">
|
||||||
<RouterView />
|
<RouterView />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
21
src/components/GeolocRequest.vue
Normal file
21
src/components/GeolocRequest.vue
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { useRepStore } from "@/stores/repStore";
|
||||||
|
import { useGeolocation } from "@vueuse/core";
|
||||||
|
|
||||||
|
const { coords } = useGeolocation();
|
||||||
|
const { getRep, setRep } = useRepStore();
|
||||||
|
|
||||||
|
async function handleGeolocClick() {
|
||||||
|
const rep = await getRep(coords.value.longitude, coords.value.latitude);
|
||||||
|
setRep(rep);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<button
|
||||||
|
class="py-2 px-4 rounded-sm bg-white text-sm text-slate-950"
|
||||||
|
@click="handleGeolocClick"
|
||||||
|
>
|
||||||
|
Trouver mon député
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
45
src/components/RepInfo.vue
Normal file
45
src/components/RepInfo.vue
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import type { Depute } from "@/models/rep";
|
||||||
|
import { computed } from "vue";
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
rep: Depute;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const repImage = computed(() => {
|
||||||
|
const imageRef = props.rep.acteur.uid["#text"].replace("PA", "");
|
||||||
|
return `https://www2.assemblee-nationale.fr/static/tribun/16/photos/carre/${imageRef}.jpg`;
|
||||||
|
});
|
||||||
|
|
||||||
|
const repFullName = computed(
|
||||||
|
() =>
|
||||||
|
`${props.rep.acteur.etatCivil.ident.prenom} ${props.rep.acteur.etatCivil.ident.nom}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const repMandate = computed(() => {
|
||||||
|
const parliamentMandate = props.rep.acteur.mandats.mandat.find(
|
||||||
|
(mandate) => mandate["@xsi:type"] === "MandatParlementaire_type"
|
||||||
|
);
|
||||||
|
return parliamentMandate;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<article>
|
||||||
|
<figure class="mb-8 mx-auto w-60 h-60 rounded-full overflow-hidden">
|
||||||
|
<img
|
||||||
|
:src="repImage"
|
||||||
|
:alt="repFullName"
|
||||||
|
class="w-full h-full object-contain"
|
||||||
|
/>
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
<h1 class="mb-4 text-center font-bold text-3xl">
|
||||||
|
{{ repFullName }}
|
||||||
|
</h1>
|
||||||
|
<h2 class="text-center font-bold text-xl">
|
||||||
|
{{ repMandate?.election?.lieu.departement }} -
|
||||||
|
{{ repMandate?.election?.lieu.numCirco }}e circonscription
|
||||||
|
</h2>
|
||||||
|
</article>
|
||||||
|
</template>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<nav class="bg-slate-900">
|
<nav class="bg-slate-900">
|
||||||
<div class="container py-4">Menu</div>
|
<div class="container py-4">Mon Député</div>
|
||||||
</nav>
|
</nav>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
146
src/models/rep.ts
Normal file
146
src/models/rep.ts
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
export interface Depute {
|
||||||
|
acteur: Acteur;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Acteur {
|
||||||
|
"@xmlns:xsi": string;
|
||||||
|
uid: Uid;
|
||||||
|
etatCivil: EtatCivil;
|
||||||
|
profession: Profession;
|
||||||
|
uri_hatvp: string;
|
||||||
|
adresses: Adresses;
|
||||||
|
mandats: Mandats;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Adresses {
|
||||||
|
adresse: { [key: string]: null | string }[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EtatCivil {
|
||||||
|
ident: Ident;
|
||||||
|
infoNaissance: InfoNaissance;
|
||||||
|
dateDeces: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Ident {
|
||||||
|
civ: string;
|
||||||
|
prenom: string;
|
||||||
|
nom: string;
|
||||||
|
alpha: string;
|
||||||
|
trigramme: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InfoNaissance {
|
||||||
|
dateNais: Date;
|
||||||
|
villeNais: string;
|
||||||
|
depNais: string;
|
||||||
|
paysNais: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Mandats {
|
||||||
|
mandat: Mandat[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Mandat {
|
||||||
|
"@xsi:type": XsiType;
|
||||||
|
uid: string;
|
||||||
|
acteurRef: Text;
|
||||||
|
legislature: null | string;
|
||||||
|
typeOrgane: string;
|
||||||
|
dateDebut: Date;
|
||||||
|
datePublication: Date | null;
|
||||||
|
dateFin: Date | null;
|
||||||
|
preseance: string;
|
||||||
|
nominPrincipale: string;
|
||||||
|
infosQualite: InfosQualite;
|
||||||
|
organes: Organes;
|
||||||
|
suppleants?: Suppleants | null;
|
||||||
|
libelle?: null;
|
||||||
|
missionSuivanteRef?: null;
|
||||||
|
missionPrecedenteRef?: null;
|
||||||
|
chambre?: null;
|
||||||
|
election?: Election;
|
||||||
|
mandature?: Mandature;
|
||||||
|
collaborateurs?: Collaborateurs;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum XsiType {
|
||||||
|
MandatAvecSuppleantType = "MandatAvecSuppleant_Type",
|
||||||
|
MandatMissionType = "MandatMission_Type",
|
||||||
|
MandatParlementaireType = "MandatParlementaire_type",
|
||||||
|
MandatSimpleType = "MandatSimple_Type",
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum Text {
|
||||||
|
Pa794094 = "PA794094",
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Collaborateurs {
|
||||||
|
collaborateur: Collaborateur[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Collaborateur {
|
||||||
|
qualite: string;
|
||||||
|
prenom: string;
|
||||||
|
nom: string;
|
||||||
|
dateDebut: null;
|
||||||
|
dateFin: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Election {
|
||||||
|
lieu: Lieu;
|
||||||
|
causeMandat: string;
|
||||||
|
refCirconscription: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Lieu {
|
||||||
|
region: string;
|
||||||
|
regionType: string;
|
||||||
|
departement: string;
|
||||||
|
numDepartement: string;
|
||||||
|
numCirco: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InfosQualite {
|
||||||
|
codeQualite: string;
|
||||||
|
libQualite: string;
|
||||||
|
libQualiteSex: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Mandature {
|
||||||
|
datePriseFonction: Date;
|
||||||
|
causeFin: null;
|
||||||
|
premiereElection: string;
|
||||||
|
placeHemicycle: string;
|
||||||
|
matriculeVote: string;
|
||||||
|
mandatRemplaceRef: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Organes {
|
||||||
|
organeRef: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Suppleants {
|
||||||
|
suppleant: Suppleant;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Suppleant {
|
||||||
|
dateDebut: Date;
|
||||||
|
dateFin: null;
|
||||||
|
suppleantRef: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Profession {
|
||||||
|
libelleCourant: string;
|
||||||
|
socProcINSEE: SocProcINSEE;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SocProcINSEE {
|
||||||
|
catSocPro: string;
|
||||||
|
famSocPro: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Uid {
|
||||||
|
"@xsi:type": string;
|
||||||
|
"#text": Text;
|
||||||
|
}
|
||||||
@@ -1,11 +1,21 @@
|
|||||||
|
import type { Depute } from "@/models/rep";
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
export const useCirStore = defineStore("repStore", () => {
|
const apiUrl = import.meta.env.VITE_API_URL;
|
||||||
async function getRep(lon: number, lat: number): Promise<any> {
|
|
||||||
return fetch(`http://localhost:3000/rep?lat=${lat}&lon=${lon}`).then((t) =>
|
export const useRepStore = defineStore("repStore", () => {
|
||||||
t.json()
|
const currentRep = ref<Depute | null>(null);
|
||||||
);
|
|
||||||
|
async function getRep(lon: number, lat: number): Promise<Depute> {
|
||||||
|
return fetch(`${apiUrl}/rep?lat=${lat}&lon=${lon}`)
|
||||||
|
.then((t) => t.json())
|
||||||
|
.catch((err) => console.log(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
return { getRep };
|
function setRep(rep: Depute) {
|
||||||
|
currentRep.value = rep;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { getRep, setRep, currentRep };
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,33 +1,42 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useCirStore } from "@/stores/repStore";
|
import GeolocRequest from "@/components/GeolocRequest.vue";
|
||||||
import { useGeolocation } from "@vueuse/core";
|
import RepInfo from "@/components/RepInfo.vue";
|
||||||
import { ref } from "vue";
|
import { useRepStore } from "@/stores/repStore";
|
||||||
|
import { storeToRefs } from "pinia";
|
||||||
|
|
||||||
const { coords } = useGeolocation();
|
const { currentRep } = storeToRefs(useRepStore());
|
||||||
const { getRep } = useCirStore();
|
|
||||||
|
|
||||||
const currentRepValue = ref<any>();
|
|
||||||
|
|
||||||
async function handleGeolocClick() {
|
|
||||||
currentRepValue.value = await getRep(
|
|
||||||
coords.value.longitude,
|
|
||||||
coords.value.latitude
|
|
||||||
);
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<main class="container py-4">
|
<main class="container py-4">
|
||||||
<button
|
<Transition name="fade" mode="out-in">
|
||||||
class="py-2 px-4 rounded-sm bg-white text-sm text-slate-950"
|
<GeolocRequest v-if="!currentRep" />
|
||||||
@click="handleGeolocClick"
|
<Suspense v-else>
|
||||||
>
|
<RepInfo :rep="currentRep" />
|
||||||
Trouver mon député
|
</Suspense>
|
||||||
</button>
|
</Transition>
|
||||||
<pre>
|
|
||||||
{{ currentRepValue }}
|
|
||||||
</pre>
|
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.fade-enter-from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
.fade-enter-to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.fade-enter-active {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
.fade-leave-from {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.fade-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
.fade-leave-active {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user