yggdrasil/components/
frontend_layout.rs1use dioxus::prelude::*;
7
8use crate::components::footer::Footer;
9use crate::components::header::{Header, SearchIconLink};
10use crate::components::nav::build_nav_items;
11use crate::components::skeletons::archive_skeleton::ArchiveSkeleton;
12use crate::components::skeletons::changelog_skeleton::ChangelogSkeleton;
13use crate::components::skeletons::delayed_skeleton::DelayedSkeleton;
14use crate::components::skeletons::friends_skeleton::FriendsSkeleton;
15use crate::components::skeletons::home_skeleton::HomeSkeleton;
16use crate::components::skeletons::post_detail_skeleton::PostDetailSkeleton;
17use crate::components::skeletons::search_skeleton::SearchSkeleton;
18use crate::components::skeletons::tags_skeleton::TagDetailSkeleton;
19use crate::router::Route;
20use crate::theme::ThemeToggle;
21
22fn route_skeleton(route: &Route) -> Element {
24 match route {
25 Route::HomePage { page } => rsx! {
26 DelayedSkeleton { HomeSkeleton { current_page: (*page).max(1) } }
27 },
28 Route::Archives {} => rsx! {
29 DelayedSkeleton { ArchiveSkeleton {} }
30 },
31 Route::TagDetail { tag } => rsx! {
32 TagDetailSkeleton { tag: tag.clone() }
33 },
34 Route::Friends {} => rsx! {
35 DelayedSkeleton { FriendsSkeleton {} }
36 },
37 Route::Search {} => rsx! {
38 DelayedSkeleton { SearchSkeleton {} }
39 },
40 Route::PostDetail { .. } => rsx! {
41 DelayedSkeleton { PostDetailSkeleton {} }
42 },
43 Route::Changelog {} => rsx! {
44 DelayedSkeleton { ChangelogSkeleton {} }
45 },
46 Route::NotFound { .. } => rsx! {
47 div { class: "py-20 md:py-28" }
48 },
49 _ => rsx! {
50 DelayedSkeleton { HomeSkeleton {} }
51 },
52 }
53}
54
55#[component]
60pub fn FrontendLayout() -> Element {
61 let route = use_route::<Route>();
62 let nav_items = build_nav_items(route.clone());
63 let max_width = "max-w-4xl";
65
66 rsx! {
67 div { class: "min-h-screen flex flex-col bg-paper-theme",
68 Header {
69 max_width,
70 nav_items,
71 right_content: rsx! {
72 SearchIconLink {}
73 ThemeToggle {}
74 },
75 }
76 main { class: "flex-1 w-full {max_width} mx-auto px-6 py-6 md:py-12 overflow-x-clip",
77 SuspenseBoundary { fallback: move |_| route_skeleton(&route), Outlet::<Route> {} }
78 }
79 Footer {}
80 }
81 }
82}