first stages of linking front/back

This commit is contained in:
samerbam 2023-08-24 14:34:08 -04:00
parent 392bfae855
commit ba7e8f24af
5 changed files with 305 additions and 45 deletions

View File

@ -3,6 +3,7 @@ import requests
# from datetime import datetime # from datetime import datetime
import time import time
import random import random
import copy
class TodoDatabase: class TodoDatabase:
def __init__(self, filename="data.json"): def __init__(self, filename="data.json"):
@ -15,9 +16,11 @@ class TodoDatabase:
pass pass
def save_todo(self, date, todo, save=True): def save_todo(self, date, todo, save=True):
if "recurring" not in self.database:
self.database["recurring"] = []
if date not in self.database: if date not in self.database:
# if not len(self.database[date]) > 0: # if not len(self.database[date]) > 0:
self.database[date] = [] self.database[date] = copy.deepcopy(self.database["recurring"])
if todo.recurring: if todo.recurring:
self.database["recurring"].append(todo.model_dump()) self.database["recurring"].append(todo.model_dump())
self.database[date].append(todo.model_dump()) self.database[date].append(todo.model_dump())

View File

@ -18,7 +18,7 @@ app = FastAPI()
auth = VerifyToken() auth = VerifyToken()
data = TodoDatabase() data = TodoDatabase()
printer = ThermalPrinter(data) printer = ThermalPrinter(data)
printer.print_default() #temp debug # printer.print_default() #temp debug
@ -40,13 +40,14 @@ class TodoDate(BaseModel):
class PrintAction(BaseModel): class PrintAction(BaseModel):
date: str = datetime.today().strftime('%Y-%m-%d') date: str = datetime.today().strftime('%Y-%m-%d')
action: str #Options: action: str #Options:
# default (pulls current todos from date, needs date) # all (pulls current todos from date, needs date)
# sudoku (prints a random sudoku) # sudoku (prints a random sudoku)
# todos (prints only dates todos) # todos (prints only dates todos)
# wordsearch (prints a random wordsearch) # wordsearch (prints a random wordsearch)
# quote (prints a random quote) # quote (prints a random quote)
# greeting (prints a greeting) # greeting (prints a greeting)
# # sentence (prints a custom message)
sentence: str = ""
# @app.get("/api/public") # @app.get("/api/public")
# def public(): # def public():
@ -118,7 +119,7 @@ def write_todos(todos: TodoList, auth_result: str = Security(auth.verify)):
@app.get("/api/todos/print") @app.get("/api/todos/print")
def print_todos(date: PrintAction, auth_result: str = Security(auth.verify)): def print_todos(action: PrintAction, auth_result: str = Security(auth.verify)):
"""A valid access token is required to access this route""" """A valid access token is required to access this route"""
# result = { # result = {
@ -128,8 +129,41 @@ def print_todos(date: PrintAction, auth_result: str = Security(auth.verify)):
# ] # ]
# } #TODO: replace with access to database if no todos provided from request, otherwise print request data # } #TODO: replace with access to database if no todos provided from request, otherwise print request data
todos = data.get_todos(date) #Options:
printer.print_todos() # all (pulls current todos from date, needs date)
# sudoku (prints a random sudoku)
# todos (prints only dates todos)
# wordsearch (prints a random wordsearch)
# quote (prints a random quote)
# greeting (prints a greeting)
# sentence (prints a custom message)
if action.action == "all":
printer.print_default()
if action.action == "sudoku":
printer.print_sudoku()
if action.action == "todos":
printer.print_todos()
if action.action == "wordsearch":
printer.print_wordsearch()
if action.action == "quote":
printer.print_random_quote()
if action.action == "greeting":
printer.print_greeting()
if action.action == "sentence":
printer.print_custom(action.sentence)
printer.finished_printing()
# todos = data.get_todos(action.date)
# printer.print_todos()
return {"result": "success"} return {"result": "success"}

View File

@ -21,6 +21,102 @@
<!-- <div id="testToken"></div> --> <!-- <div id="testToken"></div> -->
<div id="printModel" class="absolute w-full h-full overflow-y-hidden top-0 left-0 hidden">
<div class="flex flex-row w-full justify-center items-center text-center h-screen">
<div class="absolute w-full h-full bg-slate-800 opacity-40 top-0 left-0"></div>
<div class="bg-white inline-block text-left rounded-lg overflow-hidden align-bottom transition-all transform shadow-2xl sm:my-8 sm:align-middle sm:max-w-xl sm:w-full">
<div class="flex flex-col items-center pt-6 pr-6 pb-6 pl-6">
<!-- <div class="grid grid-cols-2 items-center pt-6 pr-6 pb-6 pl-6"> -->
<p class="text-2xl font-semibold leading-none tracking-tighter lg:text-3xl">Print?</p>
<!-- <div class="flex flex-col space-y-2 mt-6"> -->
<div class="grid grid-cols-2 mt-6 gap-2">
<a id="printGreeting" class="cursor-pointer flex text-center items-center justify-center w-full pt-4 pr-10 pb-4 pl-10 text-base
font-medium text-white bg-indigo-600 rounded-xl transition duration-500 ease-in-out transform
hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Print Greeting
</a>
<a id="printTodos" class="cursor-pointer flex text-center items-center justify-center w-full pt-4 pr-10 pb-4 pl-10 text-base
font-medium text-white bg-indigo-600 rounded-xl transition duration-500 ease-in-out transform
hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Print<br>To-dos
</a>
<a id="printSudoku" class="cursor-pointer flex text-center items-center justify-center w-full pt-4 pr-10 pb-4 pl-10 text-base
font-medium text-white bg-indigo-600 rounded-xl transition duration-500 ease-in-out transform
hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Print Sudoku
</a>
<a id="printWordsearch" class="cursor-pointer flex text-center items-center justify-center w-full pt-4 pr-10 pb-4 pl-10 text-base
font-medium text-white bg-indigo-600 rounded-xl transition duration-500 ease-in-out transform
hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Print Wordsearch
</a>
<a id="printQuote" class="cursor-pointer flex text-center items-center justify-center w-full pt-4 pr-10 pb-4 pl-10 text-base
font-medium text-white bg-indigo-600 rounded-xl transition duration-500 ease-in-out transform
hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Print Quote
</a>
<a id="printSentence" class="cursor-pointer flex text-center items-center justify-center w-full pt-4 pr-10 pb-4 pl-10 text-base
font-medium text-white bg-indigo-600 rounded-xl transition duration-500 ease-in-out transform
hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Print Sentence
</a>
<a id="printAll" class="col-span-2 cursor-pointer flex text-center items-center justify-center w-full pt-4 pr-10 pb-4 pl-10 text-base
font-medium text-white bg-indigo-600 rounded-xl transition duration-500 ease-in-out transform
hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Print All
</a>
</div>
<!-- <p class="mt-3 text-base leading-relaxed text-center">I am a fullstack software developer with ReactJS for frontend and NodeJS for backend</p> -->
<!-- <div class="rese"> -->
<!-- <div id="radios"> -->
<!-- <input id="rad1" type="radio" name="radioBtn" checked>
<label class="labels" for="rad1">
<span class="flex flex-col">
<span class="font-semibold">Start</span>
<span id="startTimeLabel">12:59 am</span>
</span>
</label>
<input id="rad2" type="radio" name="radioBtn">
<label class="labels" for="rad2">
<span class="flex flex-col">
<span class="font-semibold">End</span>
<span id="endTimeLabel">12:59 pm</span>
</span>
</label>
<input id="rad3" type="radio" name="radioBtn">
<label class="labels" for="rad3">Third Option</label> -->
<!-- <div id="bckgrnd"></div> -->
<!-- </div> -->
<!-- <div class="mt-6 w-full h-full"> -->
<!-- <div class="flex flex-row space-x-1 items-center justify-center"> -->
<!-- <input id="timeInput" class="h-11 rounded-lg p-4" style="background-color:rgba(239,239,240,1);" type="time" name="time" value="12:59"> -->
<!-- </div> -->
<!-- <div id="quickSelectButtons" class="flex flex-row space-x-1 items-center justify-center flex-wrap"> -->
<!-- </div> -->
<!-- </div> -->
<div class="w-full mt-6">
<a id="printExitButton" class="cursor-pointer flex text-center items-center justify-center w-full pt-4 pr-10 pb-4 pl-10 text-base
font-medium text-white bg-slate-600 rounded-xl transition duration-500 ease-in-out transform
hover:bg-slate-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-slate-500">Exit</a>
<!-- <input class="bg-blue-400 z-99" type="number" inputmode="numeric"/> -->
<!-- <input type="number" pattern="[0-9]*" /> -->
<!-- <input class="w-full bg-slate-200 absolute top-0 left-0 z-50" type="number" name="test" inputmode="decimal"> -->
</div>
<div>
<!-- <input type="number" inputmode="numeric"/> -->
<!-- <input type="number" pattern="\d*"/> -->
<!-- <input class="fixed bg-slate-200 top-0 left-0 z-50" type="number" name="test" inputmode="decimal"> -->
</div>
</div>
</div>
</div>
</div>
<!-- nice colour: bg-gray-800 --> <!-- nice colour: bg-gray-800 -->
<div id="timePickerWindow" class="absolute w-full h-full overflow-y-hidden top-0 left-0 hidden"> <div id="timePickerWindow" class="absolute w-full h-full overflow-y-hidden top-0 left-0 hidden">
<div class="flex flex-row w-full justify-center items-center text-center h-screen"> <div class="flex flex-row w-full justify-center items-center text-center h-screen">
@ -142,6 +238,11 @@
</div> </div>
</div> </div>
</ul> </ul>
<div class="p-2 bg-white shadow-md rounded-lg border m-2 flex flex-row space-x-2">
<button id="prevDayButton" class="bg-slate-200 p-2 w-1/4 rounded-md font-semibold"><- Prev</button>
<button id="nextDayButton" class="bg-slate-200 p-2 w-3/4 rounded-md font-semibold">Next -></button>
</div>
<!-- jsDelivr :: Sortable :: Latest (https://www.jsdelivr.com/package/npm/sortablejs) --> <!-- jsDelivr :: Sortable :: Latest (https://www.jsdelivr.com/package/npm/sortablejs) -->
<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>
<script type="text/javascript"> <script type="text/javascript">
@ -226,33 +327,34 @@
} }
}); });
token.then(t => { token.then(t => {
document.getElementById("loginPanel").classList.add("hidden") // document.getElementById("loginPanel").classList.add("hidden")
console.log(t) // console.log(t)
jToken = t jToken = t
getTodosFromAPI()
// document.getElementById("testToken").innerHTML = t // document.getElementById("testToken").innerHTML = t
fetch('/api/todos/get?' + new URLSearchParams({ // fetch('/api/todos/get?' + new URLSearchParams({
date: dayjs().format("YYYY-MM-DD"), // date: dayjs().format("YYYY-MM-DD"),
}), { // }), {
method: 'GET', // method: 'GET',
withCredentials: true, // withCredentials: true,
credentials: 'include', // credentials: 'include',
headers: { // headers: {
'Authorization': "Bearer " + t, // 'Authorization': "Bearer " + t,
} // }
}).then(re => { // }).then(re => {
re.json().then(jso => { // re.json().then(jso => {
console.log(jso) // console.log(jso)
for (let todo of jso.todos) { // for (let todo of jso.todos) {
console.log(todo) // console.log(todo)
// function addTask(defaultTimeRange="", defaultTaskText="New Task", editable=true) { // // function addTask(defaultTimeRange="", defaultTaskText="New Task", editable=true) {
addTask(defaultTimeRange=todo.time, defaultTaskText=todo.text, editable=false) // addTask(defaultTimeRange=todo.time, defaultTaskText=todo.text, editable=false)
} // }
}) // })
// var items = JSON.parse(re.json()) // // var items = JSON.parse(re.json())
// console.log(items.json) // // console.log(items.json)
}) // })
//TODO: Make call with token to backend to load all current todos //TODO: Make call with token to backend to load all current todos
}) })
@ -261,6 +363,39 @@
}; };
function getTodosFromAPI() {
document.getElementById("loginPanel").classList.add("hidden")
console.log(t)
// jToken = t
// document.getElementById("testToken").innerHTML = t
fetch('/api/todos/get?' + new URLSearchParams({
date: dayjs().format("YYYY-MM-DD"),
}), {
method: 'GET',
withCredentials: true,
credentials: 'include',
headers: {
'Authorization': "Bearer " + t,
}
}).then(re => {
re.json().then(jso => {
console.log(jso)
for (let todo of jso.todos) {
console.log(todo)
// function addTask(defaultTimeRange="", defaultTaskText="New Task", editable=true) {
addTask(defaultTimeRange=todo.time, defaultTaskText=todo.text, editable=false)
}
})
// var items = JSON.parse(re.json())
// console.log(items.json)
})
//TODO: Make call with token to backend to load all current todos
}
document.getElementById("loginButton").addEventListener('click', loginAction) document.getElementById("loginButton").addEventListener('click', loginAction)
// document.getElementById("loginButton").addEventListener('click', (e) => { // document.getElementById("loginButton").addEventListener('click', (e) => {
// auth0.createAuth0Client({ // auth0.createAuth0Client({

View File

@ -118,6 +118,8 @@ function blurOrKeypress(e) {
e.target.parentElement.parentElement.parentElement.removeChild(e.target.parentElement.parentElement) e.target.parentElement.parentElement.parentElement.removeChild(e.target.parentElement.parentElement)
// return // return
} }
setsavePrintButton(save=true)
// } // }
@ -301,6 +303,7 @@ function addTask(defaultTimeRange="", defaultTaskText="New Task", editable=true)
timePickerWindowButton.addEventListener("click", showTimePickerWindow) timePickerWindowButton.addEventListener("click", showTimePickerWindow)
timeslotSpan.addEventListener("mousedown", timeSlotShowTimePickerButton) timeslotSpan.addEventListener("mousedown", timeSlotShowTimePickerButton)
row.addEventListener('click', singleClickListener); row.addEventListener('click', singleClickListener);
setsavePrintButton(save=true)
// ed.firstChild.focus() // ed.firstChild.focus()
@ -406,6 +409,7 @@ function quickButtonListener(e) {
function saveButtonListener(e) { function saveButtonListener(e) {
setsavePrintButton(save=true)
let startTime = dayjs(document.getElementById("startTimeLabel").innerHTML, 'h:mm a') let startTime = dayjs(document.getElementById("startTimeLabel").innerHTML, 'h:mm a')
let endTime = dayjs(document.getElementById("endTimeLabel").innerHTML, 'h:mm a') let endTime = dayjs(document.getElementById("endTimeLabel").innerHTML, 'h:mm a')
console.log('??') console.log('??')
@ -465,6 +469,7 @@ function showTimePickerWindow(e) {
console.log(e.target.dataset.timepickershown) console.log(e.target.dataset.timepickershown)
if (this.dataset.timepickershown === 'true') return; if (this.dataset.timepickershown === 'true') return;
setsavePrintButton(save=true)
this.dataset.timepickershown = true this.dataset.timepickershown = true
// document.getElementById("") // document.getElementById("")
@ -490,6 +495,7 @@ function timeSlotShowTimePickerButton(e) {
console.log('yay!') console.log('yay!')
if (this.parentElement.parentElement.querySelector(".timePickerWindowButton").dataset.timepickershown === 'true') return; if (this.parentElement.parentElement.querySelector(".timePickerWindowButton").dataset.timepickershown === 'true') return;
console.log('woohoo') console.log('woohoo')
setsavePrintButton(save=true)
this.parentElement.parentElement.querySelector(".timePickerWindowButton").dataset.timepickershown = true this.parentElement.parentElement.querySelector(".timePickerWindowButton").dataset.timepickershown = true
let times = this.parentElement.parentElement.querySelector(".timePickerWindowButton").querySelector("#timeButtonDisplay").innerHTML.split(" to ") let times = this.parentElement.parentElement.querySelector(".timePickerWindowButton").querySelector("#timeButtonDisplay").innerHTML.split(" to ")
@ -514,6 +520,7 @@ function recurringButtonListener(e) {
// TODO: change colour to green // TODO: change colour to green
// //
setsavePrintButton(save=true)
if (this.parentElement.parentElement.dataset.recurring === "true") { if (this.parentElement.parentElement.dataset.recurring === "true") {
this.querySelector("svg").classList.add("text-black") this.querySelector("svg").classList.add("text-black")
@ -528,31 +535,106 @@ function recurringButtonListener(e) {
} }
function setsavePrintButton(save=true) {
let spb = document.getElementById("savePrintButton")
let spbt = document.getElementById("savePrintButtonText")
if (!save) {
spbt.innerHTML = "Print"
spb.classList.add("bg-indigo-200")
spb.classList.add("border-indigo-300")
spb.classList.remove("bg-green-200")
spb.classList.remove("border-green-300")
//bg-indigo-200 border-indigo-300
} else {
spbt.innerHTML = "Save"
spb.classList.remove("bg-indigo-200")
spb.classList.remove("border-indigo-300")
spb.classList.add("bg-green-200")
spb.classList.add("border-green-300")
//bg-green-200 border-green-300
}
}
function savePrintButtonListener(e) { function savePrintButtonListener(e) {
let spbt = document.getElementById("savePrintButtonText") let spbt = document.getElementById("savePrintButtonText")
if (spbt.innerHTML === "Save") { if (spbt.innerHTML === "Save") {
spbt.innerHTML = "Print" setsavePrintButton(save=false)
this.classList.add("bg-indigo-200") //TODO: send api request to save todos to database
this.classList.add("border-indigo-300")
this.classList.remove("bg-green-200")
this.classList.remove("border-green-300")
//bg-indigo-200 border-indigo-300
} else if (spbt.innerHTML === "Print") { } else if (spbt.innerHTML === "Print") {
spbt.innerHTML = "Save" document.getElementById("printModel").classList.remove("hidden")
this.classList.remove("bg-indigo-200") // setsavePrintButton(save=true)
this.classList.remove("border-indigo-300")
this.classList.add("bg-green-200")
this.classList.add("border-green-300")
//bg-green-200 border-green-300 //bg-green-200 border-green-300
} }
} }
function printButtonListener(e) {
let action = ""
switch(this.id) {
case "printGreeting":
action = "greeting"
break;
case "printTodos":
action = "todos"
break;
case "printSudoku":
action = "sudoku"
break;
case "printWordsearch":
action = "wordsearch"
break;
case "printQuote":
action = "quote"
break;
case "printSentence":
action = "sentence"
let sentence = prompt("What would you like to print?")
break;
case "printAll":
action = "all"
break;
case "printExitButton":
document.getElementById("printModel").classList.add("hidden")
return
}
}
function switchDayListener(e) {
console.log(document.getElementById("date-view").innerHTML)
console.log(dayjs(document.getElementById("date-view").innerHTML, "ddd MMM D, YYYY"))
let dateView = document.getElementById("date-view")
switch (this.id) {
case "nextDayButton":
dateView.innerHTML = dayjs(dateView.innerHTML.slice(4), "MMM D, YYYY").add(1, 'day').format("ddd MMM D, YYYY")
break;
case "prevDayButton":
dateView.innerHTML = dayjs(dateView.innerHTML.slice(4), "MMM D, YYYY").subtract(1, 'day').format("ddd MMM D, YYYY")
break;
}
}
document.getElementById("nextDayButton").addEventListener("click", switchDayListener)
document.getElementById("prevDayButton").addEventListener("click", switchDayListener)
document.getElementById("printGreeting").addEventListener("click", printButtonListener)
document.getElementById("printTodos").addEventListener("click", printButtonListener)
document.getElementById("printSudoku").addEventListener("click", printButtonListener)
document.getElementById("printWordsearch").addEventListener("click", printButtonListener)
document.getElementById("printQuote").addEventListener("click", printButtonListener)
document.getElementById("printSentence").addEventListener("click", printButtonListener)
document.getElementById("printAll").addEventListener("click", printButtonListener)
document.getElementById("printExitButton").addEventListener("click", printButtonListener)
document.getElementById("savePrintButton").addEventListener("click", savePrintButtonListener) document.getElementById("savePrintButton").addEventListener("click", savePrintButtonListener)

View File

@ -56,6 +56,12 @@ class ThermalPrinter():
print("Try running `export DYLD_LIBRARY_PATH=/opt/homebrew/lib` if on m1 mac. source: https://github.com/pyusb/pyusb/issues/355#issuecomment-1062798576") print("Try running `export DYLD_LIBRARY_PATH=/opt/homebrew/lib` if on m1 mac. source: https://github.com/pyusb/pyusb/issues/355#issuecomment-1062798576")
raise raise
def print_custom(self, text=""):
self.p.set(align="left")
for l in textwrap.wrap(text, 32):
self.p.text(l + "\n")
# self.p.text(text)
def print_greeting(self): def print_greeting(self):
self.p.set(align="center") self.p.set(align="center")
self.p.text(datetime.today().strftime('%Y-%m-%d')) self.p.text(datetime.today().strftime('%Y-%m-%d'))
@ -148,8 +154,8 @@ class ThermalPrinter():
self.p.set(align="left") self.p.set(align="left")
# self.p.text(q[0]) # self.p.text(q[0])
for l in textwrap.wrap(q[0], 32): for l in textwrap.wrap(q[0], 32):
self.p.text(l) self.p.text(l + "\n")
self.p.text("\n") # self.p.text("\n")
self.p.set(align="right") self.p.set(align="right")
self.p.text(q[1]) self.p.text(q[1])
self.p.text("\n") self.p.text("\n")