Files
wkhandClaude Opus 5.5 e14bada114 Add Rails backend: accounts via magic link, server documents, sharing
The app becomes a Rails 8 application; the Vue frontend moves to
app/frontend and is served through vite_rails.

- Without an account documents stay in the browser (IndexedDB). Sign-in
  is by magic link or the 6-digit code from the same mail; afterwards
  local documents can be uploaded into the account.
- Server documents (/d/<id>) with versioned saves and a single-editor
  lock per browser tab; others see them read-only and follow by polling.
- Sharing via link (works without an account) and via e-mail invitation,
  roles viewer/editor; the owner manages links and people.
- Store gains a read-only mode that blocks all content changes.
- Solid Queue, Cache and Cable share the one PostgreSQL database.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 20:09:06 +02:00

124 lines
3.7 KiB
Vue

<script setup lang="ts">
/**
* Small hand-drawn line-icon set for the toolbar (no icon library/font —
* consistent with this project's "nothing off the shelf" approach). One
* shared <svg> shell (24x24, stroke-only) with a name-keyed set of shapes,
* since every icon needs the exact same viewBox/stroke setup and only the
* inner geometry differs.
*/
export type ToolbarIconName =
| 'settings'
| 'undo'
| 'redo'
| 'table'
| 'chart'
| 'text'
| 'tag'
| 'button'
| 'macro'
| 'sun'
| 'moon'
| 'auto';
defineProps<{ name: ToolbarIconName }>();
</script>
<template>
<svg
class="ti"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.75"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<template v-if="name === 'settings'">
<line x1="3" y1="6" x2="21" y2="6" />
<circle cx="9" cy="6" r="2" fill="currentColor" />
<line x1="3" y1="12" x2="21" y2="12" />
<circle cx="15" cy="12" r="2" fill="currentColor" />
<line x1="3" y1="18" x2="21" y2="18" />
<circle cx="7" cy="18" r="2" fill="currentColor" />
</template>
<template v-else-if="name === 'undo'">
<path d="M7 10 H15 a4 4 0 0 1 0 8 h-3" />
<polyline points="7 10 11 6" />
<polyline points="7 10 11 14" />
</template>
<template v-else-if="name === 'redo'">
<path d="M17 10 H9 a4 4 0 0 0 0 8 h3" />
<polyline points="17 10 13 6" />
<polyline points="17 10 13 14" />
</template>
<template v-else-if="name === 'table'">
<rect x="3" y="4" width="18" height="16" rx="2" />
<line x1="3" y1="10" x2="21" y2="10" />
<line x1="3" y1="16" x2="21" y2="16" />
<line x1="9" y1="4" x2="9" y2="20" />
<line x1="15" y1="4" x2="15" y2="20" />
</template>
<template v-else-if="name === 'chart'">
<line x1="4" y1="20" x2="20" y2="20" />
<rect x="6" y="13" width="3" height="7" />
<rect x="11" y="9" width="3" height="11" />
<rect x="16" y="5" width="3" height="15" />
</template>
<template v-else-if="name === 'text'">
<rect x="4" y="4" width="16" height="16" rx="2" />
<line x1="7" y1="9" x2="17" y2="9" />
<line x1="7" y1="13" x2="17" y2="13" />
<line x1="7" y1="17" x2="13" y2="17" />
</template>
<template v-else-if="name === 'tag'">
<polygon points="4,5 14,5 20,11 14,17 4,17" />
<circle cx="9" cy="9" r="1.6" fill="currentColor" />
</template>
<template v-else-if="name === 'button'">
<rect x="3" y="7" width="18" height="10" rx="3" />
<polygon points="10,10.5 10,13.5 13,12" fill="currentColor" stroke="none" />
</template>
<template v-else-if="name === 'macro'">
<polygon points="6,4 20,12 6,20" fill="currentColor" stroke="none" />
</template>
<template v-else-if="name === 'sun'">
<circle cx="12" cy="12" r="4.5" />
<line x1="12" y1="2.5" x2="12" y2="5" />
<line x1="12" y1="19" x2="12" y2="21.5" />
<line x1="2.5" y1="12" x2="5" y2="12" />
<line x1="19" y1="12" x2="21.5" y2="12" />
<line x1="4.9" y1="4.9" x2="6.7" y2="6.7" />
<line x1="17.3" y1="17.3" x2="19.1" y2="19.1" />
<line x1="4.9" y1="19.1" x2="6.7" y2="17.3" />
<line x1="17.3" y1="6.7" x2="19.1" y2="4.9" />
</template>
<template v-else-if="name === 'moon'">
<path d="M20 14.5A8.5 8.5 0 1 1 9.5 4 6.6 6.6 0 0 0 20 14.5Z" fill="currentColor" stroke="none" />
</template>
<template v-else-if="name === 'auto'">
<circle cx="12" cy="12" r="8.5" />
<path d="M12 3.5 A8.5 8.5 0 0 1 12 20.5 Z" fill="currentColor" stroke="none" />
</template>
</svg>
</template>
<style scoped>
.ti {
width: 17px;
height: 17px;
display: block;
}
</style>