diff --git a/colors.jpeg b/colors.jpeg new file mode 100644 index 0000000..39f7ffe Binary files /dev/null and b/colors.jpeg differ diff --git a/ezgg_website/__init__.py b/ezgg_website/__init__.py index 3f94b9b..d42cfa2 100644 --- a/ezgg_website/__init__.py +++ b/ezgg_website/__init__.py @@ -1,27 +1,22 @@ from __future__ import annotations from pathlib import Path -from typing import * # type: ignore import rio from . import pages from . import components as comps -# Define a theme for Rio to use. -# -# You can modify the colors here to adapt the appearance of your app or website. -# The most important parameters are listed, but more are available! You can find -# them all in the docs -# -# https://rio.dev/docs/api/theme theme = rio.Theme.from_colors( primary_color=rio.Color.from_hex("01dffdff"), secondary_color=rio.Color.from_hex("0083ffff"), - light=True, + light=False, ) +async def on_session_start(s: rio.Session) -> None: + await s.set_title("EZ GG e.V.") + # Create the Rio app app = rio.App( name='ezgg-website', @@ -29,10 +24,10 @@ app = rio.App( rio.Page( name="Home", page_url='', - build=pages.SamplePage, + build=pages.Home, ), ], theme=theme, assets_dir=Path(__file__).parent / "assets", + on_session_start=on_session_start ) - diff --git a/ezgg_website/assets/placeholder_logo.png b/ezgg_website/assets/placeholder_logo.png new file mode 100644 index 0000000..c8c1429 Binary files /dev/null and b/ezgg_website/assets/placeholder_logo.png differ diff --git a/ezgg_website/components/__init__.py b/ezgg_website/components/__init__.py index e69de29..44d9816 100644 --- a/ezgg_website/components/__init__.py +++ b/ezgg_website/components/__init__.py @@ -0,0 +1,3 @@ +from .navigation import Navigation +from .header import Header +from .news_post import NewsPost diff --git a/ezgg_website/components/header.py b/ezgg_website/components/header.py new file mode 100644 index 0000000..bdee5d1 --- /dev/null +++ b/ezgg_website/components/header.py @@ -0,0 +1,29 @@ +from pathlib import Path + +import rio +from from_root import from_root + + +class Header(rio.Component): + def build(self) -> rio.Component: + return rio.Column( + rio.Rectangle( + content=rio.Column( + rio.Link( + rio.Image(from_root("ezgg_website/assets/placeholder_logo.png"), align_x=0, width=8), + "/" + ), + margin=1 + ), + fill=self.session.theme.neutral_color, + corner_radius=self.session.theme.corner_radius_medium, + shadow_radius=1, + shadow_color=self.session.theme.shadow_color, + shadow_offset_y=0.2, + ), + align_y=0, + margin_top=1, + margin_left=1, + margin_right=1, + height=4 + ) diff --git a/ezgg_website/components/navigation.py b/ezgg_website/components/navigation.py new file mode 100644 index 0000000..64c85a9 --- /dev/null +++ b/ezgg_website/components/navigation.py @@ -0,0 +1,68 @@ +from dataclasses import dataclass +from pathlib import Path + +import rio +from from_root import from_root + + +@dataclass +class NavigationLink: + text: str + icon: str + target: str + + +NAVIGATION_LINKS = [ + NavigationLink("Start", "material/home", "/"), + NavigationLink("Über den Verein", "material/info", "/about"), + NavigationLink("Mitglieder", "material/groups", "/member"), + NavigationLink("Satzung", "material/contract", "/constitution"), + NavigationLink("Mitglied werden", "material/contract-edit", "/join"), + NavigationLink("Galerie", "material/gallery-thumbnail", "/pics"), + NavigationLink("Impressum", "material/data-info-alert", "/imprint"), + NavigationLink("Datenschutz", "material/privacy-tip", "/privacy") +] + +class Navigation(rio.Component): + @rio.event.on_page_change + async def on_page_change(self) -> None: + await self.force_refresh() + + def build(self) -> rio.Component: + active_page = self.session.active_page_instances[0] + + links = [ + rio.Link( + rio.Button( + rio.Row( + rio.Icon(link_data.icon), + rio.Text(link_data.text), + spacing=0.5, + margin_x=1, + margin_y=0.2, + align_x=0, + ), + style=("major" if active_page.page_url == link_data.target.replace("/", "") else "plain"), + ), + link_data.target, + ) + for link_data in NAVIGATION_LINKS + ] + + return rio.Row( + rio.Rectangle( + content=rio.Column( + *links, + spacing=1, + margin=1, align_x=0 + ), + fill=self.session.theme.neutral_color, + corner_radius=self.session.theme.corner_radius_medium, + shadow_radius=1, + shadow_color=self.session.theme.shadow_color, + shadow_offset_y=0.2, + ), + align_y=0, + margin=1, + margin_top=0 + ) diff --git a/ezgg_website/components/news_post.py b/ezgg_website/components/news_post.py new file mode 100644 index 0000000..091cecd --- /dev/null +++ b/ezgg_website/components/news_post.py @@ -0,0 +1,38 @@ +from pathlib import Path +from typing import Union + +import rio + + +class NewsPost(rio.Component): + def __init__(self, header: str, article_text: Union[str, Path], date: str): + super().__init__() + self.align_y = 0 + self.margin_top = 1 + self.margin_right = 1 + self._header = header + self._date = date + if isinstance(article_text, str): + self._article_text = article_text + elif isinstance(article_text, Path): + with open(article_text, "r") as f: + self._article_text = f.read() + + def build(self) -> rio.Component: + return rio.Rectangle( + content=rio.Column( + rio.Row( + rio.Text(self._header, align_x=0.1, style="heading2"), + rio.Text(self._date, align_x=0.9, style=rio.TextStyle(italic=True)), + margin_top=0.5 + ), + rio.Column( + rio.Markdown(self._article_text, margin=1) + ) + ), + fill=self.session.theme.neutral_color, + corner_radius=self.session.theme.corner_radius_medium, + shadow_radius=1, + shadow_color=self.session.theme.shadow_color, + shadow_offset_y=0.2 + ) diff --git a/ezgg_website/main.py b/ezgg_website/main.py new file mode 100644 index 0000000..b61b4eb --- /dev/null +++ b/ezgg_website/main.py @@ -0,0 +1,5 @@ +from __future__ import annotations +from ezgg_website import app + +if __name__ == "__main__": + app.run_as_web_server(host="0.0.0.0", port=8080) diff --git a/ezgg_website/pages/__init__.py b/ezgg_website/pages/__init__.py index 57ca1b4..2ffe384 100644 --- a/ezgg_website/pages/__init__.py +++ b/ezgg_website/pages/__init__.py @@ -1 +1,2 @@ -from .sample_page import SamplePage +from .home import Home +from .page_builder import build_page diff --git a/ezgg_website/pages/home.py b/ezgg_website/pages/home.py new file mode 100644 index 0000000..8e37651 --- /dev/null +++ b/ezgg_website/pages/home.py @@ -0,0 +1,36 @@ +from __future__ import annotations + +from dataclasses import KW_ONLY, field +from typing import * # type: ignore + +import rio +from from_root import from_root + +from .page_builder import build_page +from .. import components as comps + + +class Home(rio.Component): + def build(self) -> rio.Component: + return build_page(rio.Column( + rio.Rectangle( + content=rio.Markdown("### Willkommen auf der Homepage der EZ GG e.V.", margin=1), + fill=self.session.theme.neutral_color, + corner_radius=self.session.theme.corner_radius_medium, + shadow_radius=1, + shadow_color=self.session.theme.shadow_color, + shadow_offset_y=0.2, + margin_bottom=1, + margin_right=1 + ), + comps.NewsPost( + header="Voll der Fließtext", + article_text=from_root("ezgg_website/assets/demo_article_1.txt"), + date="24.05.2024" + ), + comps.NewsPost( + header="Lorem Ipsum", + article_text=from_root("ezgg_website/assets/demo_article_2.txt"), + date="12.02.1884" + ) + )) diff --git a/ezgg_website/pages/page_builder.py b/ezgg_website/pages/page_builder.py new file mode 100644 index 0000000..01ef13f --- /dev/null +++ b/ezgg_website/pages/page_builder.py @@ -0,0 +1,36 @@ +from __future__ import annotations + + +from dataclasses import KW_ONLY, field +from typing import * # type: ignore + +import rio + +from .. import components as comps + + +def build_page(main_component: rio.Component) -> rio.Component: + return rio.Column( + rio.Row( + comps.Header() + ), + rio.Row( + rio.Column( + comps.Navigation(), + width="natural", + align_y=0, + margin_right=1 + ), + rio.Column( + main_component, + width="grow", + align_y=0 + ), + width="grow", + height="grow" + ), + spacing=2, + margin=0, + width="grow", + height="grow" + ) diff --git a/ezgg_website/pages/sample_page.py b/ezgg_website/pages/sample_page.py deleted file mode 100644 index 5956358..0000000 --- a/ezgg_website/pages/sample_page.py +++ /dev/null @@ -1,27 +0,0 @@ -from __future__ import annotations - -from dataclasses import KW_ONLY, field -from typing import * # type: ignore - -import rio - -from .. import components as comps - -class SamplePage(rio.Component): - """ - This is an example Page. Pages are identical to other Components and only - differ in how they're used. - """ - - def build(self) -> rio.Component: - return rio.Column( - rio.Text("My App", style="heading2"), - rio.Text( - "This is a sample page. Replace it with your own content." - ), - spacing=2, - margin=2, - align_x=0.5, - align_y=0, - ) - diff --git a/rio.toml b/rio.toml index ada93bc..d720725 100644 --- a/rio.toml +++ b/rio.toml @@ -1,6 +1,3 @@ -# This is the configuration file for Rio, -# an easy to use app & web framework for Python. - [app] app_type = "website" # This is either "website" or "app" main_module = "ezgg_website" # The name of your Python module