added claim/owner routes and components, test fiber page
This commit is contained in:
parent
36ae15162a
commit
c93daeda4b
5 changed files with 422 additions and 195 deletions
53
components/claims/ClaimButton.tsx
Normal file
53
components/claims/ClaimButton.tsx
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
export default function ClaimButton({
|
||||
collection,
|
||||
id,
|
||||
disabledReason,
|
||||
}: {
|
||||
collection: 'settings_fiber' | 'settings_uv' | 'settings_co2gal' | 'settings_co2gan' | 'projects' | string;
|
||||
id: string | number;
|
||||
disabledReason?: string;
|
||||
}) {
|
||||
const [busy, setBusy] = useState(false);
|
||||
const [msg, setMsg] = useState<string | null>(null);
|
||||
|
||||
const submit = async () => {
|
||||
setBusy(true);
|
||||
setMsg(null);
|
||||
try {
|
||||
const res = await fetch('/api/claims', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ target_collection: collection, target_id: id }),
|
||||
});
|
||||
const data = await res.json().catch(() => ({}));
|
||||
if (res.ok) setMsg('✅ Claim submitted for review.');
|
||||
else setMsg(data?.message || '❌ Could not submit claim.');
|
||||
} catch {
|
||||
setMsg('❌ Network/auth error. Please sign in and try again.');
|
||||
} finally {
|
||||
setBusy(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-1">
|
||||
<button
|
||||
onClick={submit}
|
||||
disabled={busy || !!disabledReason}
|
||||
className={`px-3 py-1 rounded-md text-sm border ${
|
||||
disabledReason
|
||||
? 'opacity-60 cursor-not-allowed'
|
||||
: 'bg-accent text-background hover:opacity-90'
|
||||
}`}
|
||||
>
|
||||
{busy ? 'Submitting…' : 'Claim Ownership'}
|
||||
</button>
|
||||
{disabledReason ? <span className="text-xs text-muted-foreground">{disabledReason}</span> : null}
|
||||
{msg ? <span className="text-xs">{msg}</span> : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
25
components/common/OwnerBadge.tsx
Normal file
25
components/common/OwnerBadge.tsx
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
'use client';
|
||||
|
||||
export default function OwnerBadge({
|
||||
owner,
|
||||
uploader,
|
||||
className = '',
|
||||
}: {
|
||||
owner?: { id?: string | number; display_name?: string } | null;
|
||||
uploader?: string | null;
|
||||
className?: string;
|
||||
}) {
|
||||
const hasOwner = !!owner?.id;
|
||||
const label = hasOwner ? 'Owner' : 'Uploader';
|
||||
const name = owner?.display_name ?? uploader ?? '—';
|
||||
|
||||
return (
|
||||
<span
|
||||
className={`inline-flex items-center gap-2 text-xs px-2 py-1 rounded-md border border-border bg-card ${className}`}
|
||||
title={hasOwner ? 'Owner' : (uploader ? 'Original uploader' : '')}
|
||||
>
|
||||
<span className="opacity-70">{label}:</span>
|
||||
<span className="font-medium">{name}</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue