add new sveltekit frontend
This commit is contained in:
		
						commit
						fc4334932a
					
				
					 40 changed files with 3802 additions and 0 deletions
				
			
		
							
								
								
									
										34
									
								
								frontend/src/routes/nav/Logo.svelte
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								frontend/src/routes/nav/Logo.svelte
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| 
		 After Width: | Height: | Size: 11 KiB  | 
							
								
								
									
										12
									
								
								frontend/src/routes/nav/NavItem.svelte
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								frontend/src/routes/nav/NavItem.svelte
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
<script lang="ts">
 | 
			
		||||
  export let href: string;
 | 
			
		||||
  export let plain: boolean = false;
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
{#if plain}
 | 
			
		||||
  <a {href} class="hover:text-sky-500 dark:hover:text-sky-400"><slot /></a>
 | 
			
		||||
{:else}
 | 
			
		||||
  <li>
 | 
			
		||||
    <a {href} class="hover:text-sky-500 dark:hover:text-sky-400"><slot /></a>
 | 
			
		||||
  </li>
 | 
			
		||||
{/if}
 | 
			
		||||
							
								
								
									
										101
									
								
								frontend/src/routes/nav/Navigation.svelte
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								frontend/src/routes/nav/Navigation.svelte
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,101 @@
 | 
			
		|||
<script lang="ts">
 | 
			
		||||
  import { onMount } from "svelte";
 | 
			
		||||
  import { browser } from "$app/environment";
 | 
			
		||||
 | 
			
		||||
  import {
 | 
			
		||||
    Collapse,
 | 
			
		||||
    Icon,
 | 
			
		||||
    Nav,
 | 
			
		||||
    Navbar,
 | 
			
		||||
    NavbarBrand,
 | 
			
		||||
    NavbarToggler,
 | 
			
		||||
    NavItem,
 | 
			
		||||
    NavLink,
 | 
			
		||||
  } from "sveltestrap";
 | 
			
		||||
 | 
			
		||||
  import Logo from "./Logo.svelte";
 | 
			
		||||
  import { userStore, themeStore } from "$lib/store";
 | 
			
		||||
  import { ErrorCode, type APIError, type MeUser } from "$lib/api/entities";
 | 
			
		||||
  import { apiFetch } from "$lib/api/fetch";
 | 
			
		||||
 | 
			
		||||
  let theme: string;
 | 
			
		||||
  let currentUser: MeUser | null;
 | 
			
		||||
  let showMenu: boolean = false;
 | 
			
		||||
 | 
			
		||||
  $: currentUser = $userStore;
 | 
			
		||||
  $: theme = $themeStore;
 | 
			
		||||
 | 
			
		||||
  onMount(() => {
 | 
			
		||||
    const localUser = localStorage.getItem("pronouns-user");
 | 
			
		||||
    userStore.set(localUser ? JSON.parse(localUser) : null);
 | 
			
		||||
 | 
			
		||||
    const token = localStorage.getItem("pronouns-token");
 | 
			
		||||
    if (token) {
 | 
			
		||||
      apiFetch<MeUser>("/users/@me", { token })
 | 
			
		||||
        .then((user) => {
 | 
			
		||||
          userStore.set(user);
 | 
			
		||||
          localStorage.setItem("pronouns-user", JSON.stringify(user));
 | 
			
		||||
        })
 | 
			
		||||
        .catch((e) => {
 | 
			
		||||
          console.log("getting /users/@me:", e);
 | 
			
		||||
 | 
			
		||||
          if (
 | 
			
		||||
            (e as APIError).code == ErrorCode.InvalidToken ||
 | 
			
		||||
            (e as APIError).code == ErrorCode.Forbidden
 | 
			
		||||
          ) {
 | 
			
		||||
            localStorage.removeItem("pronouns-token");
 | 
			
		||||
            localStorage.removeItem("pronouns-user");
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  $: updateTheme(theme);
 | 
			
		||||
 | 
			
		||||
  const updateTheme = (newTheme: string) => {
 | 
			
		||||
    if (!browser) return;
 | 
			
		||||
 | 
			
		||||
    document.documentElement.setAttribute("data-bs-theme", newTheme);
 | 
			
		||||
    localStorage.setItem("pronouns-theme", newTheme);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const toggleTheme = () => {
 | 
			
		||||
    themeStore.set(theme === "dark" ? "light" : "dark")
 | 
			
		||||
  };
 | 
			
		||||
  const toggleMenu = () => {
 | 
			
		||||
    showMenu = !showMenu;
 | 
			
		||||
  };
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<Navbar
 | 
			
		||||
  color={theme === "dark" ? "dark" : "light"}
 | 
			
		||||
  light={theme !== "dark"}
 | 
			
		||||
  dark={theme === "dark"}
 | 
			
		||||
  expand="lg"
 | 
			
		||||
  class="mb-4"
 | 
			
		||||
>
 | 
			
		||||
  <NavbarBrand href="/"><Logo /></NavbarBrand>
 | 
			
		||||
  <NavbarToggler on:click={toggleMenu} />
 | 
			
		||||
  <Collapse isOpen={showMenu} navbar expand="lg">
 | 
			
		||||
    <Nav class="ms-auto" navbar>
 | 
			
		||||
      <NavItem>
 | 
			
		||||
        {#if currentUser}
 | 
			
		||||
          <NavLink href="/@{currentUser.name}">@{currentUser.name}</NavLink>
 | 
			
		||||
          <NavLink href="/settings">Settings</NavLink>
 | 
			
		||||
          <NavLink href="/logout">Log out</NavLink>
 | 
			
		||||
        {:else}
 | 
			
		||||
          <NavLink href="/login">Log in</NavLink>
 | 
			
		||||
        {/if}
 | 
			
		||||
      </NavItem>
 | 
			
		||||
      <NavItem>
 | 
			
		||||
        <NavLink
 | 
			
		||||
          on:click={() => toggleTheme()}
 | 
			
		||||
          title={theme === "dark" ? "Switch to light mode" : "Switch to dark mode"}
 | 
			
		||||
        >
 | 
			
		||||
          <Icon name={theme === "dark" ? "sun" : "moon-stars"} height="24" />
 | 
			
		||||
          {theme === "dark" ? "Light mode" : "Dark mode"}
 | 
			
		||||
        </NavLink>
 | 
			
		||||
      </NavItem>
 | 
			
		||||
    </Nav>
 | 
			
		||||
  </Collapse>
 | 
			
		||||
</Navbar>
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue