scope-select.tsx2.0 KBView on GitHub 'use client';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { Label } from '@/components/ui/label';
import type { ReactNode } from 'react';
/**
* "Who can use it": the one selector for user-versus-org scope in this section.
*
* Both forms ask the same question about the same two scopes, and when each owned its
* own copy the two non-admin notes had already drifted into different wording for the
* same rule. That is the failure `INSTRUCTIONS_HELP` was hoisted to stop, so the
* shared sentence lives here and only the part that genuinely differs per form, what
* choosing "org" means for THAT kind of entry, is passed in.
*
* The org option is disabled rather than hidden for a non-admin: the option existing is
* how they learn org sharing is possible and who to ask for it.
*/
export function ScopeSelect({
id,
value,
onChange,
isOrgAdmin,
disabled = false,
orgNote,
}: {
id: string;
value: 'user' | 'org';
onChange: (scope: 'user' | 'org') => void;
isOrgAdmin: boolean;
disabled?: boolean;
/** Shown to an admin who has selected "org". What sharing costs for this entry kind. */
orgNote?: ReactNode;
}) {
return (
<div className="space-y-2">
<Label htmlFor={id}>Who can use it</Label>
<Select
value={value}
disabled={disabled}
onValueChange={(next) => onChange(next === 'org' ? 'org' : 'user')}
>
<SelectTrigger id={id}>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="user">Just me</SelectItem>
<SelectItem value="org" disabled={!isOrgAdmin}>
Everyone in my organization
</SelectItem>
</SelectContent>
</Select>
{!isOrgAdmin ? (
<p className="text-muted-foreground text-xs">
Only an organization admin can share this with everyone.
</p>
) : (
value === 'org' && orgNote && <p className="text-muted-foreground text-xs">{orgNote}</p>
)}
</div>
);
}