frontend/components/preferences2/dialog.vue

149 lines
6.1 KiB
Vue

<script setup lang="ts">
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import {
InfoIcon,
PaletteIcon,
SettingsIcon,
ShieldCheckIcon,
SmileIcon,
TerminalSquareIcon,
UserIcon,
} from "lucide-vue-next";
import pkg from "~/package.json";
import Avatar from "../profiles/avatar.vue";
import TinyCard from "../profiles/tiny-card.vue";
import { Separator } from "../ui/separator";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../ui/tabs";
import Category from "./category.vue";
import Emojis from "./emojis/index.vue";
import Page from "./page.vue";
import { preferences } from "./preferences";
import Stats from "./stats.vue";
const pages = Object.values(preferences)
.map((p) => p.options.category)
.filter((c) => c !== undefined)
.map((c) => c.split("/")[0] as string)
.concat(["Account", "Emojis", "Roles", "Developer", "About"])
// Remove duplicates
.filter((c, i, a) => a.indexOf(c) === i);
const extraPages = ["Account", "Emojis", "Roles", "Developer", "About"];
const icons: Record<string, Component> = {
Account: UserIcon,
Appearance: PaletteIcon,
Emojis: SmileIcon,
Behaviour: SettingsIcon,
Roles: ShieldCheckIcon,
Developer: TerminalSquareIcon,
About: InfoIcon,
};
// For each page, map the associated categories
const categories = Object.fromEntries(
pages.map((page) => {
const categories = Object.values(preferences)
.map((p) => p.options.category)
.filter((c) => c !== undefined)
.filter((c) => c.split("/")[0] === page)
.map((c) => c.split("/")[1] as string)
// Remove duplicates
.filter((c, i, a) => a.indexOf(c) === i);
return [page, categories];
}),
);
const { account: author1 } = useAccountFromAcct(
client,
"jessew@vs.cpluspatch.com",
);
const { account: author2 } = useAccountFromAcct(
client,
"aprl@social.lysand.org",
);
const { account: author3 } = useAccountFromAcct(
client,
"lina@social.lysand.org",
);
</script>
<template>
<Dialog open v-if="identity">
<DialogContent class="md:max-w-5xl w-full h-full p-0 md:max-h-[70dvh]">
<Tabs class="md:grid-cols-[auto_minmax(0,1fr)] !grid gap-2 *:p-4 overflow-hidden *:overflow-y-auto *:h-full" orientation="vertical"
:default-value="pages[0]">
<DialogHeader class="gap-6 grid grid-rows-[auto_minmax(0,1fr)] border-b md:border-b-0 md:border-r min-w-60 text-left">
<div class="grid gap-3 items-center grid-cols-[auto_minmax(0,1fr)]">
<Avatar :name="identity.account.display_name || identity.account.username"
:src="identity.account.avatar" />
<DialogTitle>Preferences</DialogTitle>
</div>
<DialogDescription class="sr-only">
Make changes to your preferences here.
</DialogDescription>
<TabsList class="md:grid md:grid-cols-1 w-full h-fit *:justify-start !justify-start">
<TabsTrigger v-for="page in pages" :key="page" :value="page">
<component :is="icons[page]" class="size-4 mr-2" />
{{ page }}
</TabsTrigger>
</TabsList>
</DialogHeader>
<TabsContent v-for="page in pages.filter(p => !extraPages.includes(p))" :key="page" :value="page"
as-child>
<Page :title="page">
<Category v-for="category in categories[page]" :key="category"
:preferences="Object.entries(preferences).filter(([, p]) => p.options.category === `${page}/${category}`).map(([k,]) => k as keyof typeof preferences)"
:name="category" />
</Page>
</TabsContent>
<TabsContent value="Emojis" as-child>
<Page title="Emojis">
<Emojis />
</Page>
</TabsContent>
<TabsContent value="About" as-child>
<Page title="About">
<section class="space-y-4">
<p class="leading-7 text-sm max-w-xl">
{{ pkg.description }}
</p>
<Stats />
</section>
<Separator />
<section class="space-y-2">
<h3 class="text-lg font-semibold tracking-tight">Developers</h3>
<div class="grid lg:grid-cols-3 md:grid-cols-2 grid-cols-1 gap-4">
<TinyCard v-if="author1" :account="author1" domain="vs.cpluspatch.com" />
<TinyCard v-if="author2" :account="author2" domain="social.lysand.org" />
<TinyCard v-if="author3" :account="author3" domain="social.lysand.org" />
</div>
</section>
<Separator />
<section class="space-y-2">
<h3 class="text-lg font-semibold tracking-tight">Dependencies</h3>
<ul class="grid lg:grid-cols-2 gap-2 grid-cols-1 items-center justify-center list-disc ml-6">
<li v-for="[dep, version] in Object.entries(pkg.dependencies)" :key="dep">
<code
class="rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-xs font-semibold">
{{ dep }}@{{ version }}
</code>
</li>
</ul>
</section>
</Page>
</TabsContent>
</Tabs>
</DialogContent>
</Dialog>
</template>