diff options
| author | ivarlovlie <git@ivarlovlie.no> | 2022-06-06 15:48:53 +0200 |
|---|---|---|
| committer | ivarlovlie <git@ivarlovlie.no> | 2022-06-06 15:48:53 +0200 |
| commit | 18c458d91ca5e7187ffb3615fca8970fc6e4ca65 (patch) | |
| tree | fde7f844b4d212d3892da2f72a4cfcccc56186c8 /apps/web-shared/src | |
| parent | 44a95927edb532f8982cf24c03d9fdd129016bd6 (diff) | |
| download | greatoffice-18c458d91ca5e7187ffb3615fca8970fc6e4ca65.tar.xz greatoffice-18c458d91ca5e7187ffb3615fca8970fc6e4ca65.zip | |
feat: More work on portal
Diffstat (limited to 'apps/web-shared/src')
| -rw-r--r-- | apps/web-shared/src/components/breadcrumb/bread.svelte | 9 | ||||
| -rw-r--r-- | apps/web-shared/src/components/breadcrumb/crumb.svelte | 22 | ||||
| -rw-r--r-- | apps/web-shared/src/components/breadcrumb/index.ts | 7 | ||||
| -rw-r--r-- | apps/web-shared/src/components/link-card.svelte | 47 | ||||
| -rw-r--r-- | apps/web-shared/src/components/menu/menu.svelte | 2 | ||||
| -rw-r--r-- | apps/web-shared/src/components/theme-switcher.svelte | 71 | ||||
| -rw-r--r-- | apps/web-shared/src/components/user-menu.svelte | 99 | ||||
| -rw-r--r-- | apps/web-shared/src/lib/helpers.ts | 4 | ||||
| -rw-r--r-- | apps/web-shared/src/lib/session.ts | 8 | ||||
| -rw-r--r-- | apps/web-shared/src/styles/components/auto-sized-grid.scss | 56 | ||||
| -rw-r--r-- | apps/web-shared/src/styles/components/breadcrumbs.scss | 18 | ||||
| -rw-r--r-- | apps/web-shared/src/styles/components/link-card.scss | 56 | ||||
| -rw-r--r-- | apps/web-shared/src/styles/components/user-menu.scss | 8 |
13 files changed, 379 insertions, 28 deletions
diff --git a/apps/web-shared/src/components/breadcrumb/bread.svelte b/apps/web-shared/src/components/breadcrumb/bread.svelte new file mode 100644 index 0000000..4cf0698 --- /dev/null +++ b/apps/web-shared/src/components/breadcrumb/bread.svelte @@ -0,0 +1,9 @@ +<script lang="ts"> + export type sizes = "big"|"small"; + export let size: sizes = "small"; +</script> +<nav class="breadcrumbs {size === 'small' ? 'text-sm' : 'text-lg'}"> + <ol class="flex flex-wrap gap-xxs"> + <slot></slot> + </ol> +</nav> diff --git a/apps/web-shared/src/components/breadcrumb/crumb.svelte b/apps/web-shared/src/components/breadcrumb/crumb.svelte new file mode 100644 index 0000000..7621de6 --- /dev/null +++ b/apps/web-shared/src/components/breadcrumb/crumb.svelte @@ -0,0 +1,22 @@ +<script> + export let name; + export let withArrow = false; + export let isLink = false; +</script> +<li class="breadcrumbs__item"> + <span class="color-inherit {isLink ? 'cursor-pointer color-primary-light' : ''}" + on:click>{name}</span> + {#if withArrow} + <svg class="icon margin-left-xxxs color-contrast-low" + aria-hidden="true" + viewBox="0 0 16 16"> + <polyline fill="none" + stroke="currentColor" + stroke-width="1" + stroke-linecap="round" + stroke-linejoin="round" + stroke-miterlimit="10" + points="6.5,3.5 11,8 6.5,12.5 "></polyline> + </svg> + {/if} +</li> diff --git a/apps/web-shared/src/components/breadcrumb/index.ts b/apps/web-shared/src/components/breadcrumb/index.ts new file mode 100644 index 0000000..485ed7b --- /dev/null +++ b/apps/web-shared/src/components/breadcrumb/index.ts @@ -0,0 +1,7 @@ +import Bread from "./bread.svelte"; +import Crumb from "./crumb.svelte"; + +export { + Bread, + Crumb +}; diff --git a/apps/web-shared/src/components/link-card.svelte b/apps/web-shared/src/components/link-card.svelte new file mode 100644 index 0000000..0c15a53 --- /dev/null +++ b/apps/web-shared/src/components/link-card.svelte @@ -0,0 +1,47 @@ +<script> + export let text = "View"; + export let name; + export let description = null; + export let href = null; + export let target; + export let title = null; +</script> + +<a class="link-card flex flex-column bg-light cursor-pointer radius-md {$$restProps.class??''}" + {href} + {target} + {title} + on:click + aria-label="Link label"> + <div class="padding-md"> + <div class="flex flex-wrap gap-xs items-center"> + <slot name="icon"></slot> + <div class="line-height-xs"> + <p class="text-lg font-semibold color-contrast-higher">{name}</p> + {#if description} + <p class="color-contrast-low margin-top-xxxs">{description}</p> + {/if} + </div> + </div> + </div> + <div class="link-card__footer margin-top-auto border-top border-contrast-lower"> + <p class="text-sm">{text}</p> + <div> + <svg class="icon icon--sm" + viewBox="0 0 24 24"> + <g fill="none" + stroke="currentColor" + stroke-linecap="round" + stroke-linejoin="round" + stroke-width="2"> + <line x1="3" + y1="12" + x2="21" + y2="12"/> + <polyline points="15 6 21 12 15 18"/> + </g> + </svg> + </div> + </div> +</a> + diff --git a/apps/web-shared/src/components/menu/menu.svelte b/apps/web-shared/src/components/menu/menu.svelte index 33b1160..33517ab 100644 --- a/apps/web-shared/src/components/menu/menu.svelte +++ b/apps/web-shared/src/components/menu/menu.svelte @@ -1,7 +1,7 @@ <script lang="ts"> import {random_string} from "$shared/lib/helpers"; - export let id = "__menu_" + random_string(3); + export const id = "__menu_" + random_string(3); export let trigger: HTMLElement; export let show = false; diff --git a/apps/web-shared/src/components/theme-switcher.svelte b/apps/web-shared/src/components/theme-switcher.svelte index 26ae507..d0a43b3 100644 --- a/apps/web-shared/src/components/theme-switcher.svelte +++ b/apps/web-shared/src/components/theme-switcher.svelte @@ -42,7 +42,8 @@ } </script> -<div class="ld-switch" data-theme-switcher-element> +<div class="ld-switch" + data-theme-switcher-element> <button class="reset ld-switch-btn" on:click={() => show =!show}> <span class="sr-only">{selection}</span> @@ -64,39 +65,46 @@ </svg> {:else if selection === "light"} <svg class="icon ld-switch-btn__icon" - viewBox="0 0 20 20"> - <title>light-auto</title> + viewBox="0 0 20 20"><title>light</title> <g fill="currentColor"> - <path d="M10 14a4 4 0 1 1 3.465-6" - fill-opacity=".2" + <circle cx="10" + cy="10" + r="4" + fill-opacity=".2" + stroke="currentColor" + stroke-linecap="round" + stroke-linejoin="round" + stroke-width="2"></circle> + <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" - stroke-width="2"></path> + stroke-width="2" + d="M10 1v1.5"></path> <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" - d="M12 18l2.5-7h1l2.5 7"></path> + d="M16.364 3.636l-1.061 1.061"></path> <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" - d="M12.714 16h4.572"></path> + d="M19 10h-1.5"></path> <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" - d="M10 1v1.5"></path> + d="M16.364 16.364l-1.061-1.061"></path> <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" - d="M16.364 3.636l-1.061 1.061"></path> + d="M10 19v-1.5"></path> <path fill="none" stroke="currentColor" stroke-linecap="round" @@ -119,9 +127,14 @@ </svg> {:else } <svg class="icon ld-switch-btn__icon" - viewBox="0 0 20 20"> - <title>dark-auto</title> + viewBox="0 0 20 20"><title>light-auto</title> <g fill="currentColor"> + <path d="M10 14a4 4 0 1 1 3.465-6" + fill-opacity=".2" + stroke="currentColor" + stroke-linecap="round" + stroke-linejoin="round" + stroke-width="2"></path> <path fill="none" stroke="currentColor" stroke-linecap="round" @@ -134,15 +147,36 @@ stroke-linejoin="round" stroke-width="2" d="M12.714 16h4.572"></path> - <path d="M12.146 10.159A2.5 2.5 0 0 1 14.5 8.5h1a2.5 2.5 0 0 1 1.412.441 7 7 0 0 0-4.948-5.657c.021.237.036.474.036.716a8 8 0 0 1-8 8c-.242 0-.479-.015-.716-.036a6.99 6.99 0 0 0 6.427 5.012z" - fill-opacity=".2"></path> - <path d="M16.71 8a7.015 7.015 0 0 0-4.746-4.716c.021.237.036.474.036.716a8 8 0 0 1-8 8c-.242 0-.479-.015-.716-.036A7.006 7.006 0 0 0 9 16.929" - fill="none" + <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" - stroke-width="2"></path> - <path d="M7 4a.979.979 0 0 1-1-1 1 1 0 0 0-2 0 .979.979 0 0 1-1 1 1 1 0 0 0 0 2 .979.979 0 0 1 1 1 1 1 0 0 0 2 0 .979.979 0 0 1 1-1 1 1 0 0 0 0-2z"></path> + stroke-width="2" + d="M10 1v1.5"></path> + <path fill="none" + stroke="currentColor" + stroke-linecap="round" + stroke-linejoin="round" + stroke-width="2" + d="M16.364 3.636l-1.061 1.061"></path> + <path fill="none" + stroke="currentColor" + stroke-linecap="round" + stroke-linejoin="round" + stroke-width="2" + d="M3.636 16.364l1.061-1.061"></path> + <path fill="none" + stroke="currentColor" + stroke-linecap="round" + stroke-linejoin="round" + stroke-width="2" + d="M1 10h1.5"></path> + <path fill="none" + stroke="currentColor" + stroke-linecap="round" + stroke-linejoin="round" + stroke-width="2" + d="M3.636 3.636l1.061 1.061"></path> </g> </svg> {/if} @@ -371,7 +405,6 @@ <figure class="radius-md inner-glow" on:click={() => change("system")}> <svg id="Layer_1" - class="block radius-inherit" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="70" diff --git a/apps/web-shared/src/components/user-menu.svelte b/apps/web-shared/src/components/user-menu.svelte new file mode 100644 index 0000000..c0195f4 --- /dev/null +++ b/apps/web-shared/src/components/user-menu.svelte @@ -0,0 +1,99 @@ +<script> + import {onMount} from "svelte"; + import {Menu, MenuItem, MenuItemSeparator} from "./menu"; + + let userMenuTrigger; + let showUserMenu = false; + + export let avatar = ""; + export let name; + export let secondary = ""; + let userMenuId; + + onMount(() => { + userMenuTrigger = document.getElementById("open-user-menu"); + }); +</script> + +<button class="reset user-menu-control" + id="open-user-menu" + aria-controls="{userMenuId}" + on:click={() => showUserMenu = true}> + {#if avatar} + <figure class="user-menu-control__img-wrapper radius-50%"> + <img class="user-menu-control__img" + src="{avatar}" + alt="User picture"> + </figure> + {/if} + + <div class="margin-x-xs user-menu__meta"> + <p class="user-menu__meta-title text-sm line-height-1 padding-y-xxxxs font-semibold color-contrast-higher text-truncate">{name}</p> + {#if secondary} + <p class="text-xs color-contrast-medium line-height-1 padding-bottom-xxxxs">{secondary}</p> + {/if} + </div> + + <svg class="icon icon--xxs" + aria-hidden="true" + viewBox="0 0 12 12"> + <polyline points="1 4 6 9 11 4" + fill="none" + stroke="currentColor" + stroke-linecap="round" + stroke-linejoin="round" + stroke-width="2"/> + </svg> +</button> + +<Menu trigger={userMenuTrigger} + bind:id={userMenuId} + bind:show="{showUserMenu}"> + <div slot="options"> + <MenuItem> + <svg class="icon menu__icon" + aria-hidden="true" + viewBox="0 0 16 16"> + <circle cx="8" + cy="3.5" + r="3.5"/> + <path d="M14.747,14.15a6.995,6.995,0,0,0-13.494,0A1.428,1.428,0,0,0,1.5,15.4a1.531,1.531,0,0,0,1.209.6H13.288a1.531,1.531,0,0,0,1.209-.6A1.428,1.428,0,0,0,14.747,14.15Z"/> + </svg> + <span>Profile</span> + + </MenuItem> + + <MenuItem> + <svg class="icon menu__icon" + aria-hidden="true" + viewBox="0 0 16 16"> + <g fill="currentColor"> + <path d="M15.135,6.784c-1.303-0.326-1.921-1.818-1.23-2.969c0.322-0.536,0.225-0.998-0.094-1.316l-0.31-0.31 c-0.318-0.318-0.78-0.415-1.316-0.094c-1.152,0.691-2.644,0.073-2.969-1.23C9.065,0.258,8.669,0,8.219,0H7.781 c-0.45,0-0.845,0.258-0.997,0.865c-0.326,1.303-1.818,1.921-2.969,1.23C3.279,1.773,2.816,1.87,2.498,2.188l-0.31,0.31 C1.87,2.816,1.773,3.279,2.095,3.815c0.691,1.152,0.073,2.644-1.23,2.969C0.26,6.935,0,7.33,0,7.781v0.438 c0,0.45,0.258,0.845,0.865,0.997c1.303,0.326,1.921,1.818,1.23,2.969c-0.322,0.536-0.225,0.998,0.094,1.316l0.31,0.31 c0.319,0.319,0.782,0.415,1.316,0.094c1.152-0.691,2.644-0.073,2.969,1.23C6.935,15.742,7.331,16,7.781,16h0.438 c0.45,0,0.845-0.258,0.997-0.865c0.326-1.303,1.818-1.921,2.969-1.23c0.535,0.321,0.997,0.225,1.316-0.094l0.31-0.31 c0.318-0.318,0.415-0.78,0.094-1.316c-0.691-1.152-0.073-2.644,1.23-2.969C15.742,9.065,16,8.669,16,8.219V7.781 C16,7.33,15.74,6.935,15.135,6.784z M8,11c-1.657,0-3-1.343-3-3s1.343-3,3-3s3,1.343,3,3S9.657,11,8,11z"></path> + </g> + </svg> + <span>Settings</span> + </MenuItem> + + <MenuItem> + <svg class="icon menu__icon" + aria-hidden="true" + viewBox="0 0 16 16"> + <circle cx="10.5" + cy="2.5" + r="2.5"/> + <circle cx="5.5" + cy="6.5" + r="2.5"/> + <path d="M15.826,10.124A5.455,5.455,0,0,0,9.46,6.107,3.932,3.932,0,0,1,9.5,6.5,3.97,3.97,0,0,1,8.452,9.176,6.963,6.963,0,0,1,11.539,12h2.829a1.5,1.5,0,0,0,1.458-1.876Z"/> + <path d="M10.826,14.124a5.5,5.5,0,0,0-10.652,0A1.5,1.5,0,0,0,1.632,16H9.368a1.5,1.5,0,0,0,1.458-1.876Z"/> + </svg> + <span>Team</span> + </MenuItem> + + <MenuItemSeparator/> + + <MenuItem danger="true" on:click={() => logout_user()}> + Logout + </MenuItem> + </div> +</Menu> diff --git a/apps/web-shared/src/lib/helpers.ts b/apps/web-shared/src/lib/helpers.ts index f2d0cca..4da8254 100644 --- a/apps/web-shared/src/lib/helpers.ts +++ b/apps/web-shared/src/lib/helpers.ts @@ -51,9 +51,7 @@ export function get_cookie(name) { } export function set_cookie(name, value, baseDomain = window.location.host) { - let asdf = name + "=" + encodeURIComponent(value) + (baseDomain ? ";domain=" + baseDomain : ""); - console.log(asdf); - document.cookie = asdf; + document.cookie = name + "=" + encodeURIComponent(value) + (baseDomain ? ";domain=" + baseDomain : ""); } export function unwrap_date_time_from_entry(entry: TimeEntryDto): UnwrappedEntryDateTime { diff --git a/apps/web-shared/src/lib/session.ts b/apps/web-shared/src/lib/session.ts index 4f40a17..f729687 100644 --- a/apps/web-shared/src/lib/session.ts +++ b/apps/web-shared/src/lib/session.ts @@ -1,5 +1,5 @@ import {Temporal} from "@js-temporal/polyfill"; -import {get_profile_for_active_check} from "./api/user"; +import {get_profile_for_active_check, logout} from "./api/user"; import {is_guid, session_storage_get_json, session_storage_set_json} from "./helpers"; import {SECONDS_BETWEEN_SESSION_CHECK, StorageKeys} from "./configuration"; import type {ISession} from "$shared/lib/models/ISession"; @@ -21,6 +21,12 @@ export async function is_active(forceRefresh: boolean = false): Promise<boolean> } } +export async function end_session(cb: Function): Promise<void> { + await logout(); + clear_session_data(); + cb(); +} + async function call_api(): Promise<boolean> { console.log("Getting profile data while checking session state"); try { diff --git a/apps/web-shared/src/styles/components/auto-sized-grid.scss b/apps/web-shared/src/styles/components/auto-sized-grid.scss new file mode 100644 index 0000000..a3b1be5 --- /dev/null +++ b/apps/web-shared/src/styles/components/auto-sized-grid.scss @@ -0,0 +1,56 @@ +@use '../base' as *; + +/* -------------------------------- + +File#: _1_auto-sized-grid +Title: Auto Sized Grid +Descr: A grid layout based on CSS Grid where the columns are automatically created according to a min-width value +Usage: codyhouse.co/license + +-------------------------------- */ + +.grid-auto-xs, .grid-auto-sm, .grid-auto-md, .grid-auto-lg, .grid-auto-xl { + display: grid; + gap: var(--gap-y, 0px) var(--gap-x, 0px); + grid-template-columns: repeat(auto-fit, minmax(var(--col-min-width), 1fr)); // auto add new cols +} + +.grid-auto-xs { + --col-min-width: 8rem; +} + +.grid-auto-sm { + --col-min-width: 10rem; +} + +.grid-auto-md { + --col-min-width: 15rem; +} + +.grid-auto-lg { + --col-min-width: 20rem; +} + +.grid-auto-xl { + --col-min-width: 25rem; +} + +@each $breakpoint, $value in $breakpoints { + @include breakpoint(#{$breakpoint}) { + .grid-auto-xs\@#{$breakpoint} { + --col-min-width: 8rem; + } + .grid-auto-sm\@#{$breakpoint} { + --col-min-width: 10rem; + } + .grid-auto-md\@#{$breakpoint} { + --col-min-width: 15rem; + } + .grid-auto-lg\@#{$breakpoint} { + --col-min-width: 20rem; + } + .grid-auto-xl\@#{$breakpoint} { + --col-min-width: 25rem; + } + } +} diff --git a/apps/web-shared/src/styles/components/breadcrumbs.scss b/apps/web-shared/src/styles/components/breadcrumbs.scss new file mode 100644 index 0000000..45bf7c6 --- /dev/null +++ b/apps/web-shared/src/styles/components/breadcrumbs.scss @@ -0,0 +1,18 @@ +@use '../base' as *; + +/* -------------------------------- + +File#: _1_breadcrumbs +Title: Breadcrumbs +Descr: List of links to help the user move within website structure +Usage: codyhouse.co/license + +-------------------------------- */ + +.breadcrumbs {} + +.breadcrumbs__item { + display: inline-block; // flex fallback + display: inline-flex; + align-items: center; +} diff --git a/apps/web-shared/src/styles/components/link-card.scss b/apps/web-shared/src/styles/components/link-card.scss new file mode 100644 index 0000000..dad4f98 --- /dev/null +++ b/apps/web-shared/src/styles/components/link-card.scss @@ -0,0 +1,56 @@ +@use '../base' as *; + +/* -------------------------------- + +File#: _1_link-card +Title: Link Card +Descr: Link card for app UI +Usage: codyhouse.co/license + +-------------------------------- */ + +.link-card { + text-decoration: none; + color: inherit; + box-shadow: var(--inner-glow), var(--shadow-xs); + + &:hover { + box-shadow: var(--inner-glow), var(--shadow-sm); + } +} + +.link-card__footer { + position: relative; + overflow: hidden; + height: 60px; + + > * { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + } + + > *:last-child { + transform: translateY(100%); + opacity: 0; + } +} + +.link-card:hover { + .link-card__footer { + > *:first-child { + transform: translateY(-100%); + opacity: 0; + } + + > *:last-child { + transform: translateY(0); + opacity: 1; + } + } +} diff --git a/apps/web-shared/src/styles/components/user-menu.scss b/apps/web-shared/src/styles/components/user-menu.scss index 1b5c1d5..416655f 100644 --- a/apps/web-shared/src/styles/components/user-menu.scss +++ b/apps/web-shared/src/styles/components/user-menu.scss @@ -42,7 +42,7 @@ Usage: codyhouse.co/license width: var(--profile-figure-size); height: var(--profile-figure-size); position: relative; - transition: opacity 0.2s; + //transition: opacity 0.2s; &::after { content: ''; @@ -61,7 +61,7 @@ Usage: codyhouse.co/license opacity: 0; transform: scale(0.8); - transition: all 0.2s; + //transition: all 0.2s; } } @@ -73,9 +73,9 @@ Usage: codyhouse.co/license } .user-menu__meta { - max-width: 100px; + //max-width: 100px; } .user-menu__meta-title { - transition: color 0.2s; + //transition: color 0.2s; } |
