Consolidate OptionalLinkTable and ToggleLinkTable into LinkTable

LinkTable now supports variant (list/table) and optional title toggle, replacing the need for separate components. Updates all consumers to use the unified API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-25 02:43:24 +00:00
parent c2bbd7ad88
commit d857cce5dc
8 changed files with 73 additions and 76 deletions

View File

@@ -1,20 +1,73 @@
<script setup>
import { computed } from "vue";
import { ref } from "vue";
import Link from "@/components/text/Link.vue";
import ToggleHeader from "@/components/text/ToggleHeader.vue";
const props = defineProps({
linkArr: {
items: {
type: Array,
required: true,
},
variant: {
type: String,
default: "list",
},
title: {
type: String,
default: "",
},
});
const keys = ["name", "link"];
const show = ref(false);
</script>
<template>
<a v-for="(row, rowIndex) in linkArr" :key="rowIndex" :href="row.link">
<p class="bdr-2 bg-bg_tertiary">
{{ row.name }}
</p>
</a>
<div v-if="title" class="h-fit w-fit">
<ToggleHeader v-model="show" class="justify-between flex">
{{ title }}
</ToggleHeader>
<template v-if="show">
<Link
v-if="variant === 'list'"
v-for="(item, i) in items"
:key="i"
:href="item.link"
>
<p class="bdr-2 bg-bg_tertiary">{{ item.name }}</p>
</Link>
<table v-else>
<tbody>
<tr v-for="item in items" :key="item.id">
<th>{{ item.type }}</th>
<td v-if="item.link">
<Link :href="item.link">{{ item.name }}</Link>
</td>
<td v-else>{{ item.name }}</td>
</tr>
</tbody>
</table>
</template>
</div>
<template v-else>
<template v-if="variant === 'list'">
<Link
v-for="(item, i) in items"
:key="i"
:href="item.link"
>
<p class="bdr-2 bg-bg_tertiary">{{ item.name }}</p>
</Link>
</template>
<table v-else>
<tbody>
<tr v-for="item in items" :key="item.id">
<th>{{ item.type }}</th>
<td v-if="item.link">
<Link :href="item.link">{{ item.name }}</Link>
</td>
<td v-else>{{ item.name }}</td>
</tr>
</tbody>
</table>
</template>
</template>

View File

@@ -1,27 +0,0 @@
<script setup>
// Array will have the form
// [ {type: string, name: string, link?: string}]
const props = defineProps({
data: {
type: Array,
required: true,
},
});
const keys = ["type", "name", "link"];
</script>
<template>
<table>
<tbody>
<tr v-for="item in data" :key="item.id">
<th>{{ item.type }}</th>
<td v-if="item.link">
<a :href="item.link">{{ item.name }}</a>
</td>
<td v-else>{{ item.name }}</td>
</tr>
</tbody>
</table>
</template>

View File

@@ -1,28 +0,0 @@
<script setup>
import ToggleHeader from "@/components/text/ToggleHeader.vue";
import { ref } from "vue";
import LinkTable from "@/components/util/LinkTable.vue";
const props = defineProps({
linkArr: {
type: Array,
required: true,
},
title: {
type: String,
required: true,
},
});
const show_links = ref(false);
</script>
<template>
<div class="h-fit w-fit">
<ToggleHeader v-model="show_links" class="justify-between flex"
>{{ title }}
</ToggleHeader>
<LinkTable v-if="show_links" :linkArr="props.linkArr" />
</div>
</template>

View File

@@ -1,7 +1,5 @@
<script setup>
import { ref } from "vue";
import ToggleLinkTable from "@/components/util/ToggleLinkTable.vue";
import LinkTable from "@/components/util/LinkTable.vue";
const links = [
[
@@ -245,11 +243,11 @@ const links = [
class="a4page-portrait bdr-1 flex flex-row flex-wrap overflow-x-auto gap-1"
>
<div class="w-full h-fit">
<ToggleLinkTable
<LinkTable
class="flex flex-col flex-wrap"
v-for="link in links"
:title="link[0]"
:linkArr="link[1]"
:items="link[1]"
/>
</div>
</div>

View File

@@ -1,6 +1,6 @@
<script setup>
import AutoScroll from "@/components/util/AutoScroll.vue";
import OptionalLinkTable from "@/components/util/OptionalLinkTable.vue";
import LinkTable from "@/components/util/LinkTable.vue";
import Header from "@/components/text/Header.vue";
import { useActivityStore } from "@/stores/activity";
@@ -12,7 +12,7 @@ const activityStore = useActivityStore();
<div class="flex flex-col items-center">
<Header>Consumption</Header>
<AutoScroll class="flex-1 w-full">
<OptionalLinkTable class="w-full" :data="activityStore.activity" />
<LinkTable variant="table" class="w-full" :items="activityStore.activity" />
</AutoScroll>
</div>
</template>

View File

@@ -1,6 +1,6 @@
<script setup>
import Header from "@/components/text/Header.vue";
import OptionalLinkTable from "@/components/util/OptionalLinkTable.vue";
import LinkTable from "@/components/util/LinkTable.vue";
import AutoScroll from "@/components/util/AutoScroll.vue";
import { useFavoritesStore } from "@/stores/favorites";
@@ -12,9 +12,10 @@ const favoritesStore = useFavoritesStore();
<div class="flex flex-col items-center">
<Header>favs</Header>
<AutoScroll class="w-full flex-1">
<OptionalLinkTable
<LinkTable
variant="table"
class="w-full"
:data="favoritesStore.favorites"
:items="favoritesStore.favorites"
/>
</AutoScroll>
</div>

View File

@@ -1,6 +1,6 @@
<script setup>
import Header from "@/components/text/Header.vue";
import OptionalLinkTable from "@/components/util/OptionalLinkTable.vue";
import LinkTable from "@/components/util/LinkTable.vue";
const gym = [
{ name: "Row", type: "30 min" },
{ name: "Run", type: "5k" },
@@ -14,7 +14,7 @@ const gym = [
<p>I'm not a gym geek</p>
<p>4/7 days I do:</p>
<div class="overflow-scroll w-full border-box">
<OptionalLinkTable class="w-full" :data="gym" />
<LinkTable variant="table" class="w-full" :items="gym" />
</div>
</div>
</template>

View File

@@ -24,7 +24,7 @@ const social_links = [
<RouterTable :linkArr="site_links" />
</div>
<div class="flex flex-col gap-1">
<LinkTable :linkArr="social_links" />
<LinkTable :items="social_links" />
</div>
</div>
</template>