mirror of
https://github.com/Since-3/since3-portal.git
synced 2026-10-12 21:41:16 +00:00
see comments
This commit is contained in:
parent
5edd697056
commit
b252264211
4 changed files with 34 additions and 9 deletions
|
|
@ -1,5 +1,6 @@
|
|||
"use server";
|
||||
import { createAdminClient } from "@/lib/supabase/admin";
|
||||
import { verifySession } from "@/lib/supabase/dal";
|
||||
import { generatePassword } from "@/lib/generate-password";
|
||||
import * as z from "zod";
|
||||
|
||||
|
|
@ -20,6 +21,11 @@ export async function createClient(
|
|||
formData: FormData
|
||||
): Promise<CreateClientState> {
|
||||
|
||||
const session = await verifySession();
|
||||
if (!session.isAdmin) {
|
||||
return { error: "Keine Berechtigung." }
|
||||
}
|
||||
|
||||
const validatedFields = CreateClientSchema.safeParse({
|
||||
name: formData.get("name"),
|
||||
email: formData.get("email")
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export async function getClients() {
|
|||
.eq("role", "client")
|
||||
.order("name")
|
||||
|
||||
if (error) return []
|
||||
if (error) throw new Error(`Failed to load clients: ${error.message}`)
|
||||
|
||||
return data
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,31 @@
|
|||
"use client"
|
||||
|
||||
import { useState } from "react";
|
||||
import { useRef, useState } from "react";
|
||||
import { CheckIcon, CopyIcon } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Field, FieldLabel } from "@/components/ui/field";
|
||||
|
||||
export function CopyField({ label, value }: { label: string; value: string }) {
|
||||
const [copied, setCopied] = useState(false);
|
||||
const [status, setStatus] = useState<"idle" | "copied" | "error">("idle");
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
async function handleCopy() {
|
||||
await navigator.clipboard.writeText(value);
|
||||
setCopied(true);
|
||||
setTimeout(() => setCopied(false), 1500);
|
||||
try {
|
||||
await navigator.clipboard.writeText(value);
|
||||
setStatus("copied");
|
||||
} catch {
|
||||
inputRef.current?.select();
|
||||
setStatus("error");
|
||||
}
|
||||
setTimeout(() => setStatus("idle"), 1500);
|
||||
}
|
||||
|
||||
return (
|
||||
<Field>
|
||||
<FieldLabel>{label}</FieldLabel>
|
||||
<div className="flex items-center gap-2">
|
||||
<Input value={value} readOnly className="focus-visible:ring-0" />
|
||||
<Input ref={inputRef} value={value} readOnly className="focus-visible:ring-0" />
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
|
|
@ -28,9 +34,18 @@ export function CopyField({ label, value }: { label: string; value: string }) {
|
|||
onClick={handleCopy}
|
||||
aria-label={`${label} kopieren`}
|
||||
>
|
||||
{copied ? <CheckIcon className="text-signal-success" /> : <CopyIcon />}
|
||||
{status === "copied" ? (
|
||||
<CheckIcon className="text-signal-success" />
|
||||
) : (
|
||||
<CopyIcon />
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
{status === "error" && (
|
||||
<p className="text-small text-destructive">
|
||||
Kopieren fehlgeschlagen — Text wurde markiert, bitte manuell kopieren.
|
||||
</p>
|
||||
)}
|
||||
</Field>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue