Skip to content
Snippets Groups Projects
Unverified Commit 78a9fffa authored by Mateusz Tyszczak's avatar Mateusz Tyszczak :scroll:
Browse files

Add menu

parent 7ea48447
No related branches found
No related tags found
No related merge requests found
Pipeline #117507 passed
Showing
with 232 additions and 35 deletions
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hive Bridge</title> <title>Hive Bridge</title>
</head> </head>
<body> <body class="dark">
<div id="app"></div> <div id="app"></div>
<script type="module" src="/src/main.ts"></script> <script type="module" src="/src/main.ts"></script>
</body> </body>
......
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
import { ref, onMounted, defineAsyncComponent } from 'vue'; import { ref, onMounted, defineAsyncComponent } from 'vue';
import { useSettingsStore, UsedWallet } from '@/stores/settings.store'; import { useSettingsStore, UsedWallet } from '@/stores/settings.store';
import { useWalletStore } from '@/stores/wallet.store'; import { useWalletStore } from '@/stores/wallet.store';
import AppHeader from '@/components/AppHeader.vue'; import AppSidebar from '@/components/sidebar';
import { SidebarProvider } from '@/components/ui/sidebar';
import ToggleSidebar from './components/sidebar/ToggleSidebar.vue';
const WalletOnboarding = defineAsyncComponent(() => import('@/components/onboarding/index')); const WalletOnboarding = defineAsyncComponent(() => import('@/components/onboarding/index'));
...@@ -27,15 +29,19 @@ const complete = (data: { account: string; wallet: UsedWallet }) => { ...@@ -27,15 +29,19 @@ const complete = (data: { account: string; wallet: UsedWallet }) => {
</script> </script>
<template> <template>
<div id="shadcn-root" class="dark"> <div id="shadcn-root">
<div id="app-main"> <div id="app-main">
<AppHeader/> <SidebarProvider>
<main class="mt-[65px]"> <AppSidebar/>
<RouterView /> <!-- <AppHeader/> -->
</main> <main class="w-full">
<aside v-if="settingsStore.isLoaded && !hasUser" class="fixed inset-0 flex items-center justify-center z-20"> <ToggleSidebar class="m-3" />
<WalletOnboarding @complete="complete" /> <RouterView />
</aside> </main>
<aside v-if="settingsStore.isLoaded && !hasUser" class="fixed inset-0 flex items-center justify-center z-20">
<WalletOnboarding @complete="complete" />
</aside>
</SidebarProvider>
</div> </div>
</div> </div>
</template> </template>
...@@ -43,8 +49,6 @@ const complete = (data: { account: string; wallet: UsedWallet }) => { ...@@ -43,8 +49,6 @@ const complete = (data: { account: string; wallet: UsedWallet }) => {
<style scoped> <style scoped>
#app-main { #app-main {
overflow-y: auto; overflow-y: auto;
height: 100%;
width: 100%;
background: url('/bg.svg') no-repeat center center fixed; background: url('/bg.svg') no-repeat center center fixed;
background-size: cover; background-size: cover;
} }
...@@ -52,8 +56,6 @@ const complete = (data: { account: string; wallet: UsedWallet }) => { ...@@ -52,8 +56,6 @@ const complete = (data: { account: string; wallet: UsedWallet }) => {
#shadcn-root { #shadcn-root {
background-color: hsl(var(--background)); background-color: hsl(var(--background));
color: hsl(var(--foreground)); color: hsl(var(--foreground));
height: 100vh;
width: 100%;
overflow: hidden; overflow: hidden;
font-family: Verdana, sans-serif; font-family: Verdana, sans-serif;
} }
......
...@@ -17,9 +17,6 @@ const logout = () => { ...@@ -17,9 +17,6 @@ const logout = () => {
<header class="fixed top-0 left-0 z-10 bg-black/60 backdrop-blur-sm w-full"> <header class="fixed top-0 left-0 z-10 bg-black/60 backdrop-blur-sm w-full">
<nav class="flex items-center relative sm:justify-center p-4 w-full h-[65px] border-b-[1px] border-white/25"> <nav class="flex items-center relative sm:justify-center p-4 w-full h-[65px] border-b-[1px] border-white/25">
<div class="hidden sm:inline absolute top-[14px] left-[30px]" v-if="hasUser"> <div class="hidden sm:inline absolute top-[14px] left-[30px]" v-if="hasUser">
<Button variant="outline" class="cursor-default" v-if="settingsStore.isLoaded && hasUser">
<span class="font-bold">@{{ settingsStore.settings.account }}</span>
</Button>
</div> </div>
<div class="flex items-center space-x-4"> <div class="flex items-center space-x-4">
<img src="/icon.svg" class="h-8 w-8" /> <img src="/icon.svg" class="h-8 w-8" />
......
<script setup lang="ts">
import { mdiHomeOutline, mdiMessageLockOutline, mdiFileSign, mdiAccountPlusOutline } from "@mdi/js"
import { Sidebar, SidebarContent, SidebarHeader, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarMenu, SidebarMenuButton, SidebarMenuItem } from "@/components/ui/sidebar"
import { useSidebar } from "@/components/ui/sidebar";
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { useSettingsStore, getWalletIcon } from '@/stores/settings.store';
import { computed } from 'vue';
import { Button } from '@/components/ui/button';
const settingsStore = useSettingsStore();
const hasUser = computed(() => settingsStore.settings.account !== undefined);
const logout = () => {
settingsStore.resetSettings();
window.location.reload();
};
const { toggleSidebar, isMobile } = useSidebar();
const items = [
{
title: "Home",
url: "/",
icon: mdiHomeOutline,
},
{
title: "Memo encryption",
url: "/sign/message",
icon: mdiMessageLockOutline,
},
{
title: "Transaction signing",
url: "/sign/transaction",
icon: mdiFileSign,
},
{
title: "Process Account Creation",
url: "/account/create",
icon: mdiAccountPlusOutline,
}
];
</script>
<template>
<Sidebar>
<SidebarHeader class="pb-0">
<div class="flex items-center rounded-lg p-2 mt-1 mx-1 bg-black/40 border" v-if="settingsStore.isLoaded && hasUser">
<Avatar class="w-8 h-8 mr-2">
<AvatarImage src="https://github.com/unovue.png" alt="@unovue" />
<AvatarFallback>{{ settingsStore.settings.account?.slice(0, 2) }}</AvatarFallback>
</Avatar>
<span class="font-bold">@{{ settingsStore.settings.account }}</span>
</div>
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Hive Bridge</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
<SidebarMenuItem v-for="item in items" :key="item.title">
<SidebarMenuButton asChild>
<RouterLink @click="isMobile && toggleSidebar()" :to="item.url">
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path style="fill: hsl(var(--foreground))" :d="item.icon"/></svg>
<span>{{item.title}}</span>
</RouterLink>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
</SidebarContent>
<SidebarFooter>
<Button class="bg-black/40" variant="outline" v-if="settingsStore.isLoaded && hasUser" @click="logout">
<img v-if="hasUser" :src="getWalletIcon(settingsStore.settings.wallet!)" class="h-6 w-6" />
<span class="font-bold">Disconnect</span>
</Button>
</SidebarFooter>
</Sidebar>
</template>
<style>
[data-sidebar="sidebar"] {
backdrop-filter: blur(20px);
background-color: rgba(0, 0, 0, 0.4);
}
</style>
<script setup lang="ts">
import { useSidebar } from "@/components/ui/sidebar";
import { Button } from "@/components/ui/button";
import { mdiMenuClose, mdiMenuOpen } from "@mdi/js";
const { toggleSidebar, open, isMobile } = useSidebar();
</script>
<template>
<Button variant="ghost" size="xs" @click="toggleSidebar">
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path style="fill: hsl(var(--foreground))" :d="open && !isMobile ? mdiMenuOpen : mdiMenuClose"></path>
</svg>
<span>{{ open && !isMobile ? 'Close sidebar' : 'Open sidebar' }}</span>
</Button>
</template>
export { default } from './AppSidebar.vue';
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
import { AvatarRoot } from 'reka-ui'
import { avatarVariant, type AvatarVariants } from '.'
const props = withDefaults(defineProps<{
class?: HTMLAttributes['class']
size?: AvatarVariants['size']
shape?: AvatarVariants['shape']
}>(), {
size: 'sm',
shape: 'circle',
})
</script>
<template>
<AvatarRoot :class="cn(avatarVariant({ size, shape }), props.class)">
<slot />
</AvatarRoot>
</template>
<script setup lang="ts">
import { AvatarFallback, type AvatarFallbackProps } from 'reka-ui'
const props = defineProps<AvatarFallbackProps>()
</script>
<template>
<AvatarFallback v-bind="props">
<slot />
</AvatarFallback>
</template>
<script setup lang="ts">
import type { AvatarImageProps } from 'reka-ui'
import { AvatarImage } from 'reka-ui'
const props = defineProps<AvatarImageProps>()
</script>
<template>
<AvatarImage v-bind="props" class="h-full w-full object-cover">
<slot />
</AvatarImage>
</template>
import { cva, type VariantProps } from 'class-variance-authority'
export { default as Avatar } from './Avatar.vue'
export { default as AvatarFallback } from './AvatarFallback.vue'
export { default as AvatarImage } from './AvatarImage.vue'
export const avatarVariant = cva(
'inline-flex items-center justify-center font-normal text-foreground select-none shrink-0 bg-secondary overflow-hidden',
{
variants: {
size: {
sm: 'h-10 w-10 text-xs',
base: 'h-16 w-16 text-2xl',
lg: 'h-32 w-32 text-5xl',
},
shape: {
circle: 'rounded-full',
square: 'rounded-md',
},
},
},
)
export type AvatarVariants = VariantProps<typeof avatarVariant>
...@@ -40,13 +40,13 @@ onMounted(() => { ...@@ -40,13 +40,13 @@ onMounted(() => {
</script> </script>
<template> <template>
<Card class="bg-black/40 backdrop-blur-sm"> <Card class="w-full max-w-[600px] bg-black/40 backdrop-blur-sm">
<CardHeader> <CardHeader>
<CardTitle class="inline-flex items-center justify-between"> <CardTitle class="inline-flex items-center justify-between">
<span>Authority info</span> <span>Authority info</span>
<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path style="fill: hsla(var(--foreground) / 80%)" :d="mdiAccountKeyOutline"/></svg> <svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path style="fill: hsla(var(--foreground) / 80%)" :d="mdiAccountKeyOutline"/></svg>
</CardTitle> </CardTitle>
<CardDescription class="mr-4">Use this module to gather information about your Hive on-chain authorities</CardDescription> <CardDescription class="mr-8">Use this module to gather information about your Hive on-chain authorities</CardDescription>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<div class="space-y-4" v-if="hasUser"> <div class="space-y-4" v-if="hasUser">
......
...@@ -7,13 +7,13 @@ import { Input } from '@/components/ui/input'; ...@@ -7,13 +7,13 @@ import { Input } from '@/components/ui/input';
</script> </script>
<template> <template>
<Card class="bg-black/40 backdrop-blur-sm"> <Card class="w-full max-w-[600px] bg-black/40 backdrop-blur-sm">
<CardHeader> <CardHeader>
<CardTitle class="inline-flex items-center justify-between"> <CardTitle class="inline-flex items-center justify-between">
<span>Process Account Creation</span> <span>Process Account Creation</span>
<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path style="fill: hsla(var(--foreground) / 80%)" :d="mdiAccountPlusOutline"/></svg> <svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path style="fill: hsla(var(--foreground) / 80%)" :d="mdiAccountPlusOutline"/></svg>
</CardTitle> </CardTitle>
<CardDescription class="mr-4">Use this module to process account creation request sent by other users</CardDescription> <CardDescription class="mr-8">Use this module to process account creation request sent by other users</CardDescription>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<div class="my-4"> <div class="my-4">
......
...@@ -51,13 +51,13 @@ const encryptOrDecrypt = async () => { ...@@ -51,13 +51,13 @@ const encryptOrDecrypt = async () => {
</script> </script>
<template> <template>
<Card class="bg-black/40 backdrop-blur-sm"> <Card class="w-full max-w-[600px] bg-black/40 backdrop-blur-sm">
<CardHeader> <CardHeader>
<CardTitle class="inline-flex items-center justify-between"> <CardTitle class="inline-flex items-center justify-between">
<span>Memo encryption</span> <span>Memo encryption</span>
<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path style="fill: hsla(var(--foreground) / 80%)" :d="mdiMessageLockOutline"/></svg> <svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path style="fill: hsla(var(--foreground) / 80%)" :d="mdiMessageLockOutline"/></svg>
</CardTitle> </CardTitle>
<CardDescription class="mr-4">Use this module to encrypt / decrypt given message using your memo key for any purpose</CardDescription> <CardDescription class="mr-8">Use this module to encrypt / decrypt given message using your memo key for any purpose</CardDescription>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<div class="my-4 space-x-4 flex"> <div class="my-4 space-x-4 flex">
......
...@@ -35,13 +35,13 @@ const sign = async () => { ...@@ -35,13 +35,13 @@ const sign = async () => {
</script> </script>
<template> <template>
<Card class="bg-black/40 backdrop-blur-sm"> <Card class="w-full max-w-[600px] bg-black/40 backdrop-blur-sm">
<CardHeader> <CardHeader>
<CardTitle class="inline-flex items-center justify-between"> <CardTitle class="inline-flex items-center justify-between">
<span>Transaction signing</span> <span>Transaction signing</span>
<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path style="fill: hsla(var(--foreground) / 80%)" :d="mdiFileSign"/></svg> <svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path style="fill: hsla(var(--foreground) / 80%)" :d="mdiFileSign"/></svg>
</CardTitle> </CardTitle>
<CardDescription class="mr-4">Use this module to sign the provided transaction</CardDescription> <CardDescription class="mr-8">Use this module to sign the provided transaction</CardDescription>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<Textarea v-model="inputData" placeholder="Transaction in API JSON form" class="my-4"/> <Textarea v-model="inputData" placeholder="Transaction in API JSON form" class="my-4"/>
......
import { createApp } from 'vue' import { createApp } from 'vue'
import './style.css' import './style.css'
import { createPinia } from 'pinia' import { createPinia } from 'pinia'
import { createMemoryHistory, createRouter } from 'vue-router' import { createWebHistory, createRouter } from 'vue-router'
import App from './App.vue' import App from './App.vue'
import { routes } from './utils/router' import { routes } from './utils/router'
const pinia = createPinia() const pinia = createPinia()
const router = createRouter({ const router = createRouter({
routes: routes, routes: routes,
history: createMemoryHistory(), history: createWebHistory(),
}) })
createApp(App).use(pinia).use(router).mount('#app') createApp(App).use(pinia).use(router).mount('#app')
<script setup lang="ts">
import ConfirmCreateAccountCard from '@/components/utilcards/ConfirmCreateAccountCard.vue';
</script>
<template>
<div class="flex py-4 px-8">
<ConfirmCreateAccountCard />
</div>
</template>
<script setup lang="ts"> <script setup lang="ts">
import AuthorityCard from '@/components/utilcards/AuthorityCard.vue'; import AuthorityCard from '@/components/utilcards/AuthorityCard.vue';
import ConfirmCreateAccountCard from '@/components/utilcards/ConfirmCreateAccountCard.vue';
import MemoEncryptCard from '@/components/utilcards/MemoEncryptCard.vue';
import SignTransactionCard from '@/components/utilcards/SignTransactionCard.vue';
</script> </script>
<template> <template>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 p-8"> <div class="flex py-4 px-8">
<AuthorityCard /> <AuthorityCard />
<MemoEncryptCard />
<SignTransactionCard />
<ConfirmCreateAccountCard />
</div> </div>
</template> </template>
<script setup lang="ts">
import MemoEncryptCard from '@/components/utilcards/MemoEncryptCard.vue';
</script>
<template>
<div class="flex py-4 px-8">
<MemoEncryptCard />
</div>
</template>
<script setup lang="ts">
import SignTransactionCard from '@/components/utilcards/SignTransactionCard.vue';
</script>
<template>
<div class="flex py-4 px-8">
<SignTransactionCard />
</div>
</template>
import Index from "@/pages/index.vue"; import Index from "@/pages/index.vue";
import SignTransaction from "@/pages/sign/transaction.vue";
import SignMessage from "@/pages/sign/message.vue";
import AccountCreate from "@/pages/account/create.vue";
export const routes = [ export const routes = [
{ path: '/', component: Index } { path: '/', component: Index },
{ path: '/sign/transaction', component: SignTransaction },
{ path: '/sign/message', component: SignMessage },
{ path: '/account/create', component: AccountCreate }
]; ];
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment