Skip to content

Commit

Permalink
Merge pull request #8 from bzr-sys/teams-and-overhaul-ui
Browse files Browse the repository at this point in the history
Add organizations, do a huge UI/UX overhaul
  • Loading branch information
paddyohanlon authored Oct 14, 2024
2 parents a90a780 + 39f14b7 commit 89e928d
Show file tree
Hide file tree
Showing 46 changed files with 2,413 additions and 1,018 deletions.
1,246 changes: 865 additions & 381 deletions package-lock.json

Large diffs are not rendered by default.

Binary file modified public/favicon.ico
Binary file not shown.
110 changes: 34 additions & 76 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
<script setup lang="ts">
import { useKoreroStore } from '@/stores/korero'
import { bzr } from '@/bazaar'
import { RouterLink } from 'vue-router'
import LogoIconSVG from './components/LogoIconSVG.vue'
import { storeToRefs } from 'pinia'
import { computed } from 'vue'
import type { ComputedRef } from 'vue'
import NavBar from './components/NavBar.vue'
import BaseLogin from './components/BaseLogin.vue'
import SideBar from './components/SideBar.vue'
import BaseOnboarding from './components/BaseOnboarding.vue'
const koreroStore = useKoreroStore()
koreroStore.autoSignIn()
Expand All @@ -14,80 +13,39 @@ bzr.onLogin(async () => {
koreroStore.autoSignIn()
})
function login(): void {
bzr.login()
}
function logOut(): void {
bzr.logOut()
}
const { state, orgs, user } = storeToRefs(koreroStore)
const currentOrg: ComputedRef<string> = computed(() => {
if (!state.value) {
return 'Choose org'
}
if (user.value.id === state.value.config.currentTeam) {
return user.value.name
}
const org = orgs.value.filter((o) => o.id === state.value!.config.currentTeam)
if (org.length > 0) {
return org[0].name
}
return 'Switch org'
})
// maybe redirect home if not onboarded
</script>

<template>
<div class="navbar bg-base-100">
<div class="flex-1">
<RouterLink :to="{ name: 'home' }" class="btn btn-ghost text-xl"
><LogoIconSVG width="36px" /> Korero</RouterLink
>
</div>
<div class="flex-none">
<ul class="menu menu-horizontal px-1">
<li v-if="state">
<RouterLink :to="{ name: 'settings' }" class="font-bold">{{ currentOrg }}</RouterLink>
</li>
<!-- <li v-if="koreroStore.authenticated">
<details>
<summary>Menu</summary>
<ul class="bg-base-100 rounded-t-none p-2">
<li><RouterLink :to="{ name: 'home' }">Channels</RouterLink></li>
<li><RouterLink :to="{ name: 'settings' }">Settings</RouterLink></li>
</ul>
</details>
</li> -->
<li v-if="koreroStore.authenticated">
<button @click="logOut">Sign out</button>
</li>
<li v-else>
<button @click="login" class="btn btn-accent btn-sm">Log in with Bazaar</button>
</li>
</ul>
</div>
</div>
<div v-if="koreroStore.authenticated" class="container mx-auto mb-32 p-6">
<RouterView />
</div>
<div v-else>
<div class="text-center px-4 py-24">
<p>Log in with Bazaar to get started</p>
</div>
</div>
<footer class="footer px-8 py-4">
<div class="grid-flow-col items-center">
<LogoIconSVG width="36px" />
<div>
<div>
<strong>&copy; {{ new Date().getFullYear() }} Korero</strong>
</div>
<div>Communicate effectively with your team.</div>
<div
v-if="koreroStore.authenticated"
class="flex flex-col overflow-hidden fixed top-0 right-0 bottom-0 left-0 min-h-[600px]"
>
<NavBar />
<template v-if="!koreroStore.hasCompletedOnboarding">
<BaseOnboarding />
</template>
<template v-if="koreroStore.state">
<div class="flex flex-1">
<SideBar />
<!-- height = 100vh - navbar header height -->
<main class="flex-grow h-[calc(100vh-12*0.25rem)] overflow-hidden">
<div class="px-6 pt-4 pb-16 overflow-y-auto h-full">
<RouterView />
</div>
</main>
</div>
</div>
</footer>
</template>
</div>
<template v-else>
<BaseLogin />
</template>
</template>

<style scoped></style>
<style>
html,
body,
#app {
height: 100%;
}
</style>
19 changes: 19 additions & 0 deletions src/components/AlertSVG.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script setup lang="ts"></script>

<template>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6 shrink-0 stroke-current"
fill="none"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
/>
</svg>
</template>

<style scoped></style>
19 changes: 19 additions & 0 deletions src/components/AnnouncementSVG.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script setup lang="ts">
defineProps<{ width: string }>()
</script>

<template>
<svg
viewBox="0 0 512 512"
xmlns="http://www.w3.org/2000/svg"
:style="`width: ${width}`"
aria-labelledby="announcement-svg-title"
>
<title id="announcement-svg-title">Announcement Icon</title>
<path
d="m378.011 223.207c12.306-8.247 21.13-20.55 25.02-35.069 4.253-15.87 2.096-32.402-6.073-46.551s-21.407-24.283-37.277-28.536c-14.519-3.89-29.586-2.4-42.881 4.134l-34.256-59.333c-7.292-12.631-20.39-19.993-34.932-19.745-14.581.267-27.36 8.12-34.188 21.007-4.794 9.054-9.297 18.459-14.064 28.417-19.429 40.585-41.45 86.585-89.057 114.071l-61.173 35.318c-21.057 12.157-36.14 31.865-42.472 55.494-6.331 23.629-3.123 48.239 9.034 69.295 16.901 29.274 47.671 45.658 79.268 45.658 11.524 0 23.157-2.184 34.269-6.712l42.765 74.072c8.848 15.324 24.952 23.899 41.492 23.899 8.106 0 16.318-2.061 23.829-6.397 11.027-6.367 18.925-16.682 22.238-29.046 3.312-12.364 1.631-25.246-4.736-36.274l-42.08-72.885c44.303-21.062 90.806-17.488 132.209-14.288 11.017.852 21.422 1.656 31.668 2.031 14.554.521 27.766-6.608 35.286-19.104 7.521-12.495 7.658-27.494.366-40.125l-34.256-59.334zm-24.801-86.008c9.42 2.524 17.268 8.521 22.098 16.888 9.325 16.151 4.806 36.551-9.84 47.393l-36.123-62.567c7.477-3.247 15.807-3.874 23.866-1.714zm-258.291 245.175c-22.948-.002-45.3-11.902-57.575-33.164-8.818-15.273-11.14-33.146-6.536-50.325 4.603-17.179 15.55-31.496 30.823-40.314l50.353-29.071 66.414 114.891-50.414 29.107c-10.424 6.018-21.813 8.877-33.064 8.876zm140.487 74.34c-1.584 5.914-5.346 10.838-10.59 13.866-10.896 6.29-24.879 2.545-31.171-8.352l-42.337-73.33 39.522-22.818 42.337 73.33c3.028 5.245 3.823 11.39 2.238 17.304zm155.076-146.942c-2.843 4.724-7.427 7.226-12.953 7.013-9.739-.356-19.898-1.142-30.655-1.973-45.182-3.491-95.984-7.406-146.61 17.451l-66.844-115.635c46.896-31.448 68.916-77.414 88.49-118.301 4.654-9.723 9.051-18.907 13.607-27.511 2.581-4.873 7.039-7.612 12.552-7.712.104-.002.208-.003.312-.003 5.372 0 9.808 2.567 12.513 7.252l129.724 224.689c2.757 4.775 2.71 10.007-.135 14.731zm-32.471-245.435 25.814-44.712c3.452-5.979 11.096-8.028 17.075-4.575 5.979 3.452 8.027 11.097 4.575 17.075l-25.814 44.712c-2.315 4.01-6.517 6.252-10.837 6.252-2.121 0-4.27-.54-6.238-1.677-5.979-3.452-8.027-11.097-4.575-17.075zm116.053 47.166-45.794 26.44c-1.968 1.136-4.118 1.677-6.238 1.677-4.32 0-8.521-2.242-10.837-6.252-3.452-5.979-1.403-13.624 4.575-17.075l45.794-26.44c5.977-3.453 13.623-1.403 17.075 4.575s1.403 13.624-4.575 17.075zm34.45 89.938c0 6.903-5.597 12.5-12.5 12.5h-51.63c-6.903 0-12.5-5.596-12.5-12.5s5.597-12.5 12.5-12.5h51.63c6.903 0 12.5 5.596 12.5 12.5z"
></path>
</svg>
</template>

<style scoped></style>
49 changes: 49 additions & 0 deletions src/components/BaseLogin.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<script setup lang="ts">
import { bzr } from '@/bazaar'
import LogoTextSVG from './LogoTextSVG.vue'
import BazaarLogoIcon from './BazaarLogoIcon.vue'
import HeadingOne from './HeadingOne.vue'
function login(): void {
bzr.login()
}
</script>

<template>
<div class="grid min-h-full grid-rows-[auto_1fr_auto] px-8 max-w-7xl mx-auto">
<header class="sticky flex py-8">
<a href="https://koreroapp.com/">
<LogoTextSVG width="130px" />
</a>
</header>

<main class="text-center py-12">
<HeadingOne>Welcome to Korero</HeadingOne>
<div class="text-lg pt-2 pb-8 opacity-70">To get started, please sign in</div>
<button @click="login" class="btn btn-lg">
<BazaarLogoIcon width="20px" /> Continue with Bazaar
</button>
</main>

<footer class="py-8 opacity-70">
<nav>
<ul
class="flex flex-wrap justify-center text-xs [&>li:not(:first-child)]:before:content-['•'] [&>li:not(:first-child)]:before:px-2 [&>li>a]:whitespace-nowrap"
>
<li><a href="https://koreroapp.com/">Koreroapp.com</a></li>
<li><a href="https://bzr.dev/">Powered by Bazaar</a></li>
<li><a href="https://koreroapp.com/terms/">Terms</a></li>
<li><a href="https://koreroapp.com/privacy/">Privacy</a></li>
<li><a href="https://koreroapp.com/acceptable-use-policy/">Acceptable Use Policy</a></li>
</ul>
</nav>
</footer>
</div>
</template>

<style scoped>
ul > li:not(:first-child):before {
content: '';
padding: 0 2px;
}
</style>
165 changes: 165 additions & 0 deletions src/components/BaseOnboarding.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
<script setup lang="ts">
import { useKoreroStore } from '@/stores/korero'
import HeadingOne from './HeadingOne.vue'
import BazaarLogoIcon from './BazaarLogoIcon.vue'
import { ref, watch } from 'vue'
import { bzr } from '@/bazaar'
import { useRoute, useRouter, type RouteLocationNormalizedLoadedGeneric } from 'vue-router'
import AlertSVG from './AlertSVG.vue'
import { storeToRefs } from 'pinia'
const route = useRoute()
const router = useRouter()
const koreroStore = useKoreroStore()
const { hasCompletedOnboarding, orgs, activeOrgs, user } = storeToRefs(koreroStore)
const START = 'start'
const CREATE_ORG = 'create-org'
const JOIN_ORG = 'join-org'
const USE_ORG = 'use-org'
const currentStep = ref(START)
const noActiveOrgAfterModalClose = ref(false)
function setStepFromRoute(route: RouteLocationNormalizedLoadedGeneric): void {
if (!route.query.step) return
currentStep.value = route.query.step as string
resetNotices()
}
function resetNotices(): void {
noActiveOrgAfterModalClose.value = false
}
// Set step on page load
setStepFromRoute(route)
// Set step interaction
watch(route, setStepFromRoute)
function openOrgModal() {
// @ts-ignore
bzr.orgs.openModal(null, async () => {
resetNotices()
await koreroStore.setOrgs()
if (activeOrgs.value.length > 0) {
router.push({ name: 'home', query: { step: USE_ORG } })
} else {
noActiveOrgAfterModalClose.value = true
}
})
}
function openSocialModal() {
bzr.social.openModal()
}
</script>

<template>
<!-- <ManageWorkspaces /> -->
<div v-if="!hasCompletedOnboarding" class="text-center py-12 px-4 w-[300px] mx-auto">
<HeadingOne>Welcome!</HeadingOne>

<Transition name="slide-fade" mode="out-in">
<!-- Steps -->

<!-- START -->
<div v-if="currentStep === START" class="flex flex-col gap-4">
<div class="text-lg pt-1 pb-6 opacity-70">How will you use Korero?</div>
<div>
<RouterLink
:to="{ name: 'home', query: { step: CREATE_ORG } }"
class="btn btn-lg btn-block"
>Create an organization</RouterLink
>
<!-- <div class="text-xs opacity-70">The organization owns the data</div> -->
</div>
<div>
<RouterLink :to="{ name: 'home', query: { step: JOIN_ORG } }" class="btn btn-lg btn-block"
>Join an organization</RouterLink
>
<!-- <div class="text-xs opacity-70">The organization owns the data</div> -->
</div>
<div>
<button @click="koreroStore.setTeam(user.id)" class="btn btn-md btn-block btn-ghost">
Just for me
</button>
<!-- <div class="text-xs opacity-70">You own the data</div> -->
</div>
</div>

<!-- CREATE_ORG -->
<div v-else-if="currentStep === CREATE_ORG" class="flex flex-col gap-4">
<div class="text-lg pt-1 pb-6 opacity-70">Create a Bazaar organization</div>
<button @click="openOrgModal" class="btn btn-lg">
<BazaarLogoIcon width="20px" /> Manage Organizations
</button>
<div role="alert" class="alert alert-warning" v-if="noActiveOrgAfterModalClose">
<AlertSVG />
<span>Make sure you have at least one organization with an active subscription</span>
</div>
</div>

<!-- JOIN_ORG -->
<div v-else-if="currentStep === JOIN_ORG" class="flex flex-col gap-4">
<div class="text-lg pt-1 pb-6 opacity-70">Search for an organization to join</div>
<button @click="openOrgModal" class="btn btn-lg">
<BazaarLogoIcon width="20px" /> Manage Organizations
</button>
<div role="alert" class="alert alert-warning" v-if="noActiveOrgAfterModalClose">
<AlertSVG />
<span
>Make sure you are a member of at least one organization with an active
subscription</span
>
</div>
</div>

<!-- USE_ORG -->
<div v-else-if="currentStep === USE_ORG">
<div class="text-lg pt-1 pb-6 opacity-70">Select an organization</div>

<ul class="flex flex-col gap-2">
<li v-for="org in activeOrgs" :key="org.id">
<button @click="koreroStore.setTeam(org.primaryTeam.id)" class="btn btn-md btn-block">
<div class="truncate h-[15px]">{{ org.name }}</div>
</button>
</li>
</ul>
</div>
</Transition>
<div class="mt-8">
<RouterLink
v-if="!currentStep || currentStep !== START"
:to="{ name: 'home', query: { step: START } }"
class="btn btn-link"
>Back to start</RouterLink
>
</div>
</div>
</template>

<style scoped>
/*
Enter and leave animations can use different
durations and timing functions.
*/
.slide-fade-enter-active {
transition: all 0.1s ease-out;
}
.slide-fade-leave-active {
transition: all 0.1s ease-out;
}
.slide-fade-enter-from {
transform: translateX(20px);
opacity: 0;
}
.slide-fade-leave-to {
transform: translateX(-20px);
opacity: 0;
}
</style>
Loading

0 comments on commit 89e928d

Please sign in to comment.