diff --git a/backend/db/crud.py b/backend/db/crud.py index 2ba72873ea5b8afefb49e20733bd696bb81e348c..26771a1f5bc83a5c1329d7e58b6110a3e68ed35d 100644 --- a/backend/db/crud.py +++ b/backend/db/crud.py @@ -1,130 +1,277 @@ -""" -Module to interact with the database -""" -from datetime import date, datetime, time, timedelta -from sqlalchemy.orm import Session -from sqlalchemy.sql import func -import pytz - -from db import models, schemas - - -# Define CRUD operation to collect the statistics - -def get_waiting_time(place: str, db: Session): - """ Get the last estimated waiting time for the given place """ - db_record = db.query(models.Records).filter(models.Records.place == place).order_by(models.Records.date.desc()).first() - if db_record.waiting_time is not None: - return db_record.waiting_time - else: - raise Exception - - -def get_stats(place: str, weekday: int, min_time_hour: int, min_time_mn: int, max_time_hour: int, max_time_mn: int, interval: timedelta, db: Session): - """ Get the average waiting time for each interval between two time steps """ - - def shift_time(t: time, delta: timedelta): - return (datetime.combine(date(1, 1, 1), t) + delta).time() - - def avg_time_query(start_time, end_time): - records = db.query( - (func.round( - func.avg( - 3600 * func.extract('HOUR', models.Records.waiting_time) + - 60 * func.extract('MINUTE', models.Records.waiting_time) + - func.extract('SECOND', models.Records.waiting_time)) - )) / 60 - ).filter( - models.Records.place == place, - func.weekday(models.Records.date) == weekday, - (func.extract('HOUR', models.Records.date) > start_time.hour) | - ((func.extract('HOUR', models.Records.date) == start_time.hour) & - (func.extract('MINUTE', models.Records.date) >= start_time.minute)), - (func.extract('HOUR', models.Records.date) < end_time.hour) | - ((func.extract('HOUR', models.Records.date) == end_time.hour) & - (func.extract('MINUTE', models.Records.date) < end_time.minute)), - ).one() - if records[0]: - return int(records[0]) - return None - - def add_slot(slots_list, start_time, end_time): - average_waiting_time = avg_time_query(start_time, end_time) - if average_waiting_time: - name = f'{start_time.hour:02}h{start_time.minute:02}' - slots_list.append({'name': name, 'time': average_waiting_time}) - - min_time, max_time = time(min_time_hour, min_time_mn), time(max_time_hour, max_time_mn) - stats = [] - start_time, end_time = min_time, shift_time(min_time, interval) - while start_time < max_time: - add_slot(stats, start_time, end_time) - start_time, end_time = end_time, shift_time(end_time, interval) - - return stats - - -# Define CRUD operation for the comments - -def get_comments(place: str, page: int, db: Session): - """ Get the 10 last comments for the given place """ - if page == 0: - comments = db.query(models.Comments).order_by(models.Comments.published_at.desc(), models.Comments.id.desc()).all() - else: - comments = db.query( - models.Comments).filter( - models.Comments.place == place).order_by( - models.Comments.published_at.desc(), - models.Comments.id.desc()).slice( - (page - - 1) * - 10, - page * - 10).all() - return comments - - -def create_comment(place: str, new_comments: schemas.CommentBase, db: Session): - """ Add a new comment to the database """ - date = datetime.now(tz=pytz.timezone("Europe/Paris")) - db_comment = models.Comments(**new_comments.dict(), published_at=date, place=place) - db.add(db_comment) - db.commit() - db.refresh(db_comment) - return db_comment - - -def delete_comment(id: int, db: Session): - """ Delete the comment with the matching id """ - if id == 0: - db.query(models.Comments).delete() - else: - db.query(models.Comments).filter(models.Comments.id == id).delete() - db.commit() - - -# Define CRUD operation for the news - -def get_news(place: str, db: Session): - """ Get the news for the given place """ - news = db.query(models.News).filter(models.News.place == place).order_by(models.News.published_at.desc()).all() - return news - - -def create_news(new_news: schemas.NewsBase, db: Session): - """ Add a news to the database """ - date = datetime.now(tz=pytz.timezone("Europe/Paris")) - db_news = models.News(**new_news.dict(), published_at=date) - db.add(db_news) - db.commit() - db.refresh(db_news) - return db_news - - -def delete_news(id: int, db: Session): - """ Delete the news with the matching id """ - if id == 0: - db.query(models.News).delete() - else: - db.query(models.News).filter(models.News.id == id).delete() - db.commit() +""" +Module to interact with the database +""" +from datetime import date, datetime, time, timedelta +from sqlalchemy.orm import Session +from sqlalchemy.sql import func +import pytz + +from db import models, schemas + + +# Define CRUD operation to collect the statistics + +def get_waiting_time(place: str, db: Session): + """ Get the last estimated waiting time for the given place """ + current_date = datetime.now(tz=pytz.timezone("Europe/Paris")) + weekday, current_time = current_date.weekday(), current_date.time() + first_timeslot = get_timeslot(place, weekday, True, db) + if first_timeslot and current_time < first_timeslot[0]: + return first_timeslot[0].hour, first_timeslot[0].minute + elif first_timeslot and current_time <= first_timeslot[1]: + waiting_time = db.query( + models.Records.waiting_time + ).filter( + models.Records.place == place + ).order_by( + models.Records.date.desc() + ).first() + waiting_time_minutes = round(waiting_time[0].total_seconds() / 60) + return waiting_time_minutes, None + second_timeslot = get_timeslot(place, weekday, False, db) + if second_timeslot and current_time < second_timeslot[0]: + return second_timeslot[0].hour, second_timeslot[0].minute + elif second_timeslot and current_time <= second_timeslot[1]: + waiting_time = db.query( + models.Records.waiting_time + ).filter( + models.Records.place == place + ).order_by( + models.Records.date.desc() + ).first() + waiting_time_minutes = round(waiting_time[0].total_seconds() / 60) + return waiting_time_minutes, None + return None, None + + +def get_avg_graph_points(place: str, weekday: int, min_time: time, max_time: time, interval: timedelta, db: Session): + """ Get the average waiting time for each interval between two time steps """ + + def shift_time(t: time, delta: timedelta): + return (datetime.combine(date(1, 1, 1), t) + delta).time() + + def avg_time_query(start_time, end_time): + records = db.query( + (func.round( + func.avg( + 3600 * func.extract('HOUR', models.Records.waiting_time) + + 60 * func.extract('MINUTE', models.Records.waiting_time) + + func.extract('SECOND', models.Records.waiting_time)) + )) / 60 + ).filter( + models.Records.place == place, + func.weekday(models.Records.date) == weekday, + (func.extract('HOUR', models.Records.date) > start_time.hour) | + ((func.extract('HOUR', models.Records.date) == start_time.hour) & + (func.extract('MINUTE', models.Records.date) >= start_time.minute)), + (func.extract('HOUR', models.Records.date) < end_time.hour) | + ((func.extract('HOUR', models.Records.date) == end_time.hour) & + (func.extract('MINUTE', models.Records.date) < end_time.minute)), + ).one() + if records[0]: + return int(records[0]) + return None + + def add_slot(slots_list, start_time, end_time): + average_waiting_time = avg_time_query(start_time, end_time) + if average_waiting_time: + name = f'{start_time.hour:02}h{start_time.minute:02}' + slots_list.append({'name': name, 'time': average_waiting_time}) + + stats = [] + start_time, end_time = min_time, shift_time(min_time, interval) + while start_time < max_time: + add_slot(stats, start_time, end_time) + start_time, end_time = end_time, shift_time(end_time, interval) + + return stats + + +def get_avg_graph(place: str, db: Session): + """ Get the average waiting time for each interval between two time steps, + for the current or next available timeslot""" + current_date = datetime.now(tz=pytz.timezone("Europe/Paris")) + weekday, current_time = current_date.weekday(), current_date.time() + first_timeslot = get_timeslot(place, weekday, True, db) + if first_timeslot and current_time <= first_timeslot[1]: + return get_avg_graph_points(place, weekday, first_timeslot[0], first_timeslot[1], timedelta(minutes=5), db) + second_timeslot = get_timeslot(place, weekday, False, db) + if second_timeslot and current_time <= second_timeslot[1]: + return get_avg_graph_points(place, weekday, second_timeslot[0], second_timeslot[1], timedelta(minutes=5), db) + return None + + +def get_current_graph_points(place: str, current_date: date, min_time: time, max_time: time, interval: timedelta, db: Session): + """ Get the waiting time for each interval between two time steps for the current timeslot """ + + def shift_time(t: time, delta: timedelta): + return (datetime.combine(date(1, 1, 1), t) + delta).time() + + def avg_time_query(start_time, end_time): + records = db.query( + (func.round( + func.avg( + 3600 * func.extract('HOUR', models.Records.waiting_time) + + 60 * func.extract('MINUTE', models.Records.waiting_time) + + func.extract('SECOND', models.Records.waiting_time)) + )) / 60 + ).filter( + models.Records.place == place, + func.extract('YEAR', models.Records.date) == current_date.year, + func.extract('MONTH', models.Records.date) == current_date.month, + func.extract('DAY', models.Records.date) == current_date.day, + (func.extract('HOUR', models.Records.date) > start_time.hour) | + ((func.extract('HOUR', models.Records.date) == start_time.hour) & + (func.extract('MINUTE', models.Records.date) >= start_time.minute)), + (func.extract('HOUR', models.Records.date) < end_time.hour) | + ((func.extract('HOUR', models.Records.date) == end_time.hour) & + (func.extract('MINUTE', models.Records.date) < end_time.minute)), + ).one() + if records[0]: + return int(records[0]) + return None + + def add_slot(slots_list, start_time, end_time): + average_waiting_time = avg_time_query(start_time, end_time) + if average_waiting_time: + name = f'{start_time.hour:02}h{start_time.minute:02}' + slots_list.append({'name': name, 'time': average_waiting_time}) + + stats = [] + start_time, end_time = min_time, shift_time(min_time, interval) + while start_time < max_time: + add_slot(stats, start_time, end_time) + start_time, end_time = end_time, shift_time(end_time, interval) + + return stats + + +def get_current_graph(place: str, db: Session): + """ Get the waiting_time_graph for the current timeslot""" + current_date = datetime.now(tz=pytz.timezone("Europe/Paris")) + weekday, day, current_time = current_date.weekday(), current_date.date(), current_date.time() + first_timeslot = get_timeslot(place, weekday, True, db) + if first_timeslot and current_time <= first_timeslot[0]: + return None + elif first_timeslot and current_time <= first_timeslot[1]: + return get_current_graph_points(place, day, first_timeslot[0], current_time, timedelta(minutes=5), db) + second_timeslot = get_timeslot(place, weekday, False, db) + if second_timeslot and current_time <= second_timeslot[0]: + return None + elif second_timeslot and current_time <= second_timeslot[1]: + return get_current_graph_points(place, day, second_timeslot[0], current_time, timedelta(minutes=5), db) + return None + + +# Define CRUD operation for the comments + +def get_comments(place: str, page: int, db: Session): + """ Get the 10 last comments for the given place """ + if page == 0: + comments = db.query(models.Comments).order_by(models.Comments.published_at.desc(), models.Comments.id.desc()).all() + else: + comments = db.query( + models.Comments).filter( + models.Comments.place == place).order_by( + models.Comments.published_at.desc(), + models.Comments.id.desc()).slice( + (page - + 1) * + 10, + page * + 10).all() + return comments + + +def create_comment(place: str, new_comments: schemas.CommentBase, db: Session): + """ Add a new comment to the database """ + date = datetime.now(tz=pytz.timezone("Europe/Paris")) + db_comment = models.Comments(**new_comments.dict(), published_at=date, place=place) + db.add(db_comment) + db.commit() + db.refresh(db_comment) + return db_comment + + +def delete_comment(id: int, db: Session): + """ Delete the comment with the matching id """ + if id == 0: + db.query(models.Comments).delete() + else: + db.query(models.Comments).filter(models.Comments.id == id).delete() + db.commit() + + +# Define CRUD operation for the news + +def get_news(place: str, db: Session): + """ Get the news for the given place """ + news = db.query(models.News).filter(models.News.place == place).order_by(models.News.published_at.desc()).all() + return news + + +def create_news(new_news: schemas.NewsBase, db: Session): + """ Add a news to the database """ + date = datetime.now(tz=pytz.timezone("Europe/Paris")) + db_news = models.News(**new_news.dict(), published_at=date) + db.add(db_news) + db.commit() + db.refresh(db_news) + return db_news + + +def delete_news(id: int, db: Session): + """ Delete the news with the matching id """ + if id == 0: + db.query(models.News).delete() + else: + db.query(models.News).filter(models.News.id == id).delete() + db.commit() + + +# Define CRUD operation for the opening hours + +def get_opening_hours(place: str, db: Session): + """ Get the opening hours for the given place """ + opening_hours = db.query( + models.OpeningHours.day, + models.OpeningHours.timeslot, + models.OpeningHours.open_time, + models.OpeningHours.close_time, + ).filter( + models.OpeningHours.place == place + ).order_by( + models.OpeningHours.day, models.OpeningHours.timeslot.desc() + ).all() + return opening_hours + + +def get_timeslot(place: str, day: int, timeslot: bool, db: Session): + """ Get the opening hours for the given place and timeslot""" + opening_hours = db.query( + models.OpeningHours.open_time, + models.OpeningHours.close_time, + ).filter( + models.OpeningHours.place == place, + models.OpeningHours.day == day, + models.OpeningHours.timeslot == timeslot + ).first() + return opening_hours + + +def create_opening_hours(new_opening_hours: schemas.OpeningHoursBase, db: Session): + """ Add opening hours to the database """ + db_opening_hours = models.OpeningHours(**new_opening_hours.dict()) + db.add(db_opening_hours) + db.commit() + db.refresh(db_opening_hours) + return db_opening_hours + + +def delete_opening_hours(id: int, db: Session): + """ Delete the opening hours with the matching id """ + if id == 0: + db.query(models.OpeningHours).delete() + else: + db.query(models.OpeningHours).filter(models.OpeningHours.id == id).delete() + db.commit() diff --git a/backend/db/models.py b/backend/db/models.py index 1a39110dec496e6dddcf945637598659526d1627..aa055fed106ff64251cc481f41fd4372fb54fd70 100644 --- a/backend/db/models.py +++ b/backend/db/models.py @@ -1,39 +1,51 @@ -""" -Models of the database for magasin app -""" -from sqlalchemy import Column, Integer, DateTime, Float, Interval, String, Text - -from db.database import Base - - -class Records(Base): - """Records sql table model""" - __tablename__ = "records" - - id = Column(Integer, primary_key=True, index=True) - place = Column(String(10)) - date = Column(DateTime) - density = Column(Float) - waiting_time = Column(Interval) - - -class Comments(Base): - """Comments sql table model""" - __tablename__ = "comments" - - id = Column(Integer, primary_key=True, index=True) - content = Column(Text) - published_at = Column(DateTime) - place = Column(String(10)) - - -class News(Base): - """News sql table model""" - __tablename__ = "news" - - id = Column(Integer, primary_key=True, index=True) - title = Column(String(50)) - content = Column(Text) - published_at = Column(DateTime) - end_date = Column(DateTime) - place = Column(String(10)) +""" +Models of the database for magasin app +""" +from sqlalchemy import Column, Integer, DateTime, Float, Interval, String, Text, Boolean, Time + +from db.database import Base + + +class Records(Base): + """Records sql table model""" + __tablename__ = "records" + + id = Column(Integer, primary_key=True, index=True) + place = Column(String(10)) + date = Column(DateTime) + density = Column(Float) + waiting_time = Column(Interval) + + +class Comments(Base): + """Comments sql table model""" + __tablename__ = "comments" + + id = Column(Integer, primary_key=True, index=True) + content = Column(Text) + published_at = Column(DateTime) + place = Column(String(10)) + + +class News(Base): + """News sql table model""" + __tablename__ = "news" + + id = Column(Integer, primary_key=True, index=True) + title = Column(String(50)) + content = Column(Text) + published_at = Column(DateTime) + end_date = Column(DateTime) + place = Column(String(10)) + + +class OpeningHours(Base): + """OpeningHours sql table model""" + __tablename__ = "opening_hours" + + id = Column(Integer, primary_key=True, index=True) + place = Column(String(10)) + day = Column(Integer) + timeslot = Column(Boolean) + open_time = Column(Time) + close_time = Column(Time) diff --git a/backend/db/schemas.py b/backend/db/schemas.py index 8811cdc25234b6018982fe9daecb33f8d1e6366b..e6107329523baece2bc414e6a1c9bbace35912f2 100644 --- a/backend/db/schemas.py +++ b/backend/db/schemas.py @@ -1,54 +1,71 @@ -""" -Pydantic schemas for the magasin app -""" -from typing import Optional -from datetime import datetime, timedelta -from pydantic import BaseModel, Field - - -class RecordBase(BaseModel): - """Records base schema""" - place: str = Field(..., title="Name of the RU corresponding the given record") - date: datetime = Field(..., title="Date of the record") - density: float = Field(..., title="Estimated density of people") - waiting_time: Optional[timedelta] = Field(title="Estimated waiting time for people coming at this date") - - -class Record(RecordBase): - """Database records base schema""" - id: int - - class Config: - orm_mode = True - - -class CommentBase(BaseModel): - """Comments base schema""" - content: str = Field(..., title="Content of the comment posted") - - -class Comment(CommentBase): - """Database comments base schema""" - id: int - published_at: datetime = Field(..., title="Publication date of the comment") - place: str = Field(..., title="Name of the RU corresponding the comment") - - class Config: - orm_mode = True - - -class NewsBase(BaseModel): - """News sql table model""" - title: str = Field(..., title="Title of the news") - content: str = Field(..., title="Content of the news") - end_date: datetime = Field(..., title="End date to display the news") - place: str = Field(..., title="Name of the RU corresponding the news") - - -class News(NewsBase): - """Database news base schema""" - id: int - published_at: datetime = Field(..., title="Publication date of the news") - - class Config: - orm_mode = True +""" +Pydantic schemas for the magasin app +""" +from typing import Optional +from datetime import datetime, timedelta, time +from pydantic import BaseModel, Field + + +class RecordBase(BaseModel): + """Records base schema""" + place: str = Field(..., title="Name of the RU corresponding the given record") + date: datetime = Field(..., title="Date of the record") + density: float = Field(..., title="Estimated density of people") + waiting_time: Optional[timedelta] = Field(title="Estimated waiting time for people coming at this date") + + +class Record(RecordBase): + """Database records base schema""" + id: int + + class Config: + orm_mode = True + + +class CommentBase(BaseModel): + """Comments base schema""" + content: str = Field(..., title="Content of the comment posted") + + +class Comment(CommentBase): + """Database comments base schema""" + id: int + published_at: datetime = Field(..., title="Publication date of the comment") + place: str = Field(..., title="Name of the RU corresponding the comment") + + class Config: + orm_mode = True + + +class NewsBase(BaseModel): + """News sql table model""" + title: str = Field(..., title="Title of the news") + content: str = Field(..., title="Content of the news") + end_date: datetime = Field(..., title="End date to display the news") + place: str = Field(..., title="Name of the RU corresponding the news") + + +class News(NewsBase): + """Database news base schema""" + id: int + published_at: datetime = Field(..., title="Publication date of the news") + + class Config: + orm_mode = True + + +class OpeningHoursBase(BaseModel): + """Database opening_hours base schema""" + place: str = Field(..., title="Name of the RU corresponding the given record") + day: int = Field(..., title="Day of the week") + timeslot: bool = Field(..., title="Service slot (True for midday, False for evening)") + open_time: time = Field(..., title="Opening time") + close_time: time = Field(..., title="Closing time") + + +class OpeningHours(OpeningHoursBase): + """Database opening_hours base schema""" + id: int + + class Config: + orm_mode = True diff --git a/backend/routers/stats.py b/backend/routers/stats.py index 092a062ed141b9841051e9d7d5b28e81e96a375a..514e1e29c056d923ca0278e44bba4d9d2a7e8ce5 100644 --- a/backend/routers/stats.py +++ b/backend/routers/stats.py @@ -1,21 +1,42 @@ from fastapi import APIRouter, Depends from sqlalchemy.orm import Session -from datetime import timedelta -from typing import List -from db import crud +from db import schemas, crud from db.database import get_db router = APIRouter(prefix="/api", tags=["stats"]) -@router.get('/{place}/waiting_time', response_model=timedelta) +@router.get('/{place}/waiting_time', response_model=tuple) async def waiting_time(place: str, db: Session = Depends(get_db)): return crud.get_waiting_time(place, db) -@router.get('/{place}/stats/{day}/{min_time_hour}/{min_time_mn}/{max_time_hour}/{max_time_mn}/{interval}', response_model=list) -async def stats(place: str, day: int, min_time_hour: int, min_time_mn: int, - max_time_hour: int, max_time_mn: int, interval: timedelta, db: Session = Depends(get_db)): - return crud.get_stats(place, day, min_time_hour, min_time_mn, max_time_hour, max_time_mn, interval, db) +@router.get('/{place}/stats/avg_graph', response_model=list) +async def stats(place: str, db: Session = Depends(get_db)): + return crud.get_avg_graph(place, db) + + +@router.get('/{place}/stats/current_graph', response_model=list) +async def stats(place: str, db: Session = Depends(get_db)): + return crud.get_current_graph(place, db) + +@router.get('/{place}/opening_hours', response_model=List[schemas.OpeningHours]) +async def get_opening_hours(place: str, page: int = 1, db: Session = Depends(get_db)): + return crud.get_opening_hours(place, page, db) + + +@router.get('/{place}/opening_hours/{day}/{timeslot}', response_model=List[schemas.OpeningHours]) +async def get_timeslot(place: str, day: int, timeslot: bool, db: Session = Depends(get_db)): + return crud.get_timeslot(place, day, timeslot, db) + + +@router.post('/opening_hours', response_model=schemas.OpeningHours) +async def create_opening_hours(opening_hours: schemas.OpeningHoursBase, db: Session = Depends(get_db)): + return crud.create_opening_hours(opening_hours, db) + + +@router.delete('/opening_hours/{id}', response_model=None) +async def delete_opening_hours(id: int, db: Session = Depends(get_db)): + return crud.delete_opening_hours(id, db) diff --git a/frontend/src/components/Graph.js b/frontend/src/components/Graph.js index 5b1936716c47cf43409cf48943f655a982e0063b..369edc5af4754bfc49f21550edd37c216ae9e8cb 100644 --- a/frontend/src/components/Graph.js +++ b/frontend/src/components/Graph.js @@ -11,33 +11,19 @@ import { } from "recharts"; import "../styles/Graph.css"; -export default function DailyGraph({ place }) { - const [day, min_time_hour, min_time_mn, max_time_hour, max_time_mn, interval] = [ - 3, 12, 0, 12, 40, 300, - ]; - const url = - process.env.REACT_APP_BASE_URL_BACK + - "/" + - place + - "/stats/" + - day + - "/" + - min_time_hour + - "/" + - min_time_mn + - "/" + - max_time_hour + - "/" + - max_time_mn + - "/" + - interval; - - const [data, setData] = React.useState([]); +export default function Graph({ place, type }) { + const [data, setData] = React.useState(null); React.useEffect(() => { - axios.get(url).then((response) => { - setData(response.data); - }); - }, [url]); + axios + .get( + `${process.env.REACT_APP_BASE_URL_BACK}/${encodeURIComponent( + place, + )}/stats/${encodeURIComponent(type)}_graph`, + ) + .then((response) => { + setData(response.data); + }); + }, []); if (!data) return null; const CustomTooltip = ({ active, payload }) => { diff --git a/frontend/src/components/WaitingTime.js b/frontend/src/components/WaitingTime.js index 9f28566219015d2ae7ede5158c976ae0f3ea61de..f479f89067d61a755029736b5bdd4950c1e432c6 100644 --- a/frontend/src/components/WaitingTime.js +++ b/frontend/src/components/WaitingTime.js @@ -4,31 +4,36 @@ import axios from "axios"; import "../styles/WaitingTime.css"; export default function WaitingTime({ place }) { - const [post, setPost] = useState(null); + const [post, setPost] = useState([null, null]); React.useEffect(() => { axios .get(`${process.env.REACT_APP_BASE_URL_BACK}/${encodeURIComponent(place)}/waiting_time`) - .then((response) => { - if (response.data < 60) { - setPost(0); - } else { - setPost(Math.round(response.data / 60)); - } + .then((res) => { + setPost(res.data); }); }, []); return ( <div id="waiting-time-parent"> - {post ? ( + {post[1] ? ( <div id="waiting-time-display"> - <div>Temps d'attente estimé:</div> + Le RU ouvre aujourd'hui à : <div className="waiting-time-minutes"> - <b id="waiting-time-number">{post}</b> minutes + <b id="waiting-time-number"> + {String(post[0]).padStart(2, "0")}h{String(post[1]).padStart(2, "0")} + </b> + </div> + </div> + ) : post[0] ? ( + <div id="waiting-time-display"> + Le temps d'attente est estimé à : + <div className="waiting-time-minutes"> + <b id="waiting-time-number">{post[0]}</b> minutes </div> </div> ) : ( - <div className="waiting-time-minutes">Pas de données...</div> + <div className="waiting-time-minutes">Le RU est fermé pour aujourd'hui.</div> )} </div> ); diff --git a/frontend/src/components/index.js b/frontend/src/components/index.js index 76758d28d9f9c9649ce6125ea0b07e3862024fb3..2ed4f885eb4c32b29c408a9496126867c343bf1d 100644 --- a/frontend/src/components/index.js +++ b/frontend/src/components/index.js @@ -2,5 +2,5 @@ export { default as Header } from "./Header"; export { default as Footer } from "./Footer"; export { default as Timetable } from "./Timetable"; export { default as WaitingTime } from "./WaitingTime"; -export { default as DailyGraph } from "./Graph"; +export { default as Graph } from "./Graph"; export { default as Comments } from "./Comments"; diff --git a/frontend/src/index.js b/frontend/src/index.js index fb6d33928eb6f739beb1cf45a7cb327d5a5c29c3..67409df70b96bceba0b5faf86827da9550bd40e5 100644 --- a/frontend/src/index.js +++ b/frontend/src/index.js @@ -25,13 +25,18 @@ export default function App() { console.log(e); setLoading(false); }); - setRestaurantsList([ - { name: "RU Eiffel", status: true, waiting_time: 17, timetable: "11h30-14h / 18h30-21h" }, - { name: "RU Bréguet", status: true, waiting_time: 25, timetable: "11h30-14h" }, - { name: "Lieu de vie", status: false, waiting_time: null, timetable: "11h30-14h / 18h30-21h" }, - { name: "Caféteria Eiffel", status: false, waiting_time: null, timetable: "18h30-21h" }, - { name: "Caféteria Bréguet", status: true, waiting_time: null, timetable: "18h30-21h" }, - ]); + setRestaurantsList([ + { name: "RU Eiffel", status: true, waiting_time: 17, timetable: "11h30-14h / 18h30-21h" }, + { name: "RU Bréguet", status: true, waiting_time: 25, timetable: "11h30-14h" }, + { + name: "Lieu de vie", + status: false, + waiting_time: null, + timetable: "11h30-14h / 18h30-21h", + }, + { name: "Caféteria Eiffel", status: false, waiting_time: null, timetable: "18h30-21h" }, + { name: "Caféteria Bréguet", status: true, waiting_time: null, timetable: "18h30-21h" }, + ]); }, []); useEffect(() => { diff --git a/frontend/src/views/Restaurant.js b/frontend/src/views/Restaurant.js index ab762aa581986bc85a13f6b86b4678af365249b9..827eaf7e3aba8e3a13b34a54d620c6f48367bd12 100644 --- a/frontend/src/views/Restaurant.js +++ b/frontend/src/views/Restaurant.js @@ -1,6 +1,6 @@ import React from "react"; -import { DailyGraph, WaitingTime, Comments } from "../components"; +import { Graph, WaitingTime, Comments } from "../components"; import "../styles/restaurant.css"; @@ -12,9 +12,10 @@ export default function RestaurantPage({ selection }) { <Comments place={selection.name} infos /> <div className="restaurant-container" id="restaurant-main-page"> <WaitingTime place={selection.name} /> - <DailyGraph place={selection.name} /> + <Graph place={selection.name} type="current" /> </div> <Comments place={selection.name} /> + {/*<Graph place={selection.name} type="avg" />*/} </div> )} </>