holy ravioli
@@ -5,7 +5,4 @@ import java.util.Set;
|
||||
public class AttendeeDTO {
|
||||
|
||||
public String name;
|
||||
|
||||
public Set<EventDateDTO> dates;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package be.naaturel.letsmeet.dto.httpRequest;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class EventDTO {
|
||||
|
||||
public String name;
|
||||
public Set<AttendeeDTO> attendees;
|
||||
public Map<String, Set<AttendeeDTO>> dates;
|
||||
|
||||
}
|
||||
|
||||
@@ -22,13 +22,12 @@ public class AttendeeDTOMapper implements Mapper<Attendee, AttendeeDTO> {
|
||||
public AttendeeDTO toEntity(Attendee d) {
|
||||
AttendeeDTO dto = new AttendeeDTO();
|
||||
dto.name = d.getName();
|
||||
dto.dates = dateMapper.toEntities(d.getDates(), HashSet::new);
|
||||
return dto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Attendee toModel(AttendeeDTO d) {
|
||||
return new Attendee(d.name, dateMapper.toModels(d.dates, HashSet::new));
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,30 +1,58 @@
|
||||
package be.naaturel.letsmeet.mappers.requests;
|
||||
|
||||
import be.naaturel.letsmeet.core.models.EventDate;
|
||||
import be.naaturel.letsmeet.dto.httpRequest.EventDTO;
|
||||
import be.naaturel.letsmeet.dto.httpRequest.AttendeeDTO;
|
||||
import be.naaturel.letsmeet.dto.httpRequest.EventDateDTO;
|
||||
import be.naaturel.letsmeet.mappers.Mapper;
|
||||
import be.naaturel.letsmeet.core.models.Event;
|
||||
import be.naaturel.letsmeet.core.models.Attendee;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class EventDTOMapper implements Mapper<Event, EventDTO> {
|
||||
|
||||
private final Mapper<Attendee, AttendeeDTO> attendeeMapper = new AttendeeDTOMapper();
|
||||
private final Mapper<EventDate, EventDateDTO> dateMapper = new EventDateDTOMapper();
|
||||
|
||||
@Override
|
||||
public EventDTO toEntity(Event event) {
|
||||
EventDTO eventDTO = new EventDTO();
|
||||
eventDTO.name = event.getName();
|
||||
eventDTO.attendees = attendeeMapper.toEntities(event.getAttendees(), HashSet::new);
|
||||
//eventDTO.dates = attendeeMapper.toEntities(event.getAttendees(), HashSet::new);
|
||||
|
||||
//TODO : MUST BE CLEANED
|
||||
eventDTO.dates = new HashMap<>();
|
||||
event.getAttendees().forEach(a -> {
|
||||
a.getDates().forEach(d -> {
|
||||
EventDateDTO dtoD = dateMapper.toEntity(d);
|
||||
AttendeeDTO dtoA = attendeeMapper.toEntity(a);
|
||||
String key = String.valueOf(d.getTimeStamp());
|
||||
if(eventDTO.dates.containsKey(key)){
|
||||
eventDTO.dates.get(key).add(dtoA);
|
||||
} else {
|
||||
Set<AttendeeDTO> s = new HashSet<>();
|
||||
s.add(dtoA);
|
||||
eventDTO.dates.put(key, s);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return eventDTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Event toModel(EventDTO dto) {
|
||||
return new Event(dto.name, attendeeMapper.toModels(dto.attendees, HashSet::new));
|
||||
//return new Event(dto.name, attendeeMapper.toModels(dto.dates, HashSet::new));
|
||||
Set<Attendee> set = new HashSet<>();
|
||||
for (String key : dto.dates.keySet()) {
|
||||
set.addAll(attendeeMapper.toModels(dto.dates.get(key), HashSet::new));
|
||||
}
|
||||
return new Event(dto.name, set);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package be.naaturel.letsmeet.mappers;
|
||||
|
||||
import be.naaturel.letsmeet.dto.database.EventDateEntity;
|
||||
import be.naaturel.letsmeet.mappers.Mapper;
|
||||
import be.naaturel.letsmeet.mappers.database.EventDateMapper;
|
||||
import be.naaturel.letsmeet.core.models.EventDate;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package be.naaturel.letsmeet.mappers.dto;
|
||||
|
||||
import be.naaturel.letsmeet.core.models.Event;
|
||||
import be.naaturel.letsmeet.dto.httpRequest.EventDTO;
|
||||
import be.naaturel.letsmeet.mappers.Mapper;
|
||||
import be.naaturel.letsmeet.mappers.requests.EventDTOMapper;
|
||||
import be.naaturel.letsmeet.mock.dto.MockEventDTO;
|
||||
import be.naaturel.letsmeet.mock.models.MockEventModel;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class EventDTOMapperTest {
|
||||
|
||||
private static MockEventDTO mockDto;
|
||||
private static MockEventModel mockModel;
|
||||
private static Mapper<Event, EventDTO> mapper;
|
||||
|
||||
@BeforeAll
|
||||
static void setup(){
|
||||
mockDto = new MockEventDTO();
|
||||
mockModel = new MockEventModel();
|
||||
mapper = new EventDTOMapper();
|
||||
}
|
||||
|
||||
@Test
|
||||
void single_dto_to_model_test(){
|
||||
Event res = mapper.toModel(mockDto);
|
||||
assertEquals(res.getName(), mockDto.name);
|
||||
}
|
||||
|
||||
@Test
|
||||
void single_model_to_dto_test(){
|
||||
EventDTO res = mapper.toEntity(mockModel);
|
||||
assertEquals(res.name, mockModel.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void multiple_dto_to_models_test(){
|
||||
List<Event> res = mapper.toModels(Set.of(mockDto), ArrayList::new);
|
||||
assertEquals(res.size(), 1);
|
||||
assertEquals(res.getFirst().getName(), mockDto.name);
|
||||
}
|
||||
|
||||
@Test
|
||||
void mulitple_models_to_dto_test(){
|
||||
List<EventDTO> res = mapper.toEntities(Set.of(mockModel), ArrayList::new);
|
||||
assertEquals(res.size(), 1);
|
||||
assertEquals(res.getFirst().name, mockModel.getName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package be.naaturel.letsmeet.mock.dto;
|
||||
|
||||
import be.naaturel.letsmeet.dto.httpRequest.AttendeeDTO;
|
||||
|
||||
public class MockAttendeeDTO extends AttendeeDTO {
|
||||
|
||||
public MockAttendeeDTO(){
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package be.naaturel.letsmeet.mock.dto;
|
||||
|
||||
import be.naaturel.letsmeet.core.models.Attendee;
|
||||
import be.naaturel.letsmeet.dto.httpRequest.AttendeeDTO;
|
||||
import be.naaturel.letsmeet.dto.httpRequest.EventDTO;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class MockEventDTO extends EventDTO {
|
||||
|
||||
public MockEventDTO() {
|
||||
this.name = "Mocked event";
|
||||
this.dates = new HashMap<>();
|
||||
populate(0, new HashSet<>());
|
||||
populate(1, new HashSet<>());
|
||||
populate(2, new HashSet<>());
|
||||
}
|
||||
|
||||
private void populate(long timestamp, Set<AttendeeDTO> attendees){
|
||||
this.dates.put(String.valueOf(timestamp), attendees);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package be.naaturel.letsmeet.mock.jpa;
|
||||
|
||||
import be.naaturel.letsmeet.dto.database.EventEntity;
|
||||
|
||||
public class MockEventEntity extends EventEntity {
|
||||
|
||||
public MockEventEntity(){
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package be.naaturel.letsmeet.mock.models;
|
||||
|
||||
import be.naaturel.letsmeet.core.models.Attendee;
|
||||
import be.naaturel.letsmeet.core.models.Event;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class MockEventModel extends Event {
|
||||
public MockEventModel() {
|
||||
super("Mock event model", new HashSet<>());
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 251 B After Width: | Height: | Size: 251 B |
|
Before Width: | Height: | Size: 254 B After Width: | Height: | Size: 254 B |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import ArrowRight from "@/assets/arrow-right.svg"
|
||||
import ArrowLeft from "@/assets/arrow-left.svg";
|
||||
import ArrowRight from "@/assets/svg/arrow-right.svg"
|
||||
import ArrowLeft from "@/assets/svg/arrow-left.svg";
|
||||
import {ref, onMounted, watch} from "vue";
|
||||
import { datePickerStore } from "@/stores/CalendarStore.ts";
|
||||
import { Calendar } from "@/models/Calendar.ts";
|
||||
|
||||
@@ -10,7 +10,6 @@ const props = defineProps({
|
||||
}
|
||||
});
|
||||
|
||||
// Method to handle the update
|
||||
const updateValue = (event : any) => {
|
||||
emit('update:value', event.target.value);
|
||||
};
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import type {Attendee} from "@/models/Attendee.ts";
|
||||
import type {TimeStamp} from "@/models/TimeStamp.ts";
|
||||
import type {EventDate} from "@/models/EventDate.ts";
|
||||
import type {AttendeeDto} from "@/dto/AttendeeDto.ts";
|
||||
|
||||
export class EventDto {
|
||||
|
||||
public name: string;
|
||||
public token: string;
|
||||
public attendees: AttendeeDto[];
|
||||
public dates : Map<EventDate, Attendee[]>
|
||||
|
||||
public constructor(name: string, token: string, attendees: AttendeeDto[]) {
|
||||
public constructor(name: string, token: string, dates: Map<EventDate, Attendee[]>) {
|
||||
this.name = name;
|
||||
this.token = token;
|
||||
this.attendees = attendees;
|
||||
this.dates = dates;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,25 +1,18 @@
|
||||
import type {TimeStamp, TimeStampState} from "@/models/TimeStamp.ts";
|
||||
import type {EventDate, EventDateState} from "@/models/EventDate.ts";
|
||||
|
||||
export class Attendee {
|
||||
|
||||
private name: string;
|
||||
private dates: TimeStamp[];
|
||||
|
||||
public constructor(name: string, dates: TimeStamp[]) {
|
||||
public constructor(name: string) {
|
||||
this.name = name;
|
||||
this.dates = dates;
|
||||
}
|
||||
|
||||
public getName() : string {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public getDates() : TimeStamp[] {
|
||||
return this.dates;
|
||||
}
|
||||
}
|
||||
|
||||
export interface AttendeeState {
|
||||
name : string
|
||||
dates : TimeStampState[]
|
||||
}
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
import type {Attendee, AttendeeState} from "@/models/Attendee.ts";
|
||||
import type {TimeStamp} from "@/models/TimeStamp.ts";
|
||||
import type {EventDate, EventDateState} from "@/models/EventDate.ts";
|
||||
|
||||
export class Event {
|
||||
|
||||
private name: string;
|
||||
private token: string;
|
||||
private attendees: Attendee[];
|
||||
private groups : Map<number, string[]>;
|
||||
private dates: Map<number, Attendee[]>;
|
||||
|
||||
public constructor(name: string, token: string, attendees: Attendee[]) {
|
||||
public constructor(name: string, token: string, dates : Map<number, Attendee[]>) {
|
||||
this.name = name;
|
||||
this.token = token;
|
||||
this.attendees = attendees;
|
||||
this.groups = this.byDates();
|
||||
this.dates = dates;
|
||||
}
|
||||
|
||||
public getName() : string {
|
||||
@@ -23,34 +21,14 @@ export class Event {
|
||||
return this.token;
|
||||
}
|
||||
|
||||
public getAttendees() : Attendee[] {
|
||||
return this.attendees;
|
||||
public getDates() : Map<number, Attendee[]> {
|
||||
return this.dates;
|
||||
}
|
||||
|
||||
public getGroups() : Map<number, string[]> { return this.groups; }
|
||||
|
||||
private byDates() : Map<number, string[]> {
|
||||
let res : Map<number, string[]> = new Map();
|
||||
this.attendees.forEach((attendee: Attendee) => {
|
||||
attendee.getDates().forEach((timeStamp: TimeStamp) => {
|
||||
let value : number = timeStamp.getValue();
|
||||
if(res.has(value)) {
|
||||
res.get(value)?.push(attendee.getName());
|
||||
} else {
|
||||
res.set(value, []);
|
||||
res.get(value)?.push(attendee.getName());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export interface EventState {
|
||||
name : String
|
||||
token : String
|
||||
attendees: AttendeeState[];
|
||||
name : string
|
||||
token : string
|
||||
dates: Map<EventDateState, AttendeeState[]>;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export class TimeStamp {
|
||||
export class EventDate {
|
||||
|
||||
private readonly value : number;
|
||||
|
||||
@@ -9,8 +9,13 @@ export class TimeStamp {
|
||||
public getValue() : number{
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public toString() {
|
||||
this.value.toString();
|
||||
}
|
||||
|
||||
export interface TimeStampState {
|
||||
}
|
||||
|
||||
export interface EventDateState {
|
||||
value : number;
|
||||
}
|
||||
@@ -23,8 +23,22 @@ export class EventRequests {
|
||||
|
||||
let url = this.formatUrl([this.baseUrl, this.endpoints.EVENTS, token]);
|
||||
return fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
return new EventDto(data.name, data.token, data.dates)
|
||||
})
|
||||
.catch(error => console.error(error));
|
||||
}
|
||||
|
||||
public async createEvent(event : EventDto){
|
||||
let url = this.formatUrl([this.baseUrl, this.endpoints.CREATE]);
|
||||
return fetch(url, {
|
||||
method: "POST",
|
||||
body : JSON.stringify(event)
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => new EventDto(data.name, data.token, data.attendees))
|
||||
.catch(error => console.error(error));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import {TimeStamp} from "@/models/TimeStamp.ts";
|
||||
import {EventDate} from "@/models/EventDate.ts";
|
||||
|
||||
export const datePickerStore = defineStore('datePicker', {
|
||||
state: () => {
|
||||
return { dates: [] as TimeStamp[] }
|
||||
return { dates: [] as EventDate[] }
|
||||
},
|
||||
getters: {
|
||||
value: (state) : TimeStamp[] => state.dates as TimeStamp[],
|
||||
value: (state) : EventDate[] => state.dates as EventDate[],
|
||||
},
|
||||
actions: {
|
||||
getValue(){
|
||||
return this.dates;
|
||||
},
|
||||
update(dates : Date[]) : void {
|
||||
this.dates = dates.map(date => new TimeStamp(date));
|
||||
this.dates = dates.map(date => new EventDate(date));
|
||||
},
|
||||
clear() : void {
|
||||
this.dates = [] as TimeStamp[];
|
||||
this.dates = [] as EventDate[];
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,50 +1,69 @@
|
||||
import {defineStore} from 'pinia'
|
||||
import {EventRequests} from "@/requests/EventRequests.ts";
|
||||
import type {EventDto} from "@/dto/EventDto.ts";
|
||||
import {EventDto} from "@/dto/EventDto.ts";
|
||||
import {Event, type EventState} from "@/models/Event.ts";
|
||||
import type {AttendeeDto} from "@/dto/AttendeeDto.ts";
|
||||
import {Attendee, type AttendeeState} from "@/models/Attendee.ts";
|
||||
import {TimeStamp, type TimeStampState} from "@/models/TimeStamp.ts";
|
||||
import type {TimeStampDto} from "@/dto/TimeStampDto.ts";
|
||||
import {EventDate, type EventDateState} from "@/models/EventDate.ts";
|
||||
|
||||
const requests = new EventRequests();
|
||||
|
||||
function mapToDto() : EventDto{
|
||||
return new EventDto("", "", new Map());
|
||||
}
|
||||
|
||||
function mapToModel(state : EventState) : Event{
|
||||
let dates: Map<number, Attendee[]> = new Map();
|
||||
for (let [date, attendeesState] of state.dates.entries()) {
|
||||
let attendees : Attendee[] = attendeesState.map(attendee => {
|
||||
return new Attendee(attendee.name);
|
||||
})
|
||||
dates.set(date.value, attendees);
|
||||
}
|
||||
return new Event(state.name, state.token, dates);
|
||||
}
|
||||
|
||||
function mapToState(dto : EventDto) : EventState {
|
||||
let event : EventState = {name : "", token : "", dates: new Map<EventDateState, AttendeeState[]>()};
|
||||
event.name = dto.name;
|
||||
event.token = dto.token;
|
||||
Object.entries(dto.dates).forEach(([key, attendees]) => {
|
||||
let dateState : EventDateState = { value: Number(key) };
|
||||
event.dates.set(dateState, attendees);
|
||||
});
|
||||
return event;
|
||||
}
|
||||
|
||||
export const eventStore = defineStore('eventStore', {
|
||||
state: (): {event : EventState} => {
|
||||
return {
|
||||
event : {
|
||||
name: "",
|
||||
token: "",
|
||||
attendees: [] as AttendeeState[]
|
||||
dates: new Map<EventDateState, AttendeeState[]>()
|
||||
}};
|
||||
},
|
||||
getters : {
|
||||
getEvent(state) : Event {
|
||||
let attendees : Attendee[] = state.event.attendees.map((a : AttendeeState) => {
|
||||
let dates: TimeStamp[] = a.dates.map(d => new TimeStamp(new Date(d.value)))
|
||||
return new Attendee(a.name, dates);
|
||||
});
|
||||
return new Event(state.event.name.toString(), "", attendees);
|
||||
return mapToModel(state.event);
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setName(name : string){
|
||||
this.event.name = name;
|
||||
},
|
||||
async fetch(token: string): Promise<void> {
|
||||
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.attendees = data.attendees.map((a: AttendeeDto) => ({
|
||||
name: a.name,
|
||||
dates: a.dates.map((date: TimeStampDto) => ({
|
||||
value: date.timestamp
|
||||
})) as TimeStampState[]
|
||||
}));
|
||||
this.event = mapToState(data);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
throw new Error("Unable to fetch.");
|
||||
throw new Error("Unable to fetch. " + error);
|
||||
}
|
||||
},
|
||||
async create(){
|
||||
let event = mapToDto();
|
||||
await requests.createEvent(event)
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import type {TimeStamp} from "@/models/TimeStamp.ts";
|
||||
import type {EventDate} from "@/models/EventDate.ts";
|
||||
import type {Attendee} from "@/models/Attendee.ts";
|
||||
|
||||
/**
|
||||
* I hate JavaScript and TypeScript with every single inch of my body
|
||||
*/
|
||||
export class CustomMap extends Map<TimeStamp, Attendee> {
|
||||
has(obj: TimeStamp): boolean {
|
||||
export class CustomMap extends Map<EventDate, Attendee> {
|
||||
has(obj: EventDate): boolean {
|
||||
obj.getValue()
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,10 @@ import Calendar from "@/components/Calendar.vue";
|
||||
import TextBlock from "@/components/TextBlock.vue";
|
||||
import NavLink from "@/components/NavLink.vue";
|
||||
import InputField from "@/components/InputField.vue";
|
||||
import {eventStore} from "@/stores/EventStore.ts";
|
||||
|
||||
const store = eventStore();
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -13,7 +17,7 @@ import InputField from "@/components/InputField.vue";
|
||||
<h1>Create an <span class="colored-text">event</span></h1>
|
||||
</TextBlock>
|
||||
<div class="event-form">
|
||||
<InputField placeholder="Event name"/>
|
||||
<InputField placeholder="Event name" @update:value="(newValue) => { store.setName(newValue) }"/>
|
||||
<Calendar class="calendar"/>
|
||||
<NavLink name="Create" description="Create" class="create-button"></NavLink>
|
||||
</div>
|
||||
|
||||
@@ -43,12 +43,11 @@ function formatDate(timestamp : number) : String{
|
||||
|
||||
<div v-else>
|
||||
Name : {{ event.getName() }} <br>
|
||||
<div v-for="(timestamp) in event.getGroups().keys()" >
|
||||
{{ formatDate(timestamp) }}
|
||||
<div v-for="(attendee) in event.getGroups().get(timestamp)">
|
||||
{{ attendee }}
|
||||
<div v-for="(date) in event.getDates().keys()">
|
||||
{{formatDate(date)}}
|
||||
<div v-for="(attendee) in event.getDates().get(date)">
|
||||
{{attendee.getName()}}
|
||||
</div>
|
||||
=================
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import TextBlock from "@/components/TextBlock.vue";
|
||||
<h1>Welcome !</h1>
|
||||
<p>
|
||||
This website is currently under <span class="colored-text">development</span> and might look ugly as fuck
|
||||
bla bla bla I'm just writting things nobody will read to fill the space and see how it looks.
|
||||
bla bla bla I'm just writing things nobody will read to fill the space and see how it looks.
|
||||
</p>
|
||||
<p>
|
||||
Yes I know i could have use
|
||||
|
||||