committed by
GitHub
parent
3fbc5c29ba
commit
58a29c1cc2
@@ -23,8 +23,7 @@ import {
|
||||
} from '@/components/ui/dropdown-menu';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Sparkles, Code, ChevronDown } from 'lucide-react';
|
||||
import { Sparkles, Code, ChevronDown, HandMetal } from 'lucide-react';
|
||||
import { EditorType, ProfileVariantLabel } from 'shared/types';
|
||||
import { useUserSystem } from '@/components/config-provider';
|
||||
|
||||
@@ -65,10 +64,10 @@ export function OnboardingDialog({ open, onComplete }: OnboardingDialogProps) {
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={() => {}}>
|
||||
<DialogContent className="sm:max-w-[600px]">
|
||||
<DialogContent className="sm:max-w-[600px] space-y-4">
|
||||
<DialogHeader>
|
||||
<div className="flex items-center gap-3">
|
||||
<Sparkles className="h-6 w-6 text-primary" />
|
||||
<HandMetal className="h-6 w-6 text-primary text-primary-foreground" />
|
||||
<DialogTitle>Welcome to Vibe Kanban</DialogTitle>
|
||||
</div>
|
||||
<DialogDescription className="text-left pt-2">
|
||||
@@ -76,159 +75,148 @@ export function OnboardingDialog({ open, onComplete }: OnboardingDialogProps) {
|
||||
later in Settings.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="space-y-2">
|
||||
<h2 className="text-xl flex items-center gap-2">
|
||||
<Sparkles className="h-4 w-4" />
|
||||
Choose Your Coding Agent
|
||||
</h2>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="profile">Default Profile</Label>
|
||||
<div className="flex gap-2">
|
||||
<Select
|
||||
value={profile.profile}
|
||||
onValueChange={(value) =>
|
||||
setProfile({ profile: value, variant: null })
|
||||
}
|
||||
>
|
||||
<SelectTrigger id="profile" className="flex-1">
|
||||
<SelectValue placeholder="Select your preferred coding agent" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{profiles?.map((profile) => (
|
||||
<SelectItem key={profile.label} value={profile.label}>
|
||||
{profile.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<div className="space-y-6 py-4">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2">
|
||||
<Sparkles className="h-4 w-4" />
|
||||
Choose Your Coding Agent
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="profile">Default Profile</Label>
|
||||
<div className="flex gap-2">
|
||||
<Select
|
||||
value={profile.profile}
|
||||
onValueChange={(value) =>
|
||||
setProfile({ profile: value, variant: null })
|
||||
}
|
||||
>
|
||||
<SelectTrigger id="profile" className="flex-1">
|
||||
<SelectValue placeholder="Select your preferred coding agent" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{profiles?.map((profile) => (
|
||||
<SelectItem key={profile.label} value={profile.label}>
|
||||
{profile.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{/* Show variant selector if selected profile has variants */}
|
||||
{(() => {
|
||||
const selectedProfile = profiles?.find(
|
||||
(p) => p.label === profile.profile
|
||||
);
|
||||
const hasVariants =
|
||||
selectedProfile?.variants &&
|
||||
selectedProfile.variants.length > 0;
|
||||
|
||||
{/* Show variant selector if selected profile has variants */}
|
||||
{(() => {
|
||||
const selectedProfile = profiles?.find(
|
||||
(p) => p.label === profile.profile
|
||||
);
|
||||
const hasVariants =
|
||||
selectedProfile?.variants &&
|
||||
selectedProfile.variants.length > 0;
|
||||
|
||||
if (hasVariants) {
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="w-24 px-2 flex items-center justify-between"
|
||||
>
|
||||
<span className="text-xs truncate flex-1 text-left">
|
||||
{profile.variant || 'Default'}
|
||||
</span>
|
||||
<ChevronDown className="h-3 w-3 ml-1 flex-shrink-0" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem
|
||||
onClick={() =>
|
||||
setProfile({ ...profile, variant: null })
|
||||
}
|
||||
className={!profile.variant ? 'bg-accent' : ''}
|
||||
>
|
||||
Default
|
||||
</DropdownMenuItem>
|
||||
{selectedProfile.variants.map((variant) => (
|
||||
<DropdownMenuItem
|
||||
key={variant.label}
|
||||
onClick={() =>
|
||||
setProfile({
|
||||
...profile,
|
||||
variant: variant.label,
|
||||
})
|
||||
}
|
||||
className={
|
||||
profile.variant === variant.label
|
||||
? 'bg-accent'
|
||||
: ''
|
||||
}
|
||||
>
|
||||
{variant.label}
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
);
|
||||
} else if (selectedProfile) {
|
||||
// Show disabled button when profile exists but has no variants
|
||||
return (
|
||||
if (hasVariants) {
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="w-24 px-2 flex items-center justify-between"
|
||||
disabled
|
||||
>
|
||||
<span className="text-xs truncate flex-1 text-left">
|
||||
Default
|
||||
{profile.variant || 'Default'}
|
||||
</span>
|
||||
<ChevronDown className="h-3 w-3 ml-1 flex-shrink-0" />
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
})()}
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem
|
||||
onClick={() =>
|
||||
setProfile({ ...profile, variant: null })
|
||||
}
|
||||
className={!profile.variant ? 'bg-accent' : ''}
|
||||
>
|
||||
Default
|
||||
</DropdownMenuItem>
|
||||
{selectedProfile.variants.map((variant) => (
|
||||
<DropdownMenuItem
|
||||
key={variant.label}
|
||||
onClick={() =>
|
||||
setProfile({
|
||||
...profile,
|
||||
variant: variant.label,
|
||||
})
|
||||
}
|
||||
className={
|
||||
profile.variant === variant.label
|
||||
? 'bg-accent'
|
||||
: ''
|
||||
}
|
||||
>
|
||||
{variant.label}
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
);
|
||||
} else if (selectedProfile) {
|
||||
// Show disabled button when profile exists but has no variants
|
||||
return (
|
||||
<Button
|
||||
variant="outline"
|
||||
className="w-24 px-2 flex items-center justify-between"
|
||||
disabled
|
||||
>
|
||||
<span className="text-xs truncate flex-1 text-left">
|
||||
Default
|
||||
</span>
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
})()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2">
|
||||
<Code className="h-4 w-4" />
|
||||
Choose Your Code Editor
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<h2 className="text-xl flex items-center gap-2">
|
||||
<Code className="h-4 w-4" />
|
||||
Choose Your Code Editor
|
||||
</h2>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="editor">Preferred Editor</Label>
|
||||
<Select
|
||||
value={editorType}
|
||||
onValueChange={(value: EditorType) => setEditorType(value)}
|
||||
>
|
||||
<SelectTrigger id="editor">
|
||||
<SelectValue placeholder="Select your preferred editor" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{Object.values(EditorType).map((type) => (
|
||||
<SelectItem key={type} value={type}>
|
||||
{toPrettyCase(type)}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
This editor will be used to open task attempts and project files.
|
||||
</p>
|
||||
|
||||
{editorType === EditorType.CUSTOM && (
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="editor">Preferred Editor</Label>
|
||||
<Select
|
||||
value={editorType}
|
||||
onValueChange={(value: EditorType) => setEditorType(value)}
|
||||
>
|
||||
<SelectTrigger id="editor">
|
||||
<SelectValue placeholder="Select your preferred editor" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{Object.values(EditorType).map((type) => (
|
||||
<SelectItem key={type} value={type}>
|
||||
{toPrettyCase(type)}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Label htmlFor="custom-command">Custom Command</Label>
|
||||
<Input
|
||||
id="custom-command"
|
||||
placeholder="e.g., code, subl, vim"
|
||||
value={customCommand}
|
||||
onChange={(e) => setCustomCommand(e.target.value)}
|
||||
/>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
This editor will be used to open task attempts and project
|
||||
files.
|
||||
Enter the command to run your custom editor. Use spaces for
|
||||
arguments (e.g., "code --wait").
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{editorType === EditorType.CUSTOM && (
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="custom-command">Custom Command</Label>
|
||||
<Input
|
||||
id="custom-command"
|
||||
placeholder="e.g., code, subl, vim"
|
||||
value={customCommand}
|
||||
onChange={(e) => setCustomCommand(e.target.value)}
|
||||
/>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Enter the command to run your custom editor. Use spaces for
|
||||
arguments (e.g., "code --wait").
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
} from '@/components/ui/dialog';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Shield, CheckCircle, XCircle, Settings } from 'lucide-react';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { useConfig } from '@/components/config-provider';
|
||||
|
||||
interface PrivacyOptInDialogProps {
|
||||
@@ -39,7 +38,7 @@ export function PrivacyOptInDialog({
|
||||
<DialogContent className="sm:max-w-[700px]">
|
||||
<DialogHeader>
|
||||
<div className="flex items-center gap-3">
|
||||
<Shield className="h-6 w-6 text-primary" />
|
||||
<Shield className="h-6 w-6 text-primary text-primary-foreground" />
|
||||
<DialogTitle>Feedback Opt-In</DialogTitle>
|
||||
</div>
|
||||
<DialogDescription className="text-left pt-1">
|
||||
@@ -48,62 +47,54 @@ export function PrivacyOptInDialog({
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="space-y-3 py-3">
|
||||
<Card>
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-base">
|
||||
What data do we collect?
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-2 pt-0">
|
||||
{isGitHubAuthenticated && (
|
||||
<div className="flex items-start gap-2">
|
||||
<CheckCircle className="h-4 w-4 text-green-500 mt-0.5 flex-shrink-0" />
|
||||
<div className="min-w-0">
|
||||
<p className="text-sm font-medium">
|
||||
GitHub profile information
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Username and email address to send you only very important
|
||||
updates about the project. We promise not to abuse this
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="space-y-3">
|
||||
<h2>What data do we collect?</h2>
|
||||
<div>
|
||||
{isGitHubAuthenticated && (
|
||||
<div className="flex items-start gap-2">
|
||||
<CheckCircle className="h-4 w-4 text-green-500 mt-0.5 flex-shrink-0" />
|
||||
<div className="min-w-0">
|
||||
<p className="text-sm font-medium">
|
||||
High-level usage metrics
|
||||
GitHub profile information
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Number of tasks created, projects managed, feature usage
|
||||
Username and email address to send you only very important
|
||||
updates about the project. We promise not to abuse this
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-2">
|
||||
<CheckCircle className="h-4 w-4 text-green-500 mt-0.5 flex-shrink-0" />
|
||||
<div className="min-w-0">
|
||||
<p className="text-sm font-medium">
|
||||
Performance and error data
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Application crashes, response times, technical issues
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex items-start gap-2">
|
||||
<CheckCircle className="h-4 w-4 text-green-500 mt-0.5 flex-shrink-0" />
|
||||
<div className="min-w-0">
|
||||
<p className="text-sm font-medium">High-level usage metrics</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Number of tasks created, projects managed, feature usage
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-start gap-2">
|
||||
<XCircle className="h-4 w-4 text-destructive mt-0.5 flex-shrink-0" />
|
||||
<div className="min-w-0">
|
||||
<p className="text-sm font-medium">We do NOT collect</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Task contents, code snippets, project names, or other
|
||||
personal data
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-2">
|
||||
<CheckCircle className="h-4 w-4 text-green-500 mt-0.5 flex-shrink-0" />
|
||||
<div className="min-w-0">
|
||||
<p className="text-sm font-medium">
|
||||
Performance and error data
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Application crashes, response times, technical issues
|
||||
</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
<div className="flex items-start gap-2">
|
||||
<XCircle className="h-4 w-4 text-destructive mt-0.5 flex-shrink-0" />
|
||||
<div className="min-w-0">
|
||||
<p className="text-sm font-medium">We do NOT collect</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Task contents, code snippets, project names, or other personal
|
||||
data
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 text-xs text-muted-foreground bg-muted/50 p-2 rounded-lg">
|
||||
<Settings className="h-3 w-3 flex-shrink-0" />
|
||||
|
||||
@@ -10,13 +10,12 @@ const buttonVariants = cva(
|
||||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
'bg-primary text-primary-foreground hover:bg-primary/90 border border-foreground',
|
||||
'text-primary-foreground hover:bg-primary/90 border border-foreground',
|
||||
destructive:
|
||||
'bg-destructive text-destructive-foreground hover:bg-destructive/90',
|
||||
outline:
|
||||
'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
|
||||
secondary:
|
||||
'bg-secondary text-secondary-foreground hover:bg-secondary/80 border',
|
||||
'border border-input hover:bg-accent hover:text-accent-foreground',
|
||||
secondary: 'text-secondary-foreground hover:bg-secondary/80 border',
|
||||
ghost: 'hover:text-primary-foreground/50',
|
||||
link: 'hover:underline',
|
||||
},
|
||||
|
||||
@@ -30,7 +30,7 @@ const Dialog = React.forwardRef<
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'relative z-[9999] grid w-full max-w-lg gap-4 bg-background p-6 shadow-lg duration-200 sm:rounded-lg my-8',
|
||||
'relative z-[9999] grid w-full max-w-lg gap-4 bg-primary p-6 shadow-lg duration-200 sm:rounded-lg my-8',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -25,7 +25,7 @@ const DropdownMenuSubTrigger = React.forwardRef<
|
||||
<DropdownMenuPrimitive.SubTrigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
||||
'flex cursor-default select-none items-center gap-2 px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
||||
inset && 'pl-8',
|
||||
className
|
||||
)}
|
||||
@@ -45,7 +45,7 @@ const DropdownMenuSubContent = React.forwardRef<
|
||||
<DropdownMenuPrimitive.SubContent
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'z-[10000] min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-dropdown-menu-content-transform-origin]',
|
||||
'z-[10000] min-w-[8rem] overflow-hidden border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-dropdown-menu-content-transform-origin]',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -63,7 +63,7 @@ const DropdownMenuContent = React.forwardRef<
|
||||
ref={ref}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
'z-[10000] max-h-[var(--radix-dropdown-menu-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-dropdown-menu-content-transform-origin]',
|
||||
'z-[10000] max-h-[var(--radix-dropdown-menu-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden border p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-dropdown-menu-content-transform-origin]',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -81,7 +81,7 @@ const DropdownMenuItem = React.forwardRef<
|
||||
<DropdownMenuPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
||||
'relative flex cursor-default select-none items-center gap-2 px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
||||
inset && 'pl-8',
|
||||
className
|
||||
)}
|
||||
@@ -97,7 +97,7 @@ const DropdownMenuCheckboxItem = React.forwardRef<
|
||||
<DropdownMenuPrimitive.CheckboxItem
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
'relative flex cursor-default select-none items-center py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
className
|
||||
)}
|
||||
checked={checked}
|
||||
@@ -121,7 +121,7 @@ const DropdownMenuRadioItem = React.forwardRef<
|
||||
<DropdownMenuPrimitive.RadioItem
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
'relative flex cursor-default select-none items-center py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -11,7 +11,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
||||
<input
|
||||
type={type}
|
||||
className={cn(
|
||||
'flex h-10 w-full rounded-md border bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',
|
||||
'flex h-10 w-full border px-3 py-2 text-sm ring-offset-background file:border-0 bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',
|
||||
className
|
||||
)}
|
||||
ref={ref}
|
||||
|
||||
@@ -19,7 +19,7 @@ const SelectTrigger = React.forwardRef<
|
||||
<SelectPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
|
||||
'flex h-10 w-full items-center justify-between border border-input px-3 py-2 text-sm ring-offset-background data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -75,7 +75,7 @@ const SelectContent = React.forwardRef<
|
||||
<SelectPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'relative z-[10000] max-h-[--radix-select-content-available-height] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-select-content-transform-origin]',
|
||||
'relative z-[10000] max-h-[--radix-select-content-available-height] min-w-[8rem] overflow-y-auto overflow-x-hidden border bg-primary text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-select-content-transform-origin]',
|
||||
position === 'popper' &&
|
||||
'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
|
||||
className
|
||||
@@ -118,7 +118,7 @@ const SelectItem = React.forwardRef<
|
||||
<SelectPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
'relative flex w-full cursor-default select-none items-center py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -96,7 +96,7 @@ export const KanbanCard = ({
|
||||
return (
|
||||
<Card
|
||||
className={cn(
|
||||
'p-3 focus:ring-2 outline-none border-b flex-col space-y-2',
|
||||
'p-3 focus:ring-2 ring-secondary-foreground outline-none border-b flex-col space-y-2',
|
||||
isDragging && 'cursor-grabbing',
|
||||
className
|
||||
)}
|
||||
|
||||
@@ -315,7 +315,7 @@ export function ProjectTasks() {
|
||||
{/* Left Column - Kanban Section */}
|
||||
<div className={getKanbanSectionClasses(isPanelOpen, isFullscreen)}>
|
||||
{tasks.length === 0 ? (
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="max-w-7xl mx-auto mt-8">
|
||||
<Card>
|
||||
<CardContent className="text-center py-8">
|
||||
<p className="text-muted-foreground">
|
||||
|
||||
Reference in New Issue
Block a user