chore: update application configuration and UI components for improved styling and functionality
This commit is contained in:
parent
0af6b17792
commit
37ab8d7bab
54 changed files with 23293 additions and 1666 deletions
369
pages/templates/index.vue
Normal file
369
pages/templates/index.vue
Normal file
|
|
@ -0,0 +1,369 @@
|
|||
<template>
|
||||
<div
|
||||
class="template-container min-h-screen bg-white dark:bg-neutral-950 text-neutral-900 dark:text-neutral-100 py-8"
|
||||
style="font-family: 'Ubuntu', 'Ubuntu Mono', monospace">
|
||||
<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"
|
||||
style="font-family: 'Ubuntu', monospace">
|
||||
Document Templates
|
||||
</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">
|
||||
<!-- Dithered shadow background -->
|
||||
<div class="absolute top-2 left-2 w-full h-full dither-shadow"></div>
|
||||
|
||||
<!-- Main content -->
|
||||
<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>
|
||||
|
||||
<!-- Spacer to push buttons to bottom -->
|
||||
<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 border border-black dark:border-white hover:bg-black dark:hover:bg-white transition-colors text-center font-medium bitmap-button"
|
||||
style="font-family: 'Ubuntu Mono', monospace">
|
||||
START TEMPLATE
|
||||
</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>
|
||||
|
||||
<!-- Help Section -->
|
||||
<div class="mt-12 help-section">
|
||||
<!-- Dithered shadow background -->
|
||||
<div class="absolute top-2 left-2 w-full h-full dither-shadow"></div>
|
||||
|
||||
<!-- Main content -->
|
||||
<div
|
||||
class="relative bg-white dark:bg-neutral-950 border border-black dark:border-white p-6">
|
||||
<h2
|
||||
class="text-xl font-semibold text-neutral-900 dark:text-white mb-3"
|
||||
style="font-family: 'Ubuntu', monospace">
|
||||
How Templates Work
|
||||
</h2>
|
||||
<div
|
||||
class="grid md:grid-cols-2 gap-6 text-neutral-900 dark:text-neutral-100">
|
||||
<div>
|
||||
<h3
|
||||
class="font-medium mb-2 text-neutral-900 dark:text-white"
|
||||
style="font-family: 'Ubuntu Mono', monospace">
|
||||
FILL OUT FORMS
|
||||
</h3>
|
||||
<p class="text-sm text-neutral-700 dark:text-neutral-200">
|
||||
Templates include form fields for all necessary information.
|
||||
Data auto-saves as you type.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3
|
||||
class="font-medium mb-2 text-neutral-900 dark:text-white"
|
||||
style="font-family: 'Ubuntu Mono', monospace">
|
||||
LOCAL STORAGE
|
||||
</h3>
|
||||
<p class="text-sm text-neutral-700 dark:text-neutral-200">
|
||||
All data saves in your browser only. Nothing is sent to external
|
||||
servers.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3
|
||||
class="font-medium mb-2 text-neutral-900 dark:text-white"
|
||||
style="font-family: 'Ubuntu Mono', monospace">
|
||||
EXPORT OPTIONS
|
||||
</h3>
|
||||
<p class="text-sm text-neutral-700 dark:text-neutral-200">
|
||||
Download as PDF (print), plain text, Markdown, or Word document.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3
|
||||
class="font-medium mb-2 text-neutral-900 dark:text-white"
|
||||
style="font-family: 'Ubuntu Mono', monospace">
|
||||
RESUME ANYTIME
|
||||
</h3>
|
||||
<p class="text-sm text-neutral-700 dark:text-neutral-200">
|
||||
Come back later and your progress will be saved. Clear browser
|
||||
data to start fresh.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from "vue";
|
||||
|
||||
const templates = [
|
||||
{
|
||||
id: "membership-agreement",
|
||||
name: "Membership Agreement",
|
||||
description:
|
||||
"A comprehensive agreement outlining member rights, responsibilities, decision-making processes, and financial arrangements for worker cooperatives.",
|
||||
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 Framework",
|
||||
description:
|
||||
"A customizable 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:
|
||||
"Build technology decisions on cooperative values. Define principles, technical constraints, and evaluation criteria for vendor 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:
|
||||
"Interactive tool to help determine the best 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;
|
||||
};
|
||||
|
||||
// Remove the JavaScript background handler since we're using CSS classes
|
||||
|
||||
useHead({
|
||||
title: "Document Templates - Co-op Pay & Value Tool",
|
||||
meta: [
|
||||
{
|
||||
name: "description",
|
||||
content:
|
||||
"Fillable document templates for worker cooperatives including membership agreements and governance documents.",
|
||||
},
|
||||
],
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* Ubuntu font import */
|
||||
@import url("https://fonts.googleapis.com/css2?family=Ubuntu:wght@300;400;500;700&family=Ubuntu+Mono:wght@400;700&display=swap");
|
||||
|
||||
/* Removed full-screen dither pattern to avoid gray haze in dark mode */
|
||||
|
||||
/* Exact shadow style from value-flow inspiration */
|
||||
.dither-shadow {
|
||||
background: black;
|
||||
background-image: radial-gradient(white 1px, transparent 1px);
|
||||
background-size: 2px 2px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.dither-shadow {
|
||||
background: white;
|
||||
background-image: radial-gradient(black 1px, transparent 1px);
|
||||
}
|
||||
}
|
||||
|
||||
:global(.dark) .dither-shadow {
|
||||
background: white;
|
||||
background-image: radial-gradient(black 1px, transparent 1px);
|
||||
}
|
||||
|
||||
.dither-shadow-disabled {
|
||||
background: black;
|
||||
background-image: radial-gradient(white 1px, transparent 1px);
|
||||
background-size: 2px 2px;
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.dither-shadow-disabled {
|
||||
background: white;
|
||||
background-image: radial-gradient(black 1px, transparent 1px);
|
||||
}
|
||||
}
|
||||
|
||||
:global(.dark) .dither-shadow-disabled {
|
||||
background: white;
|
||||
background-image: radial-gradient(black 1px, transparent 1px);
|
||||
}
|
||||
|
||||
/* Rely on Tailwind bg utilities on container */
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
/* Button styling - pure bitmap, no colors */
|
||||
.bitmap-button {
|
||||
font-family: "Ubuntu Mono", monospace !important;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
letter-spacing: 0.5px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.bitmap-button:hover {
|
||||
transform: translateY(-1px) translateX(-1px);
|
||||
transition: transform 0.1s ease;
|
||||
}
|
||||
|
||||
.bitmap-button:hover::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
left: 1px;
|
||||
right: -1px;
|
||||
bottom: -1px;
|
||||
border: 1px solid black;
|
||||
background: white;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.disabled-button {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Remove any inherited rounded corners */
|
||||
.template-card > *,
|
||||
.help-section > *,
|
||||
button,
|
||||
.px-4,
|
||||
div[class*="border"] {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
/* Button hover effects with bitmap feel */
|
||||
.template-card .relative:hover {
|
||||
transform: translateY(-1px);
|
||||
transition: transform 0.1s ease;
|
||||
}
|
||||
|
||||
/* Ensure sharp edges on all elements */
|
||||
* {
|
||||
border-radius: 0 !important;
|
||||
font-family: "Ubuntu", monospace;
|
||||
}
|
||||
|
||||
html.dark :deep(.text-neutral-700),
|
||||
html.dark :deep(.text-neutral-500),
|
||||
html.dark :deep(.bg-neutral-50),
|
||||
html.dark :deep(.bg-neutral-100) {
|
||||
color: white !important;
|
||||
background-color: #0a0a0a !important;
|
||||
}
|
||||
|
||||
:deep(.border-neutral-200),
|
||||
:deep(.border-neutral-300) {
|
||||
border-color: black !important;
|
||||
}
|
||||
</style>
|
||||
Loading…
Add table
Add a link
Reference in a new issue