const response = await api.get("/v1/packages")
return response.data;
}
+
+// Fetch a package by its UUID
+export async function fetchPackage(uuid: string): Promise<Package> {
+ const response = await api.get(`/v1/packages/${uuid}`);
+ return response.data;
+}
--- /dev/null
+<template>
+ <div class="block">
+ <slot />
+ </div>
+</template>
--- /dev/null
+<script setup lang="ts">
+ // Import type
+ import type { Package } from "@/api/packages";
+
+ // Fetch the package
+ defineProps<{
+ pkg: Package
+ }>();
+
+ // Components
+ import Block from "@/components/Block.vue";
+ import Container from "@/components/Container.vue";
+ import Tags from "@/components/Tags.vue";
+ import Tag from "@/components/Tag.vue";
+
+ // Utils
+ import { formatHostname, formatSize } from "@/utils/format";
+</script>
+
+<template>
+ <div class="hero is-light">
+ <div class="hero-body">
+ <Container>
+ <!-- Name & Version Information -->
+ <h3 class="title is-3">{{ pkg.name }} {{ pkg.evr }}</h3>
+
+ <!-- Summary -->
+ <h5 v-if="pkg.summary" class="subtitle is-5">
+ {{ pkg.summary }}
+ </h5>
+
+ <!-- Description -->
+ <Block v-if="pkg.description">
+ <div class="content">
+ <pre>{{ pkg.description }}</pre>
+ </div>
+ </Block>
+
+ <div class="level">
+ <!-- Size -->
+ <div v-if="pkg.size" class="level-item has-text-centered">
+ <div>
+ <p class="heading">{{ $t("Size") }}</p>
+ <p>{{ formatSize(pkg.size) }}</p>
+ </div>
+ </div>
+
+ <!-- Website -->
+ <div v-if="pkg.url" class="level-item has-text-centered">
+ <div>
+ <p class="heading">{{ $t("Website") }}</p>
+ <p>
+ <a :href="pkg.url">
+ {{ formatHostname(pkg.url) }}
+ </a>
+ </p>
+ </div>
+ </div>
+
+ <!-- License -->
+ <div v-if="pkg.license" class="level-item has-text-centered">
+ <div>
+ <p class="heading">{{ $t("License") }}</p>
+ <p>{{ pkg.license }}</p>
+ </div>
+ </div>
+
+ <!-- Groups -->
+ <div v-if="pkg.groups" class="level-item has-text-centered">
+ <div>
+ <p class="heading">{{ $t("Groups") }}</p>
+ <Tags>
+ <Tag v-for="group in pkg.groups" :key="group">
+ {{ group }}
+ </Tag>
+ </Tags>
+ </div>
+ </div>
+
+ <!-- Packager -->
+ <div v-if="pkg.packager" class="level-item has-text-centered">
+ <div>
+ <p class="heading">{{ $t("Packager") }}</p>
+ <p>{{ pkg.packager }}</p>
+ </div>
+ </div>
+ </div>
+ </Container>
+ </div>
+ </div>
+</template>
--- /dev/null
+import { onMounted, ref } from "vue";
+
+// API
+import type { Package } from "@/api/packages";
+import { fetchPackage } from "@/api/packages";
+
+export function usePackage(uuid: string) {
+ const pkg = ref<Package>();
+
+ // Fetch the package
+ async function loadPackage() {
+ pkg.value = await fetchPackage(uuid);
+ }
+
+ return {
+ pkg,
+ loadPackage,
+ };
+}
import BuildersView from "../views/BuildersView.vue"
import MirrorsView from "../views/MirrorsView.vue"
import NotFoundView from "../views/NotFoundView.vue"
+import PackageByUUIDView from "../views/PackageByUUIDView.vue"
import PackagesView from "../views/PackagesView.vue"
const router = createRouter({
component: PackagesView,
},
+ // Package by UUID
+ {
+ path: "/packages/:uuid(\\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\\b)",
+ name: "package-by-uuid",
+ component: PackageByUUIDView,
+ },
+
// 404 - Not Found
{
path: "/:pathMatch(.*)*",
--- /dev/null
+<script setup lang="ts">
+ import { onMounted } from "vue";
+ import { useRoute } from "vue-router";
+
+ // Composables
+ import { usePackage } from "@/composables/packages";
+
+ // Import UI components
+ import PackageHeader from "@/components/PackageHeader.vue";
+
+ // Fetch the package UUID from the URL
+ const route = useRoute();
+ const uuid = route.params.uuid as string;
+
+ // Fetch the package
+ const { pkg, loadPackage } = usePackage(uuid);
+
+ onMounted(async () => {
+ await loadPackage();
+ });
+</script>
+
+<template>
+ <!-- Show the header -->
+ <PackageHeader v-if="pkg" :pkg="pkg" />
+</template>