add edit profile page and default profile picture

This commit is contained in:
David Rodenkirchen 2024-08-26 16:38:32 +02:00
parent bdae7b266b
commit 09d7178ea0
4 changed files with 242 additions and 2 deletions

View File

@ -109,7 +109,7 @@ if __name__ == "__main__":
Page( Page(
name="EditProfile", name="EditProfile",
page_url="edit-profile", page_url="edit-profile",
build=lambda: pages.PlaceholderPage(placeholder_name="Profil bearbeiten"), build=pages.EditProfilePage,
guard=logged_in_guard guard=logged_in_guard
), ),
Page( Page(

View File

@ -0,0 +1,239 @@
from datetime import date, datetime
from asyncio import sleep
from hashlib import sha256
from typing import Optional
from from_root import from_root
from rio import Column, Component, event, Text, TextStyle, Button, Color, Row, TextInput, Image, TextInputChangeEvent, NoFileSelectedError
from email_validator import validate_email, EmailNotValidError
from src.ez_lan_manager import ConfigurationService, UserService
from src.ez_lan_manager.components.MainViewContentBox import MainViewContentBox
from src.ez_lan_manager.pages import BasePage
from src.ez_lan_manager.types.SessionStorage import SessionStorage
from src.ez_lan_manager.types.User import User
class EditProfilePage(Component):
@staticmethod
def optional_date_to_str(d: Optional[date]) -> str:
if not d:
return ""
return d.strftime("%d.%m.%Y")
@event.on_populate
async def on_populate(self) -> None:
await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - Profil bearbeiten")
def on_email_changed(self, change_event: TextInputChangeEvent) -> None:
try:
validate_email(change_event.text, check_deliverability=False)
self.email_input.is_valid = True
except EmailNotValidError:
self.email_input.is_valid = False
def on_birthday_changed(self, change_event: TextInputChangeEvent) -> None:
if len(change_event.text) == 0:
self.birthday_input.is_valid = True
return
try:
day, month, year = change_event.text.split(".")
year = int(year)
if year < 1900 or year > datetime.now().year - 12:
raise ValueError
date(day=int(day), month=int(month), year=year)
self.birthday_input.is_valid = True
except (ValueError, TypeError, IndexError):
self.birthday_input.is_valid = False
async def upload_new_pfp(self) -> None:
try:
new_pfp = await self.session.file_chooser(file_extensions=("png", "jpg", "jpeg"), multiple=False)
except NoFileSelectedError:
return
if new_pfp.size_in_bytes > 2 * 1_000_000:
await self.display_save_result_animation(False, optional_text="Bild zu groß! (> 2MB)")
return
image_data = await new_pfp.read_bytes()
self.session[UserService].set_profile_picture(self.session[SessionStorage].user_id, image_data)
self.pfp_image_container.image = image_data
await self.display_save_result_animation(True)
async def display_save_result_animation(self, success: bool, optional_text: Optional[str] = None) -> None:
self.saved_text.text = ""
if success:
self.saved_text.style = TextStyle(
fill=self.session.theme.success_color,
font_size=0.9
)
t = "Gespeichert!" if not optional_text else optional_text
for c in t:
self.saved_text.text = self.saved_text.text + c
await self.saved_text.force_refresh()
await sleep(0.08)
else:
self.saved_text.style = TextStyle(
fill=self.session.theme.danger_color,
font_size=0.9
)
t = "Fehler!" if not optional_text else optional_text
for c in t:
self.saved_text.text = self.saved_text.text + c
await self.saved_text.force_refresh()
await sleep(0.08)
async def on_save_pressed(self) -> None:
if not all((self.email_input.is_valid, self.birthday_input.is_valid)):
await self.display_save_result_animation(False)
return
if len(self.new_pw_1_input.text.strip()) > 0:
if self.new_pw_1_input.text.strip() != self.new_pw_2_input.text.strip():
await self.display_save_result_animation(False)
return
user: User = self.session[UserService].get_user(self.session[SessionStorage].user_id)
user.user_mail = self.email_input.text
if len(self.birthday_input.text) == 0:
user.user_birth_day = None
else:
day, month, year = self.birthday_input.text.split(".")
user.user_birth_day = date(day=int(day), month=int(month), year=int(year))
user.user_first_name = self.first_name_input.text
user.user_last_name = self.last_name_input.text
if len(self.new_pw_1_input.text.strip()) > 0:
user.user_password = sha256(self.new_pw_1_input.text.encode(encoding="utf-8")).hexdigest()
self.session[UserService].update_user(user)
await self.display_save_result_animation(True)
def build(self) -> Component:
user = self.session[UserService].get_user(self.session[SessionStorage].user_id)
pfp = self.session[UserService].get_profile_picture(user.user_id)
self.saved_text = Text(
"",
margin_top=2,
margin_bottom=1,
align_x=0.1
)
self.email_input = TextInput(
label="E-Mail Adresse",
text=user.user_mail,
margin_left=1,
margin_right=1,
margin_bottom=1,
grow_x=True,
on_change=self.on_email_changed
)
self.first_name_input = TextInput(
label="Vorname",
text=user.user_first_name,
margin_left=1,
margin_right=1,
grow_x=True
)
self.last_name_input = TextInput(
label="Nachname",
text=user.user_last_name,
margin_right=1,
grow_x=True
)
self.birthday_input = TextInput(
label="Geburtstag (TT.MM.JJJJ)",
text=self.optional_date_to_str(user.user_birth_day),
margin_left=1,
margin_right=1,
margin_bottom=1,
grow_x=True,
on_change=self.on_birthday_changed
)
self.new_pw_1_input = TextInput(
label="Neues Passwort setzen",
text="",
margin_left=1,
margin_right=1,
margin_bottom=1,
grow_x=True,
is_secret=True
)
self.new_pw_2_input = TextInput(
label="Neues Passwort wiederholen",
text="",
margin_left=1,
margin_right=1,
margin_bottom=1,
grow_x=True,
is_secret=True
)
self.pfp_image_container = Image(
from_root("src/ez_lan_manager/assets/img/anon_pfp.png") if pfp is None else pfp,
align_x=0.5,
min_width=10,
min_height=10,
margin_top=1,
margin_bottom=1
)
return BasePage(
content=Column(
MainViewContentBox(
content=Column(
self.pfp_image_container,
Button(
content=Text(
"Neues Bild hochladen",
style=TextStyle(fill=Color.from_hex("02dac5"), font_size=0.9)
),
align_x=0.5,
margin_bottom=1,
shape="rectangle",
style="major",
color="primary",
on_press=self.upload_new_pfp
),
Row(
TextInput(label="Deine User-ID", text=user.user_id, is_sensitive=False, margin_left=1, grow_x=False),
TextInput(label="Dein Nickname", text=user.user_name, is_sensitive=False, margin_left=1, margin_right=1, grow_x=True),
margin_bottom=1
),
self.email_input,
Row(
self.first_name_input,
self.last_name_input,
margin_bottom=1
),
self.birthday_input,
self.new_pw_1_input,
self.new_pw_2_input,
Row(
self.saved_text,
Button(
content=Text(
"Speichern",
style=TextStyle(fill=self.session.theme.success_color, font_size=0.9),
align_x=0.2
),
align_x=0.9,
margin_top=2,
margin_bottom=1,
shape="rectangle",
style="major",
color="primary",
on_press=self.on_save_pressed
),
)
)
),
align_y=0,
)
)

View File

@ -2,4 +2,5 @@ from .BasePage import BasePage
from .NewsPage import NewsPage from .NewsPage import NewsPage
from .PlaceholderPage import PlaceholderPage from .PlaceholderPage import PlaceholderPage
from .Logout import LogoutPage from .Logout import LogoutPage
from.Account import AccountPage from .Account import AccountPage
from .EditProfile import EditProfilePage