Generate print-ready name tags in TownStix US-10 format (4" x 2" labels, 10 per sheet) from CSV files or Google Sheets with flexible column mapping and HTML/PDF export.
This skill has safety concerns that you should review before use. Some patterns were detected that may pose a risk.Safety score: 60/100.
KillerSkills scans all public content for safety. Use caution before installing or executing flagged content.
Generate print-ready name tags in the TownStix US-10 format (4" x 2" labels, 10 per sheet) from CSV files or Google Sheets. Features an intuitive multi-step wizard with flexible column mapping and both HTML and PDF export options.
This skill helps you work with a Nuxt 4 application that transforms CSV data or Google Sheets into professionally formatted name tag labels. The application provides a three-step wizard flow: upload data, map columns to name tag lines (with customizable 3-line format), and preview/export as HTML or PDF.
**Key Features:**
**Wizard Flow:**
**State Management:**
The app uses composables (not stores) for shared state:
**API Endpoints:**
**Server Utilities Pipeline:**
```
CSV Data → parseRawData() → parseCSVToPagesWithMapping() → generateNameTagsHTML() → generatePDF()
```
**Component Architecture:** Follows atomic design (atoms/molecules/organisms in `app/components/`)
**TypeScript Types:** All core types in `types/index.d.ts` (NameTagRow, NameTagPage, ColumnMapping, ParsedData, etc.)
**Start development:**
```bash
pnpm dev # http://localhost:3000
```
**Code quality checks:**
```bash
pnpm check:all # Lint + format check + deadcode
pnpm fix:all # Auto-fix issues
```
**Build and preview:**
```bash
pnpm build
pnpm preview
```
**Adding a new wizard step:**
1. Add to `WizardStep` type in `types/index.d.ts`
2. Update `useWizardNavigation` composable logic
3. Create new step component in `app/components/organisms/`
4. Wire into `NameTagWizard.vue`
**Creating a new API endpoint:**
1. Create `server/api/[name].post.ts`
2. Use `defineEventHandler` wrapper
3. Add corresponding types to `types/index.d.ts`
4. Update relevant composable to call new endpoint
**Adding a new component:**
1. Determine level: atom/molecule/organism
2. Create in appropriate `app/components/` subdirectory
3. Use component-scoped PostCSS (not inline Tailwind)
4. Follow glassmorphism design patterns from existing components
**Modifying label format:**
**Working with feature flags:**
1. Define in `feature-flags.config.ts`
2. Use `const { isEnabled } = useFeatureFlags()` in components
3. Check `docs/ADSENSE_SEO_SETUP.md` for AdSense flag example
**Use component-scoped PostCSS with semantic class names:**
```vue
<template>
<div class="glass-card">
<slot />
</div>
</template>
<style lang="postcss" scoped>
.glass-card {
@apply relative overflow-hidden rounded-xl border;
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(12px);
border-color: rgba(255, 255, 255, 0.1);
}
</style>
```
**Why:** Single source of truth, easier to maintain than long utility strings.
**Global styles:** `app/assets/css/main.css` (Plus Jakarta Sans font, scrollbar styling)
**Two-layer approach:**
1. **Verification (always present):** Meta tag in `nuxt.config.ts` → `app.head.meta` for site ownership
2. **Ad display (feature flag):** Script loading in `app/app.vue` → `useHead()` when `adsense` flag enabled
```typescript
// feature-flags.config.ts
export default defineFeatureFlags(() => ({
adsense: { enabled: false, description: 'Google AdSense integration' },
newFeature: { enabled: true, description: 'My new feature' }
}))
```
```vue
<!-- Component usage -->
<script setup lang="ts">
const { isEnabled } = useFeatureFlags()
const showNewFeature = isEnabled('newFeature')
</script>
```
```typescript
// server/api/custom.post.ts
export default defineEventHandler(async (event) => {
const body = await readBody(event)
// Process data
const result = processData(body)
return {
success: true,
data: result
}
})
```
```vue
<!-- app/components/molecules/CustomCard.vue -->
<template>
<div class="custom-card">
<h3 class="card-title">{{ title }}</h3>
<p class="card-content">{{ content }}</p>
</div>
</template>
<script setup lang="ts">
interface Props {
title: string
content: string
}
defineProps<Props>()
</script>
<style lang="postcss" scoped>
.custom-card {
@apply rounded-lg border p-6;
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(12px);
}
.card-title {
@apply text-lg font-semibold mb-2;
}
.card-content {
@apply text-sm text-gray-600 dark:text-gray-400;
}
</style>
```
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/townstix-name-tag-generator/raw