-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
28 changed files
with
1,430 additions
and
1,338 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
from random import randint | ||
from pathlib import Path | ||
import datetime | ||
|
||
import starlette.status as status | ||
from fastapi import APIRouter, Request, Depends | ||
from fastapi.responses import HTMLResponse, RedirectResponse | ||
from fastapi.templating import Jinja2Templates | ||
|
||
from flashcards_htmx.app import template, decks | ||
|
||
|
||
templates = Jinja2Templates(directory=Path(__file__).parent / "templates") | ||
router = APIRouter(prefix="/htmx/components") | ||
|
||
|
||
@router.get("/decks", response_class=HTMLResponse) | ||
async def decks_component(render=Depends(template("responses/decks.html"))): | ||
return render(decks=decks) | ||
|
||
|
||
@router.get("/decks/search_filters", response_class=HTMLResponse) | ||
async def decks_search_component( | ||
render=Depends(template("components/filter-modal.html")), | ||
): | ||
return render( | ||
title=f"decks", content=f"Content here", positive=f"Search", negative=f"Cancel" | ||
) | ||
|
||
|
||
@router.get("/decks/{deck_id}/cards", response_class=HTMLResponse) | ||
async def cards_component( | ||
deck_id: str, render=Depends(template("responses/cards.html")) | ||
): | ||
return render(deck=decks[deck_id]) | ||
|
||
|
||
@router.get("/decks/{deck_id}/study", response_class=HTMLResponse) | ||
async def study_component( | ||
deck_id: str, render=Depends(template("responses/study.html")) | ||
): | ||
# TODO actually get the card to study from the deck | ||
card_id = randint(0, 3) | ||
if card_id == "0": | ||
return render(card=None) | ||
if card_id == "1": | ||
return render(error="Test Error") | ||
return render(deck=decks[deck_id], deck_id=deck_id, card=decks[deck_id]["cards"]["1"], card_id="1") | ||
|
||
|
||
@router.post( | ||
"/decks/{deck_id}/study/{card_id}/{result}", response_class=RedirectResponse | ||
) | ||
async def save_review_component( | ||
deck_id: str, card_id: str, result: str, request: Request | ||
): | ||
# TODO save the review | ||
decks[deck_id]["cards"][card_id]["reviews"][len(decks[deck_id]["cards"][card_id]["reviews"])] = { | ||
"date": datetime.utcnow().isoformat(), | ||
"result": result, | ||
} | ||
return RedirectResponse( | ||
request.url_for("study_component", deck_id=deck_id), | ||
status_code=status.HTTP_302_FOUND, | ||
) | ||
|
||
|
||
@router.get("/decks/{deck_id}/confirm-delete", response_class=HTMLResponse) | ||
async def deck_confirm_delete_component( | ||
deck_id: str, render=Depends(template("components/message-modal.html")) | ||
): | ||
return render( | ||
title=f"Deleting {decks[deck_id]['name']}", | ||
content=f"Are you really sure you wanna delete the deck {decks[deck_id]['name']}? It contains XXXX cards!", | ||
positive=f"Yes, delete {decks[deck_id]['name']}", | ||
negative=f"No, don't delete", | ||
) | ||
|
||
|
||
@router.get( | ||
"/decks/{deck_id}/cards/{card_id}/confirm-delete", response_class=HTMLResponse | ||
) | ||
async def card_confirm_delete_component( | ||
deck_id: str, | ||
card_id: str, | ||
render=Depends(template("components/message-modal.html")), | ||
): | ||
return render( | ||
title=f"Deleting card n. {decks[deck_id]['cards'][card_id]['id']}", | ||
content=f"Are you really sure you wanna delete this card? [TODO show card preview]", | ||
positive=f"Yes, delete it", | ||
negative=f"No, don't delete", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
from typing import Optional | ||
from pathlib import Path | ||
|
||
import starlette.status as status | ||
from fastapi import APIRouter, Request, Depends | ||
from fastapi.responses import HTMLResponse, RedirectResponse | ||
from fastapi.templating import Jinja2Templates | ||
|
||
from flashcards_htmx.app import template, decks | ||
|
||
|
||
templates = Jinja2Templates(directory=Path(__file__).parent / "templates") | ||
router = APIRouter() | ||
|
||
|
||
@router.get("/home", response_class=HTMLResponse) | ||
async def home_page(request: Request, render=Depends(template("private/home.html"))): | ||
return render( | ||
navbar_title="Home", | ||
searchable=True, | ||
new_item_endpoint=request.url_for("create_deck_page"), | ||
new_item_text="New Deck...", | ||
) | ||
|
||
|
||
@router.get("/profile", response_class=HTMLResponse) | ||
async def profile_page(render=Depends(template("private/profile.html"))): | ||
# TODO actually get the profile information | ||
return render(navbar_title="My name") | ||
|
||
|
||
@router.get("/study/{deck_id}", response_class=HTMLResponse) | ||
async def study_page(deck_id: str, render=Depends(template("private/study.html"))): | ||
return render(navbar_title=decks[deck_id]["name"], deck=decks[deck_id], deck_id=deck_id) | ||
|
||
|
||
@router.get("/decks/new", response_class=HTMLResponse) | ||
async def create_deck_page(render=Depends(template("private/deck.html"))): | ||
return render( | ||
navbar_title="New Deck", | ||
deck={"name": "", "description": "", "algorithm": "Random"}, | ||
deck_id= len(decks) + 1 | ||
) | ||
|
||
|
||
@router.get("/decks/{deck_id}", response_class=HTMLResponse) | ||
async def edit_deck_page(deck_id: str, render=Depends(template("private/deck.html"))): | ||
return render(navbar_title=decks[deck_id]["name"], deck=decks[deck_id], deck_id=deck_id) | ||
|
||
|
||
@router.post("/decks/{deck_id}", response_class=RedirectResponse) | ||
async def save_deck_endpoint(deck_id: str, request: Request): | ||
async with request.form() as form: | ||
decks[deck_id] = { | ||
"name": form["name"], | ||
"description": form["description"], | ||
"algorithm": form["algorithm"], | ||
"cards": {}, | ||
} | ||
return RedirectResponse( | ||
request.url_for("home_page"), status_code=status.HTTP_302_FOUND | ||
) | ||
|
||
|
||
@router.get("/decks/{deck_id}/cards", response_class=HTMLResponse) | ||
async def cards_page( | ||
deck_id: str, request: Request, render=Depends(template("private/cards.html")) | ||
): | ||
return render( | ||
navbar_title=decks[deck_id]["name"], | ||
deck=decks[deck_id], | ||
deck_id=deck_id, | ||
searchable=True, | ||
new_item_endpoint=request.url_for("create_card_page", deck_id=deck_id), | ||
new_item_text="New Card...", | ||
) | ||
|
||
|
||
@router.get("/decks/{deck_id}/cards/new", response_class=HTMLResponse) | ||
async def create_card_page(deck_id: str, render=Depends(template("private/card.html"))): | ||
return render( | ||
navbar_title=decks[deck_id]["name"], | ||
deck=decks[deck_id], | ||
deck_id=deck_id, | ||
card={ | ||
"id": len(decks[deck_id]["cards"]) + 1, | ||
"question_data": {}, | ||
"answer_data": {}, | ||
"preview_data": {}, | ||
"tags": [], | ||
"type": "Q/A", | ||
}, | ||
) | ||
|
||
|
||
@router.get("/decks/{deck_id}/cards/{card_id}", response_class=HTMLResponse) | ||
async def edit_card_page( | ||
deck_id: str, card_id: str, render=Depends(template("private/card.html")) | ||
): | ||
return render( | ||
navbar_title=decks[deck_id]["name"], | ||
deck=decks[deck_id], | ||
deck_id=deck_id, | ||
card=decks[deck_id]["cards"][card_id] | ||
) | ||
|
||
|
||
@router.post("/decks/{deck_id}/cards/{card_id}", response_class=RedirectResponse) | ||
async def save_card_endpoint(deck_id: str, card_id: Optional[str], request: Request): | ||
async with request.form() as form: | ||
decks[deck_id]["cards"][card_id] = { | ||
"question_data": { | ||
key[len("question."):] : value for key, value in form.items() if key.startswith("question.") | ||
}, | ||
"answer_data": { | ||
key[len("answer."):] : value for key, value in form.items() if key.startswith("answer.") | ||
}, | ||
"preview_data": { | ||
key[len("preview."):] : value for key, value in form.items() if key.startswith("preview.") | ||
}, | ||
"tags": form["tags"].split(","), | ||
"type": form["type"], | ||
} | ||
return RedirectResponse( | ||
request.url_for("home_page"), status_code=status.HTTP_302_FOUND | ||
) | ||
|
||
|
||
@router.post("/logout", response_class=RedirectResponse) | ||
async def logout_page(request: Request): | ||
return RedirectResponse( | ||
request.url_for("home_page"), status_code=status.HTTP_302_FOUND | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import starlette.status as status | ||
from fastapi import APIRouter, Request, Depends | ||
from fastapi.responses import HTMLResponse, RedirectResponse | ||
|
||
from flashcards_htmx.app import template | ||
|
||
|
||
router = APIRouter() | ||
|
||
|
||
@router.get("/", response_class=HTMLResponse) | ||
async def landing_page(render=Depends(template("public/landing-page.html"))): | ||
return render() | ||
|
||
|
||
@router.get("/login", response_class=HTMLResponse) | ||
async def login_page(render=Depends(template("public/login.html"))): | ||
return render() | ||
|
||
|
||
@router.post("/login", response_class=RedirectResponse) | ||
async def login_action(request: Request): | ||
# FIXME Actually do the login! | ||
return RedirectResponse( | ||
request.url_for("home_page"), status_code=status.HTTP_302_FOUND | ||
) | ||
|
||
|
||
@router.get("/signup", response_class=HTMLResponse) | ||
async def signup_page(render=Depends(template("public/signup.html"))): | ||
return render() | ||
|
||
|
||
@router.post("/signup", response_class=RedirectResponse) | ||
async def signup_action(request: Request): | ||
# FIXME Actually do the signup! | ||
return RedirectResponse( | ||
request.url_for("home_page"), status_code=status.HTTP_302_FOUND | ||
) | ||
|
||
|
||
@router.get("/reset-password", response_class=HTMLResponse) | ||
async def reset_password_page(render=Depends(template("public/reset-password.html"))): | ||
return render() | ||
|
||
|
||
@router.post("/reset-password", response_class=RedirectResponse) | ||
async def reset_password_action(request: Request): | ||
# FIXME Actually do the password reset! | ||
return RedirectResponse( | ||
request.url_for("home_page"), status_code=status.HTTP_302_FOUND | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
Oops, something went wrong.