Add account hierarchy framework with migrations, RLS policies, and UI components

This commit is contained in:
T. Zehetbauer
2026-03-31 22:18:04 +02:00
parent 7e7da0b465
commit 59546ad6d2
262 changed files with 11671 additions and 3927 deletions

View File

@@ -73,7 +73,7 @@ export function GenerateDocumentForm({ accountSlug, initialType }: Props) {
setSelectedType(e.target.value);
setResult(null);
}}
className="border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2"
className="border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-sm focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none"
>
<option value="member-card">Mitgliedsausweis</option>
<option value="invoice">Rechnung</option>
@@ -92,7 +92,8 @@ export function GenerateDocumentForm({ accountSlug, initialType }: Props) {
<p className="font-medium">Demnächst verfügbar</p>
<p className="mt-1 text-amber-700 dark:text-amber-300">
Die Generierung von &ldquo;{DOCUMENT_LABELS[selectedType]}&rdquo;
befindet sich noch in Entwicklung und wird in Kürze verfügbar sein.
befindet sich noch in Entwicklung und wird in Kürze verfügbar
sein.
</p>
</div>
</div>
@@ -118,7 +119,7 @@ export function GenerateDocumentForm({ accountSlug, initialType }: Props) {
id="format"
name="format"
disabled={isPending}
className="border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:opacity-50"
className="border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-sm focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:opacity-50"
>
<option value="A4">A4</option>
<option value="A5">A5</option>
@@ -131,7 +132,7 @@ export function GenerateDocumentForm({ accountSlug, initialType }: Props) {
id="orientation"
name="orientation"
disabled={isPending}
className="border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:opacity-50"
className="border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-sm focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:opacity-50"
>
<option value="portrait">Hochformat</option>
<option value="landscape">Querformat</option>
@@ -140,7 +141,7 @@ export function GenerateDocumentForm({ accountSlug, initialType }: Props) {
</div>
{/* Hint */}
<div className="text-muted-foreground rounded-md bg-muted/50 p-4 text-sm">
<div className="text-muted-foreground bg-muted/50 rounded-md p-4 text-sm">
<p>
<strong>Hinweis:</strong>{' '}
{selectedType === 'member-card'
@@ -211,11 +212,7 @@ export function GenerateDocumentForm({ accountSlug, initialType }: Props) {
* Trigger a browser download from a base64 string.
* Uses an anchor element with the download attribute set to the full filename.
*/
function downloadFile(
base64Data: string,
mimeType: string,
fileName: string,
) {
function downloadFile(base64Data: string, mimeType: string, fileName: string) {
const byteCharacters = atob(base64Data);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {