204 lines
6.3 KiB
Vue
204 lines
6.3 KiB
Vue
<template>
|
|
<div>
|
|
<div
|
|
class="template-container min-h-screen bg-white dark:bg-neutral-950 text-neutral-900 dark:text-neutral-100 py-8">
|
|
<div class="max-w-6xl mx-auto px-4 relative">
|
|
<div class="mb-8">
|
|
<h1 class="text-3xl font-bold text-neutral-900 dark:text-white mb-2">
|
|
Wizards
|
|
</h1>
|
|
<p class="text-neutral-700 dark:text-neutral-200">
|
|
Fillable forms for cooperative documents. Data saves locally in your
|
|
browser.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
<div
|
|
v-for="template in templates"
|
|
:key="template.id"
|
|
class="template-card h-full flex flex-col">
|
|
<div
|
|
class="absolute top-2 left-2 w-full h-full dither-shadow"></div>
|
|
<div
|
|
class="relative bg-white dark:bg-neutral-950 border border-black dark:border-white p-6 h-full flex flex-col">
|
|
<div class="mb-4">
|
|
<h3
|
|
class="text-xl font-semibold text-neutral-900 dark:text-white">
|
|
{{ template.name }}
|
|
</h3>
|
|
</div>
|
|
<p class="text-neutral-700 dark:text-neutral-200 mb-4">
|
|
{{ template.description }}
|
|
</p>
|
|
<div class="flex flex-wrap gap-2 mb-4">
|
|
<span
|
|
v-for="tag in template.tags"
|
|
:key="tag"
|
|
class="px-2 py-1 text-xs font-medium bg-white dark:bg-neutral-950 text-neutral-900 dark:text-neutral-900 border border-black dark:border-white dither-tag">
|
|
{{ tag }}
|
|
</span>
|
|
</div>
|
|
<div class="text-sm text-neutral-700 dark:text-neutral-200 mb-4">
|
|
<div class="flex items-center gap-4">
|
|
<span>{{ template.estimatedTime }}</span>
|
|
<span>{{ template.fields }} fields</span>
|
|
</div>
|
|
</div>
|
|
<div class="flex-1"></div>
|
|
<div class="flex gap-2 mt-auto">
|
|
<NuxtLink
|
|
:to="template.path"
|
|
class="flex-1 px-4 py-2 bg-black dark:bg-white text-white dark:text-black text-center font-medium tracking-wider hover:underline"
|
|
style="font-family: 'Ubuntu Mono', monospace">
|
|
START WIZARD
|
|
</NuxtLink>
|
|
<NuxtLink
|
|
v-if="hasData(template.id)"
|
|
:to="template.path"
|
|
class="px-4 py-2 bg-white dark:bg-neutral-950 text-black dark:text-white border border-black dark:border-white hover:bg-white dark:hover:bg-neutral-950 transition-colors bitmap-button"
|
|
title="Continue from saved data"
|
|
style="font-family: 'Ubuntu Mono', monospace">
|
|
RESUME
|
|
</NuxtLink>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed } from "vue";
|
|
|
|
const templates = [
|
|
{
|
|
id: "membership-agreement",
|
|
name: "Membership Agreement",
|
|
description:
|
|
"An agreement outlining member rights, responsibilities, decision-making processes, and financial arrangements.",
|
|
icon: "i-heroicons-user-group",
|
|
path: "/templates/membership-agreement",
|
|
tags: ["Legal", "Governance", "Membership"],
|
|
estimatedTime: "15-30 min",
|
|
fields: 25,
|
|
storageKey: "membership-agreement-data",
|
|
},
|
|
{
|
|
id: "conflict-resolution-framework",
|
|
name: "Conflict Resolution",
|
|
description:
|
|
"A framework for handling conflicts with restorative justice principles, clear processes, and organizational values alignment.",
|
|
icon: "i-heroicons-scale",
|
|
path: "/templates/conflict-resolution-framework",
|
|
tags: ["Governance", "Process", "Care"],
|
|
estimatedTime: "20-40 min",
|
|
fields: 35,
|
|
storageKey: "conflict-resolution-framework-data",
|
|
},
|
|
{
|
|
id: "tech-charter",
|
|
name: "Technology Charter",
|
|
description:
|
|
"How do you decide what technology and tools align with your values? This wizard helps you define principles, technical constraints, and evaluation criteria for tech selection.",
|
|
icon: "i-heroicons-cog-6-tooth",
|
|
path: "/templates/tech-charter",
|
|
tags: ["Technology", "Decision-Making", "Governance"],
|
|
estimatedTime: "10-20 min",
|
|
fields: 20,
|
|
storageKey: "tech-charter-data",
|
|
},
|
|
{
|
|
id: "decision-framework",
|
|
name: "Decision Framework Helper",
|
|
description:
|
|
"Need help deciding how to decide? This wizard guides you towards a decision-making approach based on urgency, expertise, stakes, and team dynamics.",
|
|
icon: "i-heroicons-light-bulb",
|
|
path: "/templates/decision-framework",
|
|
tags: ["Decision-Making", "Process", "Governance"],
|
|
estimatedTime: "5-10 min",
|
|
fields: 7,
|
|
storageKey: "decision-framework-data",
|
|
},
|
|
];
|
|
|
|
const hasData = (templateId) => {
|
|
const template = templates.find((t) => t.id === templateId);
|
|
if (!template?.storageKey) return false;
|
|
if (process.client) {
|
|
const saved = localStorage.getItem(template.storageKey);
|
|
return saved && saved !== "{}";
|
|
}
|
|
return false;
|
|
};
|
|
|
|
useHead({
|
|
title: "Wizards - Co-op Pay & Value Tool",
|
|
meta: [
|
|
{
|
|
name: "description",
|
|
content:
|
|
"Interactive wizards for worker cooperatives including membership agreements and governance documents.",
|
|
},
|
|
],
|
|
});
|
|
</script>
|
|
|
|
<style scoped>
|
|
.template-card {
|
|
@apply relative;
|
|
font-family: "Ubuntu", monospace;
|
|
}
|
|
|
|
.help-section {
|
|
@apply relative;
|
|
}
|
|
|
|
.coming-soon {
|
|
opacity: 0.7;
|
|
}
|
|
|
|
.dither-tag {
|
|
position: relative;
|
|
background: white;
|
|
}
|
|
.dither-tag::before {
|
|
content: "";
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background-image: repeating-linear-gradient(
|
|
45deg,
|
|
transparent 0px,
|
|
transparent 1px,
|
|
black 1px,
|
|
black 2px
|
|
);
|
|
opacity: 0.1;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.bitmap-button {
|
|
font-family: "Ubuntu Mono", monospace !important;
|
|
text-transform: uppercase;
|
|
font-weight: bold;
|
|
letter-spacing: 0.5px;
|
|
position: relative;
|
|
}
|
|
|
|
.bitmap-button:hover::after {
|
|
content: "";
|
|
position: absolute;
|
|
top: 1px;
|
|
left: 1px;
|
|
right: -1px;
|
|
bottom: -1px;
|
|
border: 1px solid black;
|
|
background: white;
|
|
z-index: -1;
|
|
}
|
|
</style>
|