Skip to content

Commit

Permalink
feat: Add more page in dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
flemzord committed May 6, 2024
1 parent a372cd9 commit 0a54869
Show file tree
Hide file tree
Showing 26 changed files with 823 additions and 62 deletions.
11 changes: 1 addition & 10 deletions apps/web/components/CustomerTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,7 @@
<div class="relative isolate">
<div class="mx-auto max-w-7xl py-10">
<div class="px-4 sm:px-6 lg:px-8">
<div class="sm:flex sm:items-center">
<div class="sm:flex-auto">
<h1 class="text-base font-semibold leading-6 text-gray-900">Customers</h1>
<p class="mt-2 text-sm text-gray-700">You can create, modify or delete a customer.</p>
</div>
<div class="mt-4 sm:ml-16 sm:mt-0 sm:flex-none">
<CustomerModal />
</div>
</div>
<div class="mt-8 flow-root">
<div class="mt-2 flow-root">
<div class="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div class="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
<table class="min-w-full divide-y divide-gray-300">
Expand Down
104 changes: 104 additions & 0 deletions apps/web/components/LicenseChart.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<script setup lang="ts">
const props = defineProps(['licenseId']);
import {
CategoryScale,
Chart as ChartJS,
Legend,
LineElement,
LinearScale,
PointElement,
Title,
Tooltip,
} from 'chart.js';
import { Line } from 'vue-chartjs';
ChartJS.register(
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend,
);
interface QueryResult {
rows: Rows[];
fields: Array<Array<string>>;
}
interface Rows {
count: number;
time: Date;
action: string;
}
const { $client } = useNuxtApp();
const { data: licenses } = await $client.licenseUsage.getById.useQuery({
id: props.licenseId,
});
const query: QueryResult = licenses.value;
const rows: Rows[] = query.rows;
console.log('rows', rows);
// MAP
const valueSuccess = rows
.filter((item) => item.action === 'SUCCESS')
.map((item) => item.count);
const valueExpired = rows
.filter((item) => item.action === 'EXPIRED')
.map((item) => item.count);
const labels = rows.map((x) => x.time);
const chartOptions = {
responsive: true,
maintainAspectRatio: false,
scales: {
yAxes: [
{
display: true,
type: 'time',
time: {
parser: 'MM/DD/YYYY',
tooltipFormat: 'll',
unit: 'day',
unitStepSize: 1,
displayFormats: {
day: 'MM/DD/YYYY',
},
},
},
],
},
};
const chartData = {
labels: labels,
datasets: [
{
label: 'SUCCESS',
backgroundColor: '#209a2a',
data: valueSuccess,
},
{
label: 'EXPIRED',
backgroundColor: '#c1123a',
data: valueExpired,
},
],
};
</script>

<template>
<div class="relative isolate">
<div class="mx-auto max-w-7xl py-10">
<div class="px-4 sm:px-6 lg:px-8">
<Line
id="LineChart"
:options="chartOptions"
:data="chartData"
/>
</div>
</div>
</div>
</template>
15 changes: 4 additions & 11 deletions apps/web/components/LicenseTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,7 @@
<div class="relative isolate">
<div class="mx-auto max-w-7xl py-10">
<div class="px-4 sm:px-6 lg:px-8">
<div class="sm:flex sm:items-center">
<div class="sm:flex-auto">
<h1 class="text-base font-semibold leading-6 text-gray-900">Licenses</h1>
<p class="mt-2 text-sm text-gray-700">You can create, modify or delete a license.</p>
</div>
<div class="mt-4 sm:ml-16 sm:mt-0 sm:flex-none">
<LicenseModal />
</div>
</div>
<div class="mt-8 flow-root">
<div class="mt-2 flow-root">
<div class="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div class="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
<table class="min-w-full divide-y divide-gray-300">
Expand Down Expand Up @@ -56,7 +47,9 @@
</thead>
<tbody class="divide-y divide-gray-200 bg-white">
<tr v-for="token of license" :key="token.id">
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-0">{{ token.License.name }}</td>
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-0">
<NuxtLink :to="{ name: 'dashboard-license-id', params: { id: token.License.id }}">{{ token.License.name }}</NuxtLink>
</td>
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{{ token.Product.name }}</td>
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{{ token.Customer.name }}</td>
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{{ token.License.createdAt }}</td>
Expand Down
11 changes: 1 addition & 10 deletions apps/web/components/ProductTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,7 @@
<div class="relative isolate">
<div class="mx-auto max-w-7xl py-10">
<div class="px-4 sm:px-6 lg:px-8">
<div class="sm:flex sm:items-center">
<div class="sm:flex-auto">
<h1 class="text-base font-semibold leading-6 text-gray-900">Products</h1>
<p class="mt-2 text-sm text-gray-700">You can create, modify or delete a product.</p>
</div>
<div class="mt-4 sm:ml-16 sm:mt-0 sm:flex-none">
<ProductModal />
</div>
</div>
<div class="mt-8 flow-root">
<div class="mt-2 flow-root">
<div class="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div class="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
<table class="min-w-full divide-y divide-gray-300">
Expand Down
34 changes: 12 additions & 22 deletions apps/web/layouts/dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,12 @@
<div class="flex flex-shrink-0 items-center">
<img class="h-14 w-auto" src="/logo.png" alt="GetLicensed" />
</div>
<div class="hidden md:ml-6 md:flex md:space-x-8">
<a href="/dashboard" class="inline-flex items-center border-b-2 border-indigo-500 px-1 pt-1 text-sm font-medium text-gray-900">Dashboard</a>
<!-- <a href="#" class="inline-flex items-center border-b-2 border-transparent px-1 pt-1 text-sm font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700">Team</a>-->
<!-- <a href="#" class="inline-flex items-center border-b-2 border-transparent px-1 pt-1 text-sm font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700">Projects</a>-->
<!-- <a href="#" class="inline-flex items-center border-b-2 border-transparent px-1 pt-1 text-sm font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700">Calendar</a>-->
<div class="hidden sm:-my-px sm:ml-6 sm:flex sm:space-x-8">
<a v-for="item in navigation" :key="item.name" :href="item.href" :class="[item.current ? 'border-indigo-500 text-gray-900' : 'border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700', 'inline-flex items-center border-b-2 px-1 pt-1 text-sm font-medium']" :aria-current="item.current ? 'page' : undefined">{{ item.name }}</a>
</div>
</div>
<div class="flex items-center">
<div class="hidden md:ml-4 md:flex md:flex-shrink-0 md:items-center">
<!-- <button type="button" class="relative rounded-full bg-white p-1 text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">-->
<!-- <span class="absolute -inset-1.5" />-->
<!-- <span class="sr-only">View notifications</span>-->
<!-- <BellIcon class="h-6 w-6" aria-hidden="true" />-->
<!-- </button>-->

<!-- Profile dropdown -->
<Menu as="div" class="relative ml-3">
Expand Down Expand Up @@ -64,28 +56,19 @@

<DisclosurePanel class="md:hidden">
<div class="space-y-1 pb-3 pt-2">
<!-- Current: "bg-indigo-50 border-indigo-500 text-indigo-700", Default: "border-transparent text-gray-500 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-700" -->
<DisclosureButton as="a" href="#/dashboard" class="block border-l-4 border-indigo-500 bg-indigo-50 py-2 pl-3 pr-4 text-base font-medium text-indigo-700 sm:pl-5 sm:pr-6">Dashboard</DisclosureButton>
<!-- <DisclosureButton as="a" href="#" class="block border-l-4 border-transparent py-2 pl-3 pr-4 text-base font-medium text-gray-500 hover:border-gray-300 hover:bg-gray-50 hover:text-gray-700 sm:pl-5 sm:pr-6">Team</DisclosureButton>-->
<!-- <DisclosureButton as="a" href="#" class="block border-l-4 border-transparent py-2 pl-3 pr-4 text-base font-medium text-gray-500 hover:border-gray-300 hover:bg-gray-50 hover:text-gray-700 sm:pl-5 sm:pr-6">Projects</DisclosureButton>-->
<!-- <DisclosureButton as="a" href="#" class="block border-l-4 border-transparent py-2 pl-3 pr-4 text-base font-medium text-gray-500 hover:border-gray-300 hover:bg-gray-50 hover:text-gray-700 sm:pl-5 sm:pr-6">Calendar</DisclosureButton>-->
<DisclosureButton v-for="item in navigation" :key="item.name" as="a" :href="item.href" :class="[item.current ? 'border-indigo-500 bg-indigo-50 text-indigo-700' : 'border-transparent text-gray-600 hover:border-gray-300 hover:bg-gray-50 hover:text-gray-800', 'block border-l-4 py-2 pl-3 pr-4 text-base font-medium']" :aria-current="item.current ? 'page' : undefined">{{ item.name }}</DisclosureButton>
</div>
<div class="border-t border-gray-200 pb-3 pt-4">
<div class="flex items-center px-4 sm:px-6">
<div class="flex-shrink-0">
<span class="inline-flex h-10 w-10 items-center justify-center rounded-full bg-gray-500">
<span class="font-medium leading-none text-white">{{ user.name.substring(0, 2) }}</span>
</span>
<span class="font-medium leading-none text-white">{{ user.name.substring(0, 2) }}</span>
</span>
</div>
<div class="ml-3">
<div class="text-base font-medium text-gray-800">{{ user.name }}</div>
<div class="text-sm font-medium text-gray-500">{{ user.email }}</div>
</div>
<!-- <button type="button" class="relative ml-auto flex-shrink-0 rounded-full bg-white p-1 text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">-->
<!-- <span class="absolute -inset-1.5" />-->
<!-- <span class="sr-only">View notifications</span>-->
<!-- <BellIcon class="h-6 w-6" aria-hidden="true" />-->
<!-- </button>-->
</div>
<div class="mt-3 space-y-1">
<!-- <DisclosureButton as="a" href="#" class="block px-4 py-2 text-base font-medium text-gray-500 hover:bg-gray-100 hover:text-gray-800 sm:px-6">Your Profile</DisclosureButton>-->
Expand Down Expand Up @@ -118,4 +101,11 @@ import {
import { PlusIcon } from '@heroicons/vue/20/solid';
import { Bars3Icon, XMarkIcon } from '@heroicons/vue/24/outline';
const { user, clear } = useUserSession();
const navigation = [
{ name: 'Dashboard', href: '/dashboard', current: true },
{ name: 'Product', href: '/dashboard/product', current: false },
{ name: 'Customer', href: '/dashboard/customer', current: false },
{ name: 'License', href: '/dashboard/license', current: false },
];
</script>
37 changes: 37 additions & 0 deletions apps/web/pages/dashboard/customer/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<script setup lang="ts">
definePageMeta({
layout: 'dashboard',
middleware: 'auth',
});
useSeoMeta({
title: 'Customer - GetLicensed',
});
</script>

<template>
<main>
<header class="relative isolate">
<div class="absolute inset-0 -z-10 overflow-hidden" aria-hidden="true">
<div class="absolute left-16 top-full -mt-16 transform-gpu opacity-50 blur-3xl xl:left-1/2 xl:-ml-80">
<div class="aspect-[1154/678] w-[72.125rem] bg-gradient-to-br from-[#FF80B5] to-[#9089FC]" style="clip-path: polygon(100% 38.5%, 82.6% 100%, 60.2% 37.7%, 52.4% 32.1%, 47.5% 41.8%, 45.2% 65.6%, 27.5% 23.4%, 0.1% 35.3%, 17.9% 0%, 27.7% 23.4%, 76.2% 2.5%, 74.2% 56%, 100% 38.5%)" />
</div>
<div class="absolute inset-x-0 bottom-0 h-px bg-gray-900/5" />
</div>

<div class="mx-auto max-w-7xl px-4 py-10 sm:px-6 lg:px-8">
<div class="mx-auto flex max-w-2xl items-center justify-between gap-x-8 lg:mx-0 lg:max-w-none">
<div class="flex items-center gap-x-6">
<h1>
<div class="mt-1 text-base font-semibold leading-6 text-gray-900">Customers</div>
</h1>
<div>
<CustomerModal />
</div>
</div>
</div>
</div>
</header>
<CustomerTable />
</main>
</template>
4 changes: 0 additions & 4 deletions apps/web/pages/dashboard/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,5 @@ useSeoMeta({
</div>
</div>
</header>

<ProductTable />
<CustomerTable />
<LicenseTable />
</main>
</template>
44 changes: 44 additions & 0 deletions apps/web/pages/dashboard/license/[id].vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<script setup lang="ts">
definePageMeta({
layout: 'dashboard',
middleware: 'auth',
});
useSeoMeta({
title: 'License - GetLicensed',
});
const { $client } = useNuxtApp();
const route = useRoute();
const { data: license } = await $client.license.getById.useQuery({
id: route.params.id.toString(),
});
const toto = license.value;
</script>


<template>
<main>
<header class="relative isolate">
<div class="absolute inset-0 -z-10 overflow-hidden" aria-hidden="true">
<div class="absolute left-16 top-full -mt-16 transform-gpu opacity-50 blur-3xl xl:left-1/2 xl:-ml-80">
<div class="aspect-[1154/678] w-[72.125rem] bg-gradient-to-br from-[#FF80B5] to-[#9089FC]" style="clip-path: polygon(100% 38.5%, 82.6% 100%, 60.2% 37.7%, 52.4% 32.1%, 47.5% 41.8%, 45.2% 65.6%, 27.5% 23.4%, 0.1% 35.3%, 17.9% 0%, 27.7% 23.4%, 76.2% 2.5%, 74.2% 56%, 100% 38.5%)" />
</div>
<div class="absolute inset-x-0 bottom-0 h-px bg-gray-900/5" />
</div>

<div class="mx-auto max-w-7xl px-4 py-10 sm:px-6 lg:px-8">
<div class="mx-auto flex max-w-2xl items-center justify-between gap-x-8 lg:mx-0 lg:max-w-none">
<div class="flex items-center gap-x-6">
<h1>
<div class="mt-1 text-base font-semibold leading-6 text-gray-900">License {{ toto?.name }} ({{ toto?.id }})</div>
</h1>
</div>
</div>
</div>
</header>

<LicenseChart :licenseId="route.params.id.toString()" />
</main>
</template>
38 changes: 38 additions & 0 deletions apps/web/pages/dashboard/license/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<script setup lang="ts">
definePageMeta({
layout: 'dashboard',
middleware: 'auth',
});
useSeoMeta({
title: 'License - GetLicensed',
});
</script>

<template>
<main>
<header class="relative isolate">
<div class="absolute inset-0 -z-10 overflow-hidden" aria-hidden="true">
<div class="absolute left-16 top-full -mt-16 transform-gpu opacity-50 blur-3xl xl:left-1/2 xl:-ml-80">
<div class="aspect-[1154/678] w-[72.125rem] bg-gradient-to-br from-[#FF80B5] to-[#9089FC]" style="clip-path: polygon(100% 38.5%, 82.6% 100%, 60.2% 37.7%, 52.4% 32.1%, 47.5% 41.8%, 45.2% 65.6%, 27.5% 23.4%, 0.1% 35.3%, 17.9% 0%, 27.7% 23.4%, 76.2% 2.5%, 74.2% 56%, 100% 38.5%)" />
</div>
<div class="absolute inset-x-0 bottom-0 h-px bg-gray-900/5" />
</div>

<div class="mx-auto max-w-7xl px-4 py-10 sm:px-6 lg:px-8">
<div class="mx-auto flex max-w-2xl items-center justify-between gap-x-8 lg:mx-0 lg:max-w-none">
<div class="flex items-center gap-x-6">
<h1>
<div class="mt-1 text-base font-semibold leading-6 text-gray-900">Licenses</div>
</h1>

<div>
<LicenseModal />
</div>
</div>
</div>
</div>
</header>
<LicenseTable />
</main>
</template>
Loading

0 comments on commit 0a54869

Please sign in to comment.