Cleaned up the grid that shows a person's db entries. Created basic card for the dashboard page.
This commit is contained in:
BIN
__pycache__/dashboard.cpython-312.pyc
Normal file
BIN
__pycache__/dashboard.cpython-312.pyc
Normal file
Binary file not shown.
BIN
__pycache__/main.cpython-312.pyc
Normal file
BIN
__pycache__/main.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
13
dashboard.py
Normal file
13
dashboard.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import theme
|
||||||
|
from nicegui import ui
|
||||||
|
from main import checked_data
|
||||||
|
|
||||||
|
@ui.page('/dashboard')
|
||||||
|
def dashboard():
|
||||||
|
with theme.frame('Dashboard'):
|
||||||
|
pass
|
||||||
|
|
||||||
|
with ui.grid(columns='auto 150px'):
|
||||||
|
with ui.card().classes('border-purple-200 grid justify-items-center').style('border: 2px solid rgba(0, 255, 0, .25)'):
|
||||||
|
ui.label('John 3:16').classes('text-center')
|
||||||
|
ui.label('For God Sent his son etc etc').classes('font-bold')
|
||||||
124
main.py
124
main.py
@ -1,5 +1,5 @@
|
|||||||
import data
|
import data
|
||||||
import homepage
|
import dashboard
|
||||||
from nicegui import app, ui
|
from nicegui import app, ui
|
||||||
import re
|
import re
|
||||||
import requests
|
import requests
|
||||||
@ -20,15 +20,17 @@ def index_page() -> None:
|
|||||||
|
|
||||||
with ui.grid(columns=1).classes('self-center justify-items-center content-center p-2 m-2 rounded-xl'):
|
with ui.grid(columns=1).classes('self-center justify-items-center content-center p-2 m-2 rounded-xl'):
|
||||||
toggle = ui.toggle(["Hannah", "Fiona", "Liam"], clearable=True, on_change=lambda: show_person(toggle))
|
toggle = ui.toggle(["Hannah", "Fiona", "Liam"], clearable=True, on_change=lambda: show_person(toggle))
|
||||||
with ui.row().classes('absolute bottom-0 left-0 p-2 m-2'):
|
with ui.row().classes('fixed bottom-0 left-0 p-2 m-2'):
|
||||||
with ui.element('q-fab').props('icon=navigation color=green'):
|
with ui.element('q-fab').props('icon=navigation color=accent'):
|
||||||
ui.element('q-fab-action').props('icon=add color=blue-5').on('click', lambda: add_verse(toggle))
|
ui.element('q-fab-action').props('icon=add color=secondary').on('click', lambda: add_verse(toggle))
|
||||||
ui.element('q-fab-action').props('icon=remove color=red-3').on('click', lambda: remove_verse(toggle))
|
ui.element('q-fab-action').props('icon=remove color=negative').on('click', lambda: remove_verse(toggle))
|
||||||
|
|
||||||
with ui.row().style('justify-content: center') as showperson:
|
with ui.row().style('justify-content: center') as showperson:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
showperson.set_visibility(False)
|
showperson.set_visibility(False)
|
||||||
|
# FEAT: Allow editing of the verse. Awana will sometimes only give the student part of a verse (i.e 1 John 4:14 is actually 14b).
|
||||||
|
# FEAT: Find how to pin/bind a verse to a second page
|
||||||
|
|
||||||
@ui.refreshable
|
@ui.refreshable
|
||||||
def show_person(person):
|
def show_person(person):
|
||||||
@ -42,20 +44,29 @@ def index_page() -> None:
|
|||||||
else:
|
else:
|
||||||
showperson.set_visibility(True) #False if showperson.visible else True)
|
showperson.set_visibility(True) #False if showperson.visible else True)
|
||||||
# showoptions.set_visibility(True)
|
# showoptions.set_visibility(True)
|
||||||
with showperson.classes('border-8'):
|
if person.value == "Hannah":
|
||||||
with ui.grid(columns=5).classes('rounded-md items-center border-8'):
|
setcolor = "rgba(0, 255, 0, .5)"
|
||||||
|
elif person.value == "Fiona":
|
||||||
|
setcolor = "rgba(255, 0, 0, .5)"
|
||||||
|
else:
|
||||||
|
setcolor = "rgba(0, 0, 255, .5)"
|
||||||
|
with showperson.classes(f'border-8').style(f'border: {setcolor} 1px solid;'):
|
||||||
|
with ui.grid(columns=5).classes('items-center w-full'):
|
||||||
|
ui.separator().classes('col-span-5 h-2')
|
||||||
for item in dbinfo:
|
for item in dbinfo:
|
||||||
label_verse = ui.label(text=item[0]).classes('hidden')
|
label_verse = ui.label(text=item[0]).classes('hidden')
|
||||||
label_passage = ui.label(text=item[1]).classes('hidden')
|
label_passage = ui.label(text=item[1]).classes('hidden')
|
||||||
label_status = ui.label(text=item[2]).classes('hidden')
|
label_status = ui.label(text=item[2]).classes('hidden')
|
||||||
ui.chip(label_verse.text, icon='ads_click', on_click=lambda: ui.notify(label_passage.text))
|
ui.label(label_verse.text).classes('font-bold')
|
||||||
|
# ui.chip(label_verse.text, icon='ads_click', on_click=lambda: ui.notify(label_passage.text)).classes('border p-1')
|
||||||
ui.label(label_passage.text).classes('text-wrap')
|
ui.label(label_passage.text).classes('text-wrap')
|
||||||
if label_status.text == '0':
|
if label_status.text == '0':
|
||||||
ui.chip("Incomplete", selectable=True, icon="add", color="orange", on_selection_change=lambda: toggle_completion(label_verse.text, person, status=1))
|
ui.chip("Incomplete", selectable=True, icon="add", color="negative", on_selection_change=lambda: toggle_completion(label_verse.text, person, status=1))
|
||||||
else:
|
else:
|
||||||
ui.chip("Complete", selectable=True, icon="add", color="green", on_selection_change=lambda: toggle_completion(label_verse.text, person, status=0))
|
ui.chip("Complete", selectable=True, icon="add", color="accent", on_selection_change=lambda: toggle_completion(label_verse.text, person, status=0))
|
||||||
ui.checkbox('Pin Verse')#.bind_visibility_from(card, 'value')
|
ui.checkbox('Pin Verse')#.bind_visibility_from(card, 'value')
|
||||||
ui.checkbox('Mark as Completed')#.bind_value(item[2])
|
ui.checkbox('Mark as Completed')#.bind_value(item[2])
|
||||||
|
ui.separator().classes('col-span-5 h-2')
|
||||||
else:
|
else:
|
||||||
showperson.clear()
|
showperson.clear()
|
||||||
|
|
||||||
@ -68,6 +79,7 @@ def index_page() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def add_verse(person):
|
def add_verse(person):
|
||||||
|
# TODO: Add check of existing verses so that a user can't add duplicates.
|
||||||
if person.value is None:
|
if person.value is None:
|
||||||
ui.notify("Oops! You haven't selected a person")
|
ui.notify("Oops! You haven't selected a person")
|
||||||
else:
|
else:
|
||||||
@ -76,55 +88,63 @@ def index_page() -> None:
|
|||||||
with ui.card().classes('flex-wrap items-center'):
|
with ui.card().classes('flex-wrap items-center'):
|
||||||
result = ui.input(label="Add Verse Here")
|
result = ui.input(label="Add Verse Here")
|
||||||
with ui.row().classes('justify-content-center'):
|
with ui.row().classes('justify-content-center'):
|
||||||
ui.button().props('push glossy icon=add_circle color=indigo-5').on('click', lambda: submit_verse(result, person))
|
ui.button().props('push glossy icon=add_circle color=secondary').on('click', lambda: submit_verse(result, person))
|
||||||
ui.button().props('push glossy icon=cancel color=orange-3').on('click', lambda: addverse.close())
|
ui.button().props('push glossy icon=cancel color=negative').on('click', lambda: addverse.close())
|
||||||
|
|
||||||
def submit_verse(result, person):
|
def submit_verse(result, person):
|
||||||
# Verify the format of a Bible Verse
|
# Check if Verse is already in db
|
||||||
if not re.match(r'((^\d\s\w{1,}\s|^\w{1,}\s)(\d{1,2}:)(\d{1,2}-\d{1,2}|\d{1,2}))', result.value):
|
dbcheck = cur.execute(f"select * from tasks where person = '{person.value.lower()}' and verse = '{result.value}';")
|
||||||
ui.notify("Verse was input incorrectly.")
|
check_for_verse = dbcheck.fetchone()
|
||||||
addverse.clear()
|
if check_for_verse is not None:
|
||||||
|
ui.notify(f"{result.value} already exists for {person.value}! You can't have duplicates")
|
||||||
else:
|
else:
|
||||||
# Split up the string for later
|
# Verify the format of a Bible Verse
|
||||||
colon = result.value.split(':')
|
if not re.match(r'((^\d\s\w{1,}\s|^\w{1,}\s)(\d{1,2}:)(\d{1,2}-\d{1,2}|\d{1,2}))', result.value):
|
||||||
precolon = colon[0].split(' ')[1].strip()
|
ui.notify("Verse was input incorrectly.")
|
||||||
postcolon = colon[1].strip()
|
addverse.clear()
|
||||||
if '-' in postcolon:
|
|
||||||
start = postcolon.split('-')[0]
|
|
||||||
end = postcolon.split('-')[1]
|
|
||||||
else:
|
else:
|
||||||
start = postcolon
|
# Split up the string for later
|
||||||
|
colon = result.value.split(':')
|
||||||
# Get Verse Endpoint
|
precolon = colon[0].split(' ')[1].strip()
|
||||||
url = f"https://api.esv.org/v3/passage/text/?q={result.value}"
|
postcolon = colon[1].strip()
|
||||||
response = requests.get(url, headers=HEADERS)
|
if '-' in postcolon:
|
||||||
if response.status_code == 200 or response.status_code == 202:
|
start = postcolon.split('-')[0]
|
||||||
vpass = response.json()
|
end = postcolon.split('-')[1]
|
||||||
passage = str(vpass["passages"])
|
|
||||||
# npassage gets rid of any carriage return characters
|
|
||||||
npassage = passage.replace('\\n', '').strip()
|
|
||||||
# xpassage removes Footnotes section, if it exists
|
|
||||||
if 'Footnotes' in npassage:
|
|
||||||
xpassage = re.sub(r'Footnotes.*', '', npassage)
|
|
||||||
else:
|
else:
|
||||||
xpassage = npassage.replace("(ESV)']", '')
|
start = postcolon
|
||||||
# vpassage grabs the actual verses, dropping the title (starting from first verse in result)
|
|
||||||
print(xpassage)
|
# Get Verse Endpoint
|
||||||
vpassage = re.search(fr'\[{start}\].*', xpassage).group(0)
|
url = f"https://api.esv.org/v3/passage/text/?q={result.value}"
|
||||||
# zpassage - remove any parenthesis or brackets references
|
response = requests.get(url, headers=HEADERS)
|
||||||
zpassage = re.sub(r'\[\d+\]|\(\d+\)|\s{2,}', '', vpassage).strip()
|
if response.status_code == 200 or response.status_code == 202:
|
||||||
if re.match(r'^\“', zpassage):
|
vpass = response.json()
|
||||||
zpassage = f'{zpassage}”'
|
passage = str(vpass["passages"])
|
||||||
|
# npassage gets rid of any carriage return characters
|
||||||
|
npassage = passage.replace('\\n', '').strip()
|
||||||
|
# xpassage removes Footnotes section, if it exists
|
||||||
|
if 'Footnotes' in npassage:
|
||||||
|
xpassage = re.sub(r'Footnotes.*', '', npassage)
|
||||||
|
else:
|
||||||
|
xpassage = npassage.replace("(ESV)']", '')
|
||||||
|
# vpassage grabs the actual verses, dropping the title (starting from first verse in result)
|
||||||
|
print(xpassage)
|
||||||
|
vpassage = re.search(fr'\[{start}\].*', xpassage).group(0)
|
||||||
|
# zpassage - remove any parenthesis or brackets references
|
||||||
|
zpassage = re.sub(r'\[\d+\]|\(\d+\)|\s{2,}', '', vpassage).strip()
|
||||||
|
if re.match(r'^\“', zpassage):
|
||||||
|
zpassage = f'{zpassage}”'
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
print(zpassage)
|
||||||
else:
|
else:
|
||||||
pass
|
print(response.text)
|
||||||
print(zpassage)
|
ui.notify("Uh oh. Something went wrong.")
|
||||||
else:
|
|
||||||
print(response.text)
|
|
||||||
ui.notify("Uh oh. Something went wrong.")
|
|
||||||
|
|
||||||
ins = cur.execute(f"insert into tasks values('{person.value.lower()}', '{result.value}', '{zpassage}', 0, 0, 'none');")
|
ins = cur.execute(f"replace into tasks values('{person.value.lower()}', '{result.value}', '{zpassage}', 0, 0, 'none');")
|
||||||
db.commit()
|
db.commit()
|
||||||
show_person(person)
|
show_person(person)
|
||||||
|
|
||||||
|
def checked_data() -> None:
|
||||||
|
datavals = []
|
||||||
|
|
||||||
ui.run(storage_secret='b601785a-855c-41d1-adeb-68f0330d8186')
|
ui.run(storage_secret='b601785a-855c-41d1-adeb-68f0330d8186')
|
||||||
|
|||||||
Binary file not shown.
8
theme.py
8
theme.py
@ -5,13 +5,15 @@ from nicegui import ui
|
|||||||
@contextmanager
|
@contextmanager
|
||||||
def frame(navigation_title: str):
|
def frame(navigation_title: str):
|
||||||
"""Custom page frame to share the same styling and behavior across all pages"""
|
"""Custom page frame to share the same styling and behavior across all pages"""
|
||||||
ui.colors(primary='#6E93D6', secondary='#53B689', accent='#111B1E', positive='#53B689')
|
ui.colors(primary='#023047', secondary='#219ebc', accent='#8ecae6', positive='#ffb703', negative='#fb8500')
|
||||||
with ui.header():
|
with ui.header():
|
||||||
ui.label('Awana Verse Practice').classes('font-bold')
|
ui.label('Awana Verse Practice').classes('font-bold font-16')
|
||||||
ui.space()
|
ui.space()
|
||||||
ui.space()
|
ui.space()
|
||||||
ui.space()
|
ui.space()
|
||||||
ui.space()
|
ui.space()
|
||||||
ui.label(navigation_title)
|
with ui.row():
|
||||||
|
ui.link('Admin', '/').classes(replace='text-white')
|
||||||
|
ui.link('Dashboard', '/dashboard').classes(replace='text-white')
|
||||||
with ui.column().classes('absolute-center items-center'):
|
with ui.column().classes('absolute-center items-center'):
|
||||||
yield
|
yield
|
||||||
|
|||||||
Reference in New Issue
Block a user