diff --git a/app/config.py.example b/app/config.py.example index e7d927ca..587753ff 100644 --- a/app/config.py.example +++ b/app/config.py.example @@ -18,6 +18,7 @@ class Settings(BaseSettings): # GENERAL DOMAIN = 'Our-Domain' + # DATABASE DEVELOPMENT_DATABASE_STRING = "sqlite:///./dev.db" # Set the following True if working on PSQL environment or set False otherwise diff --git a/app/internal/timer.py b/app/internal/timer.py new file mode 100644 index 00000000..9cf39314 --- /dev/null +++ b/app/internal/timer.py @@ -0,0 +1,26 @@ +from datetime import datetime +from typing import Dict, List, Optional + +from sqlalchemy.orm import Session +from app.database.models import Event, UserEvent + + +def get_next_user_event(session: Session, user_id: int) -> List[Event]: + next_user_event = ( + session.query(Event).join(UserEvent) + .filter(UserEvent.user_id == user_id) + .filter(Event.start >= datetime.now()) + .order_by(Event.start) + ) + return next_user_event[0] + + +def get_next_user_event_start_time( + session: Session, + user_id: int +) -> Dict[str, Optional[str]]: + next_event = get_next_user_event(session, user_id) + timer_to_next_event = None + if next_event is not None: + timer_to_next_event = next_event.start.strftime("%Y-%m-%d %H:%M") + return {"timer": timer_to_next_event} diff --git a/app/main.py b/app/main.py index aa95cc21..8da2952b 100644 --- a/app/main.py +++ b/app/main.py @@ -71,6 +71,7 @@ def create_tables(engine, psql_environment): register, search, telegram, + timer, user, weekview, weight, @@ -121,6 +122,7 @@ async def swagger_ui_redirect(): salary.router, search.router, telegram.router, + timer.router, user.router, weekview.router, weight.router, diff --git a/app/routers/timer.py b/app/routers/timer.py new file mode 100644 index 00000000..b3ce39f2 --- /dev/null +++ b/app/routers/timer.py @@ -0,0 +1,19 @@ +from typing import Dict, Optional + +from fastapi import APIRouter, Depends, Request +from app.internal.security.dependancies import current_user, schema +from app.internal.timer import get_next_user_event_start_time +from app.dependencies import get_db + + +router = APIRouter() + + +@router.get("/timer") +def timer( + request: Request, + session=Depends(get_db), + user: schema.CurrentUser = Depends(current_user) +) -> Dict[str, Optional[str]]: + + return get_next_user_event_start_time(session, user.user_id) diff --git a/app/static/timer.js b/app/static/timer.js new file mode 100644 index 00000000..dce476e4 --- /dev/null +++ b/app/static/timer.js @@ -0,0 +1,29 @@ +//credit for the countdowntimer: https://gist.github.com/Mak-Pro/0e1194d0f8696489a5c8bac72c8fa300 +function countdownTimer() { + fetch('/timer') + .then(response => response.json()) + .then(data => { + + const countDownDate = new Date(data.timer).getTime(); + + // Update the countdown every 1 second + const timerInterval = setInterval(function() { + const now = new Date().getTime(); + const distance = countDownDate - now; + const days = Math.floor(distance / (1000 * 60 * 60 * 24)); + const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); + const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); + const seconds = Math.floor((distance % (1000 * 60)) / 1000); + // Output the result to base.html in an element with id="eventtimer" + document.getElementById("eventtimer").innerText = "Upcoming event in: " + days + "d " + hours + "h " + + minutes + "m " + seconds + "s "; + // Countdown had finished + if (distance < 0) { + clearInterval(timerInterval); + document.getElementById("eventtimer").innerText = "Your Event Starts NOW:)"; + } + }, 1000); + } ); +} + +document.addEventListener("DOMContentLoaded", countdownTimer); diff --git a/app/templates/base.html b/app/templates/base.html index fd313c61..d3ee880b 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -89,6 +89,7 @@ + diff --git a/app/templates/partials/user_profile/sidebar_left/features_card/export_calendar.html b/app/templates/partials/user_profile/sidebar_left/features_card/export_calendar.html index 3a34dade..46c2bb11 100644 --- a/app/templates/partials/user_profile/sidebar_left/features_card/export_calendar.html +++ b/app/templates/partials/user_profile/sidebar_left/features_card/export_calendar.html @@ -4,6 +4,7 @@ Export my calendar +


diff --git a/tests/test_profile.py b/tests/test_profile.py index 880c6ebc..95008a15 100644 --- a/tests/test_profile.py +++ b/tests/test_profile.py @@ -36,6 +36,7 @@ def test_profile_page(profile_test_client): assert b'FakeName' in data assert b'Happy new user!' in data assert b'On This Day' in data + assert b'Event' in data def test_update_user_fullname(profile_test_client): diff --git a/tests/test_timer.py b/tests/test_timer.py new file mode 100644 index 00000000..3d94f2fa --- /dev/null +++ b/tests/test_timer.py @@ -0,0 +1,18 @@ +from app.internal.timer import get_next_user_event +from app.internal.timer import get_next_user_event_start_time + + +def test_get_last_event_success(next_week_event, session): + next_event = get_next_user_event( + session=session, + user_id=next_week_event.owner_id, + ) + assert next_event == next_week_event + + +def test_time_left(next_week_event, session): + time_left = get_next_user_event_start_time( + session=session, + user_id=next_week_event.owner_id, + ) + assert isinstance(time_left["timer"], str)