Skip to content
This repository was archived by the owner on Sep 12, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 1 addition & 5 deletions src/app.css
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/* Write your global styles here, in PostCSS syntax */

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
:root {
--neutral-000: #141414;
Expand All @@ -15,21 +15,17 @@
--neutral-700: #babfbf;
--neutral-800: #d3d9dc;
--neutral-900: #f5f4f4;

--primary-100: #ff5a00;
--primary-200: #ff9d00;
--primary-300: #ffbf00;
--primary-400: #e3ff00;

--accent-1: #22d3ee;
--accent-2: #eb00eb;

--color-primary: var(--primary-100);
--color-background: var(--neutral-900);
--color-off-background: #ffffff;
--color-text: var(--neutral-100);
}

.dark {
--color-primary: var(--primary-100);
--color-background: var(--neutral-100);
Expand Down
102 changes: 100 additions & 2 deletions src/lib/components/header.svelte
Original file line number Diff line number Diff line change
@@ -1,16 +1,58 @@
<script lang="ts">
import ProfilePicture from './profile-picture.svelte';
import { page } from '$app/stores';
import { onMount } from 'svelte';
export let username: string;

const navItems = [{ name: 'Docs', path: '/docs' }];
let closeHamburgerMenu: () => void;
let burger: Element;
let menu: Element;
let closeButton: Element;

onMount(() => {
closeHamburgerMenu = () => {
menu?.classList.add('hidden');
};

burger?.addEventListener('click', () => {
menu?.classList.toggle('hidden');
});

closeButton?.addEventListener('click', closeHamburgerMenu);
});
</script>

<header class="my-8 flex flex-wrap items-center justify-between">
<a href="/">
<img src="/images/hubber.png" class="w-8 object-contain md:w-12" alt="hubber" />
</a>
<div class="flex items-center gap-4 lg:gap-8">
<div class="lg:hidden">
<button
class="navbar-burger flex items-center p-3 text-neutral-900"
bind:this={burger}
data-test-id="hamburger-btn"
>
<svg
class="block h-4 w-4 fill-current dark:hidden"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
color="black"
>
<title>Mobile menu</title>
<path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z" />
</svg>
<svg
class="block hidden h-4 w-4 fill-current dark:block"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<title>Mobile menu</title>
<path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z" />
</svg>
</button>
</div>
<div class="hidden items-center gap-4 lg:flex lg:gap-8">
<ul>
{#each navItems as item}
<li>
Expand All @@ -26,12 +68,68 @@
<ProfilePicture {username} />
{:else}
<a
data-test-id="login-btn"
data-test-id="login-btn-lg"
class="default-transition rounded-xl bg-skin-text px-4 py-2 text-skin-off-background hover:bg-primary-100 dark:bg-skin-text-highlight dark:text-skin-background dark:hover:bg-primary-100"
href="/login">Login</a
>
{/if}
</div>

<!-- hamburger menu for smaller devices(below lg)-->
<div class="navbar-menu absolute z-50 hidden" bind:this={menu}>
<div class="navbar-backdrop fixed inset-0 bg-gray-800 opacity-50" />
<nav
class="fixed top-0 left-0 bottom-0 flex w-5/6 max-w-sm flex-col overflow-y-auto bg-neutral-900 py-6 px-6 dark:bg-neutral-100"
>
<div class="mb-8 flex items-center justify-between">
<a href="/" on:click={closeHamburgerMenu}>
<img src="/images/hubber.png" class="w-8 object-contain md:w-12" alt="hubber" />
</a>
<button class="navbar-close" bind:this={closeButton}>
<svg
class="h-6 w-6 cursor-pointer text-gray-400 text-neutral-900"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
</div>
<div class="flex flex-col items-center gap-4 gap-8 ">
{#if username}
<ProfilePicture {username} />
{/if}
<ul>
{#each navItems as item}
<li>
<a
on:click={closeHamburgerMenu}
class="default-transition text-skin-text-highlight decoration-transparent hover:underline hover:decoration-inherit"
class:active={$page.url.pathname.includes(item.path)}
href={item.path}
>{item.name}
</a>
</li>
{/each}
</ul>
{#if !username}
<a
data-test-id="login-btn"
class="default-transition rounded-xl bg-skin-text px-4 py-2 text-skin-off-background hover:bg-primary-100 dark:bg-skin-text-highlight dark:text-skin-background dark:hover:bg-primary-100"
href="/login"
on:click={closeHamburgerMenu}>Login</a
>
{/if}
</div>
</nav>
</div>
</header>

<style lang="postcss">
Expand Down
23 changes: 22 additions & 1 deletion src/lib/components/profile-picture.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
</script>

<div>
<button on:click={togglePopper}>
<button class="hidden lg:flex" on:click={togglePopper}>
<img
bind:this={root}
class="rounded-full hover:shadow-lg dark:hover:shadow-dark"
Expand Down Expand Up @@ -76,4 +76,25 @@
>
</div>
{/if}
<!-- smaller devices -->
<div
class="flex w-screen max-w-xs flex-col items-center justify-center rounded-xl bg-skin-off-background p-4 lg:hidden"
>
<div class="flex flex-col items-center justify-center gap-4">
<img
class="rounded-full"
alt="Github profile picture of {username}"
src="https://www.github.com/{username}.png"
width="96"
height="96"
/>
<div class="font-semibold">{username}</div>
</div>
<div class="my-2 w-full border-[0.5px] border-skin-text-highlight" />
<a
href="/api/authentication/logout"
class="default-transition underline decoration-primary-100 hover:decoration-transparent"
>Sign out</a
>
</div>
</div>
4 changes: 3 additions & 1 deletion tests/docs/introduction.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
/* eslint-disable @typescript-eslint/no-empty-function */
import { expect, test } from '@playwright/test';

test.fixme('docs header element is active', async ({ page }) => {
test('docs header element is active', async ({ page }) => {
// navigate to the docs landing page /docs
await page.goto('/docs');
// check if the docs link in the page header is having the active class
await expect(page.getByRole('link', { name: 'Docs' })).toHaveClass(/active/);
});

test('Correct Page Heading', async ({ page }) => {
Expand Down
21 changes: 20 additions & 1 deletion tests/login.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,29 @@ test.describe('Login Card', () => {
});

test.describe('Header', () => {
test('Header contains Login Button', async ({ page }) => {
test('Header contains Login Button For Device Width Greater Than lg', async ({ page }) => {
//navigate to the docs page
await page.goto('/docs');

//check if the header contains a link that redirects to the login page
await page.locator('data-test-id=login-btn-lg').click();
await page.waitForLoadState('networkidle');

expect(await page.url()).toContain('/login');
});
});

test.describe('Header', () => {
test.use({
viewport: { width: 600, height: 900 },
});
test('Header contains Login Button In For Device Width Less Than lg', async ({ page }) => {
//navigate to the docs page
await page.goto('/docs');

//opening hamburger menu
await page.locator('data-test-id=hamburger-btn').click();

//check if the header contains a link that redirects to the login page
await page.locator('data-test-id=login-btn').click();
await page.waitForLoadState('networkidle');
Expand Down