Finally implemented EventStore.ts

This commit is contained in:
Laurent
2025-03-19 13:45:03 +01:00
parent 9b8b2463a3
commit 83a0a23268
16 changed files with 191 additions and 53 deletions

View File

@@ -1,19 +1,34 @@
<script setup lang="ts"> <script setup lang="ts">
import Button from "@/components/Button.vue"; import Button from "@/components/Button.vue";
import {useRouter} from "vue-router";
const props = defineProps<{ const router = useRouter();
path: string;
description: string; const props = defineProps({
}>(); description: {
type: [String],
required: true
},
name: {
type: [String],
required: true
},
params: {
type: [Object],
required: false
}});
function browse() : void {
console.log({ name: props.name, params: props.params});
router.push({ name: props.name, params: props.params});
}
</script> </script>
<template> <template>
<div class="nav-link"> <div class="nav-link" @click="browse">
<router-link :to=path >
<Button :description="description"/> <Button :description="description"/>
</router-link>
</div> </div>
</template> </template>

17
front/src/dto/EventDto.ts Normal file
View File

@@ -0,0 +1,17 @@
import type {Participant} from "@/models/Participant.ts";
import type {TimeStamp} from "@/models/TimeStamp.ts";
import type {ParticipantDto} from "@/dto/ParticipantDto.ts";
export class EventDto {
public name: string;
public token: string;
public participants: ParticipantDto[];
public constructor(name: string, token: string, participants: ParticipantDto[]) {
this.name = name;
this.token = token;
this.participants = participants;
}
}

View File

@@ -0,0 +1,13 @@
import type {TimeStampDto} from "@/dto/TimeStampDto.ts";
export class ParticipantDto {
public name: string;
public dates: TimeStampDto[];
public constructor(name: string, dates: TimeStampDto[]) {
this.name = name;
this.dates = dates;
}
}

View File

@@ -0,0 +1,8 @@
export class TimeStampDto {
public timestamp : number;
public constructor(date : Date) {
this.timestamp = date.getTime();
}
}

View File

@@ -0,0 +1,7 @@
export abstract class DateHelper {
public static toDate(timestamp: number): Date {
return new Date(timestamp);
}
}

View File

@@ -9,9 +9,9 @@ import NavLink from "@/components/NavLink.vue";
<nav class="nav"> <nav class="nav">
<p>Let's<br>Meet</p> <p>Let's<br>Meet</p>
<div class="nav-actions-group"> <div class="nav-actions-group">
<NavLink path="/" description="Home"></NavLink> <NavLink name="home" description="Home"></NavLink>
<NavLink path="/login" description="Log in"></NavLink> <NavLink name="login" description="Log in"></NavLink>
<NavLink path="/about" description="About"></NavLink> <NavLink name="about" description="About"></NavLink>
</div> </div>
</nav> </nav>

View File

@@ -1,4 +1,5 @@
import type {Participant} from "@/models/Participant.ts"; import type {Participant, ParticipantState} from "@/models/Participant.ts";
import type {TimeStampState} from "@/models/TimeStamp.ts";
export class Event { export class Event {
@@ -12,4 +13,23 @@ export class Event {
this.participants = participants; this.participants = participants;
} }
public getName() : string {
return this.name;
}
public getToken() : string {
return this.token;
}
public getParticipants() : Participant[] {
return this.participants;
}
} }
export interface EventState {
name : String
token : String
participants: ParticipantState[];
}

View File

@@ -1,4 +1,4 @@
import type {TimeStamp} from "@/models/TimeStamp.ts"; import type {TimeStamp, TimeStampState} from "@/models/TimeStamp.ts";
export class Participant { export class Participant {
@@ -10,4 +10,16 @@ export class Participant {
this.dates = dates; this.dates = dates;
} }
public getName(){
return this.name;
}
public getDate() : TimeStamp[]{
return this.dates;
}
}
export interface ParticipantState {
name : String
dates : TimeStampState[]
} }

View File

@@ -10,3 +10,7 @@ export class TimeStamp {
return this.value; return this.value;
} }
} }
export interface TimeStampState {
value : number;
}

View File

@@ -1,4 +1,5 @@
import { API_PATHS } from "@/config/ApiConfig.ts"; import {API_PATHS} from "@/config/ApiConfig.ts";
import {EventDto} from "@/dto/EventDto.ts";
export class EventRequests { export class EventRequests {
@@ -12,22 +13,18 @@ export class EventRequests {
private formatUrl(parts:string[]) : string { private formatUrl(parts:string[]) : string {
let res = ""; let res = "";
console.log(parts)
parts.forEach((value) => { parts.forEach((value) => {
console.log(value)
res += value.trim(); res += value.trim();
}) })
return res.replace(/(http|https?:\/\/[^\/]+)\/\//, '$1/'); return res.replace(/([^:]\/)\/+/g, "$1");
} }
public queryEvent(token : string) { public async queryEvent(token : string): Promise<void | EventDto> {
let url = this.formatUrl([this.baseUrl, this.endpoints.EVENTS, token]); let url = this.formatUrl([this.baseUrl, this.endpoints.EVENTS, token]);
console.log(url); return fetch(url)
fetch(url)
.then(response => response.json()) .then(response => response.json())
.then(data => console.log(data)) .then(data => new EventDto(data.name, data.token, data.participants))
.catch(error => console.error(error)); .catch(error => console.error(error));
} }
} }

View File

@@ -9,13 +9,13 @@ import EventView from "@/views/EventView.vue";
const router = createRouter({ const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL), history: createWebHistory(import.meta.env.BASE_URL),
routes: [ routes: [
{ path: '/', name: 'home', component: HomeView}, { path: '/', name: 'home', component: HomeView},
{ path: '/about', name: 'about', component: AboutView}, { path: '/about', name: 'about', component: AboutView},
{ path: '/create', name: 'create', component: CreateView}, { path: '/create', name: 'create', component: CreateView},
{ path: '/join', name: 'join', component: JoinView}, { path: '/join', name: 'join', component: JoinView},
{ path: '/event', name: 'event', component: EventView}, { path: '/event/:token', name: 'event', component: EventView},
{ path: '/error', name: 'error', component: ErrorView}, { path: '/error', name: 'error', component: ErrorView},
{ path: '/:pathMatch(.*)*', component: ErrorView } { path: '/:pathMatch(.*)*', component: ErrorView }
] ]
}) })

View File

@@ -1,18 +1,44 @@
import { defineStore } from 'pinia' import {defineStore} from 'pinia'
import {EventRequests} from "@/requests/EventRequests.ts"; import {EventRequests} from "@/requests/EventRequests.ts";
import type {EventDto} from "@/dto/EventDto.ts";
import type {EventState} from "@/models/Event.ts";
import type {ParticipantDto} from "@/dto/ParticipantDto.ts";
import type {ParticipantState} from "@/models/Participant.ts";
import type {TimeStamp, TimeStampState} from "@/models/TimeStamp.ts";
import type {TimeStampDto} from "@/dto/TimeStampDto.ts";
const requests = new EventRequests(); const requests = new EventRequests();
export const eventStore = defineStore('datePicker', { export const eventStore = defineStore('eventStore', {
state: () => { state: (): {event : EventState} => {
return { return {
event: Event event : {
name: "",
token: "",
participants: [] as ParticipantState[]
}};
},
getters : {
getEvent() {
} }
}, },
actions: { actions: {
fetch: (token : string) => { async fetch(token: string): Promise<void> {
requests.queryEvent(token); try{
} let data : EventDto | void = await requests.queryEvent(token);
if(!data) throw new Error("No event found");
this.event.name = data.name;
this.event.token = data.token;
this.event.participants = data.participants.map((p: ParticipantDto) => ({
name: p.name,
dates: p.dates.map((date: TimeStampDto) => ({
value: date.timestamp
})) as TimeStampState[]
}));
} catch (error) {
console.error("Unable to fetch. " + error);
}
},
}, },
}) });

View File

@@ -13,7 +13,7 @@ import NavLink from "@/components/NavLink.vue";
</TextBlock> </TextBlock>
<div class="event-form"> <div class="event-form">
<Calendar class="calendar"/> <Calendar class="calendar"/>
<NavLink path="/create" description="Create" class="create-button"></NavLink> <NavLink name="Create" description="Create" class="create-button"></NavLink>
</div> </div>
</div> </div>

View File

@@ -1,9 +1,33 @@
<script setup lang="ts"> <script setup lang="ts">
import {eventStore} from "@/stores/EventStore.ts";
import {onMounted} from "vue";
import {useRoute} from "vue-router";
import {DateHelper} from "../helpers/DateHelper.ts";
const route = useRoute();
const store = eventStore();
const token = extractToken();
onMounted(async () => {
await store.fetch(token);
})
function extractToken() : string {
return Array.isArray(route.params.token) ? route.params.token[0] : route.params.token;
}
</script> </script>
<template> <template>
Name : {{ store.event.name }}
Participants :
<div v-for="(p) in store.event.participants" >
{{ p.name }}
<div v-for="(d) in p.dates">
{{ DateHelper.toDate(d.value) }}
</div>
</div>
</template> </template>
<style scoped> <style scoped>

View File

@@ -21,8 +21,8 @@ import TextBlock from "@/components/TextBlock.vue";
<div class="actions-group"> <div class="actions-group">
<h1>Meet up <span class="colored-text">now</span> !</h1> <h1>Meet up <span class="colored-text">now</span> !</h1>
<NavLink path="/create" description="Create"></NavLink> <NavLink name="create" description="Create"></NavLink>
<NavLink path="/join" description="Join"></NavLink> <NavLink name="join" description="Join"></NavLink>
</div> </div>
</div> </div>

View File

@@ -1,16 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import TextBlock from "@/components/TextBlock.vue"; import TextBlock from "@/components/TextBlock.vue";
import Button from "@/components/Button.vue";
import InputField from "@/components/InputField.vue"; import InputField from "@/components/InputField.vue";
import { eventStore } from "@/stores/EventStore.ts"; import NavLink from "@/components/NavLink.vue";
import {ref} from "vue";
let token : string = ''; const token = ref("");
const event = eventStore();
function fetch(){
event.fetch(token);
}
</script> </script>
@@ -22,9 +17,9 @@ function fetch(){
</TextBlock> </TextBlock>
<div class="actions-group"> <div class="actions-group">
<h1>Event <span class="colored-text">code</span></h1> <h1>EventDto <span class="colored-text">code</span></h1>
<InputField @update:value="(newValue) => {token = newValue}" /> <InputField @update:value="(newValue) => {token = newValue}" />
<Button description="Go for it !" @click="fetch"/> <NavLink description="Go for it !" name="event" :params="{ token: token }" />
</div> </div>
</div> </div>
@@ -88,7 +83,7 @@ function fetch(){
font-size: calc(0.4 * 75px); font-size: calc(0.4 * 75px);
} }
.input-field, .button { .input-field, .nav-link {
height: 75px; height: 75px;
min-height: 75px; min-height: 75px;
} }
@@ -112,7 +107,7 @@ function fetch(){
margin: 0 5px 5px 5px; margin: 0 5px 5px 5px;
} }
.button, .input-field .nav-link, .input-field
{ {
width: 50%; width: 50%;
} }
@@ -140,7 +135,7 @@ function fetch(){
margin: 0 5px 5px 5px; margin: 0 5px 5px 5px;
} }
.button, .input-field .nav-link, .input-field
{ {
width: 70%; width: 70%;
} }