mirror of
https://github.com/coleam00/Archon.git
synced 2025-12-24 02:39:17 -05:00
Fixes from biome and consistency review.
This commit is contained in:
@@ -234,6 +234,36 @@ Save to `PRPs/reviews/ui-consistency-review-[feature].md`.
|
||||
|
||||
**Note**: The PRPs/reviews/ directory is gitignored and won't be committed.
|
||||
|
||||
### Step 7: Create Implementation PRP
|
||||
|
||||
After completing the review report, **immediately create a PRP** for implementing the fixes using the review findings.
|
||||
|
||||
**CRITICAL**: Do not stop after generating the report. The review is only the first phase - the PRP creation is required.
|
||||
|
||||
**Use**: `/prp-claude-code:prp-claude-code-create` command with argument: `ui-consistency-fixes-[feature]`
|
||||
|
||||
**PRP Should Include**:
|
||||
1. **Feature Goal**: Fix all UI consistency violations identified in the review
|
||||
2. **Context**: Reference the review report and specific violations with file:line numbers
|
||||
3. **Implementation Tasks**: Ordered by priority (Critical → High → Medium → Low)
|
||||
- Each task should reference specific violations from the review
|
||||
- Include exact code snippets for fixes (from review report)
|
||||
- Use dependency ordering (e.g., fix unconstrained scrolls before testing)
|
||||
4. **Validation Gates**:
|
||||
- Re-run automated scans from Step 3
|
||||
- Verify all violations are fixed
|
||||
- Test responsive behavior at all breakpoints (375px, 768px, 1024px, 1440px)
|
||||
5. **Success Metrics**:
|
||||
- Zero violations in automated scans
|
||||
- All scores improved to 10/10
|
||||
- Overall grade improved to A or A+
|
||||
|
||||
**PRP Template Sections to Emphasize**:
|
||||
- **codebase_patterns**: Link to review report and UI_STANDARDS.md sections violated
|
||||
- **existing_code**: Include specific file:line references from violation findings
|
||||
- **implementation_notes**: Include "why this matters" context from review report
|
||||
- **edge_cases**: Include responsive testing requirements and dark mode validation
|
||||
|
||||
---
|
||||
|
||||
Start the review now.
|
||||
Start the review now and create the PRP when complete.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Layout, Palette } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { PillNavigation, type PillNavigationItem } from "@/features/ui/primitives/pill-navigation";
|
||||
import { ThemeToggle } from "../../../components/ui/ThemeToggle";
|
||||
import { PillNavigation, type PillNavigationItem } from "../shared/PillNavigation";
|
||||
import { LayoutsTab } from "../tabs/LayoutsTab";
|
||||
import { StyleGuideTab } from "../tabs/StyleGuideTab";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export { PillNavigation, type PillNavigationItem } from "@/features/ui/primitives/pill-navigation";
|
||||
export { StyleGuideView } from "./components/StyleGuideView";
|
||||
export { PillNavigation } from "./shared/PillNavigation";
|
||||
export { SideNavigation } from "./shared/SideNavigation";
|
||||
export { LayoutsTab } from "./tabs/LayoutsTab";
|
||||
export { StyleGuideTab } from "./tabs/StyleGuideTab";
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { Code, File, FileText, Globe, Search } from "lucide-react";
|
||||
import { Code, FileText, Globe, Search } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { Button } from "@/features/ui/primitives/button";
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/features/ui/primitives/dialog";
|
||||
import { Dialog, DialogContent } from "@/features/ui/primitives/dialog";
|
||||
import { Input } from "@/features/ui/primitives/input";
|
||||
import { StatPill } from "@/features/ui/primitives/pill";
|
||||
import { cn } from "@/features/ui/primitives/styles";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/features/ui/primitives/tabs";
|
||||
|
||||
@@ -75,7 +74,6 @@ const DocumentBrowserModal = ({ open, onOpenChange }: { open: boolean; onOpenCha
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const [selectedDoc, setSelectedDoc] = useState(MOCK_DOCUMENTS[0]);
|
||||
const [selectedCode, setSelectedCode] = useState(MOCK_CODE[0]);
|
||||
const [sourceType, setSourceType] = useState<"web" | "document">("web");
|
||||
|
||||
const filteredDocuments = MOCK_DOCUMENTS.filter((doc) => doc.title.toLowerCase().includes(searchQuery.toLowerCase()));
|
||||
|
||||
@@ -231,7 +229,7 @@ const DocumentBrowserModal = ({ open, onOpenChange }: { open: boolean; onOpenCha
|
||||
<h3 className="text-lg font-semibold text-white">{selectedCode.summary}</h3>
|
||||
<span className="px-2 py-1 text-xs bg-cyan-500/20 text-cyan-400 rounded">{selectedCode.language}</span>
|
||||
</div>
|
||||
<pre className="bg-black/30 rounded-lg p-4 overflow-x-auto">
|
||||
<pre className="bg-black/30 rounded-lg p-4 overflow-x-auto scrollbar-hide">
|
||||
<code className="text-gray-300 text-sm">{selectedCode.code}</code>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
@@ -133,23 +133,25 @@ export const KnowledgeLayoutExample = () => {
|
||||
</div>
|
||||
) : (
|
||||
// Table View - matching TaskView standard pattern
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr className="bg-gradient-to-r from-gray-50 to-gray-100 dark:from-gray-900 dark:to-gray-800 border-b-2 border-gray-200 dark:border-gray-700">
|
||||
<th className="px-4 py-3 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Title</th>
|
||||
<th className="px-4 py-3 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Type</th>
|
||||
<th className="px-4 py-3 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Source</th>
|
||||
<th className="px-4 py-3 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Chunks</th>
|
||||
<th className="px-4 py-3 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{MOCK_KNOWLEDGE_ITEMS.map((item, index) => (
|
||||
<KnowledgeTableRow key={item.id} item={item} index={index} />
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
<div className="w-full">
|
||||
<div className="overflow-x-auto scrollbar-hide">
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr className="bg-gradient-to-r from-gray-50 to-gray-100 dark:from-gray-900 dark:to-gray-800 border-b-2 border-gray-200 dark:border-gray-700">
|
||||
<th className="px-4 py-3 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Title</th>
|
||||
<th className="px-4 py-3 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Type</th>
|
||||
<th className="px-4 py-3 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Source</th>
|
||||
<th className="px-4 py-3 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Chunks</th>
|
||||
<th className="px-4 py-3 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{MOCK_KNOWLEDGE_ITEMS.map((item, index) => (
|
||||
<KnowledgeTableRow key={item.id} item={item} index={index} />
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@ import { Button } from "@/features/ui/primitives/button";
|
||||
import { DraggableCard } from "@/features/ui/primitives/draggable-card";
|
||||
import { Input } from "@/features/ui/primitives/input";
|
||||
import { StatPill } from "@/features/ui/primitives/pill";
|
||||
import { PillNavigation, type PillNavigationItem } from "@/features/ui/primitives/pill-navigation";
|
||||
import { SelectableCard } from "@/features/ui/primitives/selectable-card";
|
||||
import { cn } from "@/features/ui/primitives/styles";
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/features/ui/primitives/tooltip";
|
||||
import { PillNavigation, type PillNavigationItem } from "../shared/PillNavigation";
|
||||
|
||||
const MOCK_PROJECTS = [
|
||||
{
|
||||
@@ -731,7 +731,7 @@ const TaskCardExample = ({ task, index }: { task: (typeof MOCK_TASKS)[0]; index:
|
||||
const TaskTableView = () => {
|
||||
return (
|
||||
<div className="w-full">
|
||||
<div className="overflow-x-auto">
|
||||
<div className="overflow-x-auto scrollbar-hide">
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr className="bg-gradient-to-r from-gray-50 to-gray-100 dark:from-gray-900 dark:to-gray-800 border-b-2 border-gray-200 dark:border-gray-700">
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Code, Database, FileText, Flame, Globe, Key, Monitor, Moon, Palette, Settings } from "lucide-react";
|
||||
import { useId } from "react";
|
||||
import { CollapsibleSettingsCard } from "@/components/ui/CollapsibleSettingsCard";
|
||||
import { Card } from "@/features/ui/primitives/card";
|
||||
import { Input } from "@/features/ui/primitives/input";
|
||||
@@ -6,6 +7,17 @@ import { Label } from "@/features/ui/primitives/label";
|
||||
import { Switch } from "@/features/ui/primitives/switch";
|
||||
|
||||
export const SettingsLayoutExample = () => {
|
||||
const openaiKeyId = useId();
|
||||
const googleKeyId = useId();
|
||||
const dbUrlId = useId();
|
||||
const autoBackupId = useId();
|
||||
const extractCodeId = useId();
|
||||
const maxExamplesId = useId();
|
||||
const matchCountId = useId();
|
||||
const rerankId = useId();
|
||||
const maxDepthId = useId();
|
||||
const followLinksId = useId();
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
{/* Explanation Text */}
|
||||
@@ -84,11 +96,11 @@ export const SettingsLayoutExample = () => {
|
||||
</p>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<Label htmlFor="openai-key" className="text-xs font-medium text-gray-600 dark:text-gray-400">
|
||||
<Label htmlFor={openaiKeyId} className="text-xs font-medium text-gray-600 dark:text-gray-400">
|
||||
OPENAI_API_KEY
|
||||
</Label>
|
||||
<Input
|
||||
id="openai-key"
|
||||
id={openaiKeyId}
|
||||
type="password"
|
||||
placeholder="Enter new value (encrypted)"
|
||||
className="mt-2"
|
||||
@@ -96,11 +108,11 @@ export const SettingsLayoutExample = () => {
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="google-key" className="text-xs font-medium text-gray-600 dark:text-gray-400">
|
||||
<Label htmlFor={googleKeyId} className="text-xs font-medium text-gray-600 dark:text-gray-400">
|
||||
GOOGLE_API_KEY
|
||||
</Label>
|
||||
<Input
|
||||
id="google-key"
|
||||
id={googleKeyId}
|
||||
type="password"
|
||||
placeholder="Enter new value (encrypted)"
|
||||
className="mt-2"
|
||||
@@ -115,21 +127,21 @@ export const SettingsLayoutExample = () => {
|
||||
<CollapsibleSettingsCard title="Database Settings" icon={Database} accentColor="blue" defaultExpanded={false}>
|
||||
<Card edgePosition="top" edgeColor="blue">
|
||||
<div>
|
||||
<Label htmlFor="db-url" className="text-sm font-medium">
|
||||
<Label htmlFor={dbUrlId} className="text-sm font-medium">
|
||||
Database URL
|
||||
</Label>
|
||||
<Input
|
||||
id="db-url"
|
||||
id={dbUrlId}
|
||||
placeholder="postgresql://..."
|
||||
className="mt-2"
|
||||
defaultValue="postgresql://localhost:5432/archon"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-between mt-4">
|
||||
<Label htmlFor="auto-backup" className="text-sm font-medium">
|
||||
<Label htmlFor={autoBackupId} className="text-sm font-medium">
|
||||
Auto Backup
|
||||
</Label>
|
||||
<Switch id="auto-backup" />
|
||||
<Switch id={autoBackupId} />
|
||||
</div>
|
||||
</Card>
|
||||
</CollapsibleSettingsCard>
|
||||
@@ -141,16 +153,16 @@ export const SettingsLayoutExample = () => {
|
||||
Configure how code blocks are extracted from crawled documents.
|
||||
</p>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<Label htmlFor="extract-code" className="text-sm font-medium">
|
||||
<Label htmlFor={extractCodeId} className="text-sm font-medium">
|
||||
Extract Code Examples
|
||||
</Label>
|
||||
<Switch id="extract-code" defaultChecked />
|
||||
<Switch id={extractCodeId} defaultChecked />
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="max-examples" className="text-sm font-medium">
|
||||
<Label htmlFor={maxExamplesId} className="text-sm font-medium">
|
||||
Max Examples per Source
|
||||
</Label>
|
||||
<Input id="max-examples" type="number" placeholder="50" className="mt-2" defaultValue="50" />
|
||||
<Input id={maxExamplesId} type="number" placeholder="50" className="mt-2" defaultValue="50" />
|
||||
</div>
|
||||
</Card>
|
||||
</CollapsibleSettingsCard>
|
||||
@@ -159,16 +171,16 @@ export const SettingsLayoutExample = () => {
|
||||
<CollapsibleSettingsCard title="RAG Configuration" icon={Settings} accentColor="orange" defaultExpanded={true}>
|
||||
<Card edgePosition="top" edgeColor="orange">
|
||||
<div>
|
||||
<Label htmlFor="match-count" className="text-sm font-medium">
|
||||
<Label htmlFor={matchCountId} className="text-sm font-medium">
|
||||
Match Count
|
||||
</Label>
|
||||
<Input id="match-count" type="number" placeholder="5" className="mt-2" defaultValue="5" />
|
||||
<Input id={matchCountId} type="number" placeholder="5" className="mt-2" defaultValue="5" />
|
||||
</div>
|
||||
<div className="flex items-center justify-between mt-4">
|
||||
<Label htmlFor="rerank" className="text-sm font-medium">
|
||||
<Label htmlFor={rerankId} className="text-sm font-medium">
|
||||
Enable Reranking
|
||||
</Label>
|
||||
<Switch id="rerank" defaultChecked />
|
||||
<Switch id={rerankId} defaultChecked />
|
||||
</div>
|
||||
</Card>
|
||||
</CollapsibleSettingsCard>
|
||||
@@ -177,16 +189,16 @@ export const SettingsLayoutExample = () => {
|
||||
<CollapsibleSettingsCard title="Crawling Settings" icon={Globe} accentColor="pink" defaultExpanded={false}>
|
||||
<Card edgePosition="top" edgeColor="pink">
|
||||
<div>
|
||||
<Label htmlFor="max-depth" className="text-sm font-medium">
|
||||
<Label htmlFor={maxDepthId} className="text-sm font-medium">
|
||||
Max Crawl Depth
|
||||
</Label>
|
||||
<Input id="max-depth" type="number" placeholder="3" className="mt-2" defaultValue="3" />
|
||||
<Input id={maxDepthId} type="number" placeholder="3" className="mt-2" defaultValue="3" />
|
||||
</div>
|
||||
<div className="flex items-center justify-between mt-4">
|
||||
<Label htmlFor="follow-links" className="text-sm font-medium">
|
||||
<Label htmlFor={followLinksId} className="text-sm font-medium">
|
||||
Follow External Links
|
||||
</Label>
|
||||
<Switch id="follow-links" />
|
||||
<Switch id={followLinksId} />
|
||||
</div>
|
||||
</Card>
|
||||
</CollapsibleSettingsCard>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useId } from "react";
|
||||
import { Button } from "@/features/ui/primitives/button";
|
||||
import { Card } from "@/features/ui/primitives/card";
|
||||
import { Checkbox } from "@/features/ui/primitives/checkbox";
|
||||
@@ -7,6 +8,19 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@
|
||||
import { Switch } from "@/features/ui/primitives/switch";
|
||||
|
||||
export const StaticForms = () => {
|
||||
const exampleInputId = useId();
|
||||
const exampleDisabledId = useId();
|
||||
const exampleTextareaId = useId();
|
||||
const check1Id = useId();
|
||||
const check2Id = useId();
|
||||
const check3Id = useId();
|
||||
const switch1Id = useId();
|
||||
const switch2Id = useId();
|
||||
const switch3Id = useId();
|
||||
const selectCyanId = useId();
|
||||
const selectPurpleId = useId();
|
||||
const formInputId = useId();
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
@@ -20,12 +34,12 @@ export const StaticForms = () => {
|
||||
<h4 className="text-sm font-semibold mb-3 text-gray-900 dark:text-white">Text Input</h4>
|
||||
<div className="space-y-3">
|
||||
<div>
|
||||
<Label htmlFor="example-input">Label</Label>
|
||||
<Input id="example-input" placeholder="Enter text..." className="mt-1" />
|
||||
<Label htmlFor={exampleInputId}>Label</Label>
|
||||
<Input id={exampleInputId} placeholder="Enter text..." className="mt-1" />
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="example-disabled">Disabled</Label>
|
||||
<Input id="example-disabled" placeholder="Disabled..." disabled className="mt-1" />
|
||||
<Label htmlFor={exampleDisabledId}>Disabled</Label>
|
||||
<Input id={exampleDisabledId} placeholder="Disabled..." disabled className="mt-1" />
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400 mt-3 font-mono">{"<Input />"}</p>
|
||||
@@ -35,9 +49,9 @@ export const StaticForms = () => {
|
||||
<Card className="p-6">
|
||||
<h4 className="text-sm font-semibold mb-3 text-gray-900 dark:text-white">Textarea</h4>
|
||||
<div>
|
||||
<Label htmlFor="example-textarea">Description</Label>
|
||||
<Label htmlFor={exampleTextareaId}>Description</Label>
|
||||
<textarea
|
||||
id="example-textarea"
|
||||
id={exampleTextareaId}
|
||||
placeholder="Enter description..."
|
||||
rows={4}
|
||||
className="mt-1 w-full rounded-md border border-gray-300 dark:border-gray-600 bg-white/50 dark:bg-black/30 px-3 py-2 text-sm backdrop-blur-sm focus:border-cyan-500 focus:outline-none"
|
||||
@@ -51,16 +65,16 @@ export const StaticForms = () => {
|
||||
<h4 className="text-sm font-semibold mb-3 text-gray-900 dark:text-white">Checkbox</h4>
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<Checkbox id="check-1" defaultChecked color="cyan" />
|
||||
<Label htmlFor="check-1">Checked</Label>
|
||||
<Checkbox id={check1Id} defaultChecked color="cyan" />
|
||||
<Label htmlFor={check1Id}>Checked</Label>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Checkbox id="check-2" color="purple" />
|
||||
<Label htmlFor="check-2">Unchecked</Label>
|
||||
<Checkbox id={check2Id} color="purple" />
|
||||
<Label htmlFor={check2Id}>Unchecked</Label>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Checkbox id="check-3" disabled defaultChecked />
|
||||
<Label htmlFor="check-3">Disabled</Label>
|
||||
<Checkbox id={check3Id} disabled defaultChecked />
|
||||
<Label htmlFor={check3Id}>Disabled</Label>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400 mt-3 font-mono">{"<Checkbox />"}</p>
|
||||
@@ -71,16 +85,16 @@ export const StaticForms = () => {
|
||||
<h4 className="text-sm font-semibold mb-3 text-gray-900 dark:text-white">Switch Toggle</h4>
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<Label htmlFor="switch-1">Enable Feature</Label>
|
||||
<Switch id="switch-1" defaultChecked />
|
||||
<Label htmlFor={switch1Id}>Enable Feature</Label>
|
||||
<Switch id={switch1Id} defaultChecked />
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<Label htmlFor="switch-2">Dark Mode</Label>
|
||||
<Switch id="switch-2" />
|
||||
<Label htmlFor={switch2Id}>Dark Mode</Label>
|
||||
<Switch id={switch2Id} />
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<Label htmlFor="switch-3">Disabled</Label>
|
||||
<Switch id="switch-3" disabled />
|
||||
<Label htmlFor={switch3Id}>Disabled</Label>
|
||||
<Switch id={switch3Id} disabled />
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400 mt-3 font-mono">{"<Switch />"}</p>
|
||||
@@ -91,9 +105,9 @@ export const StaticForms = () => {
|
||||
<h4 className="text-sm font-semibold mb-3 text-gray-900 dark:text-white">Select Dropdown</h4>
|
||||
<div className="space-y-3">
|
||||
<div>
|
||||
<Label htmlFor="select-cyan">Cyan Variant</Label>
|
||||
<Label htmlFor={selectCyanId}>Cyan Variant</Label>
|
||||
<Select defaultValue="option2">
|
||||
<SelectTrigger id="select-cyan" color="cyan" className="mt-1">
|
||||
<SelectTrigger id={selectCyanId} color="cyan" className="mt-1">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
@@ -104,9 +118,9 @@ export const StaticForms = () => {
|
||||
</Select>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="select-purple">Purple Variant</Label>
|
||||
<Label htmlFor={selectPurpleId}>Purple Variant</Label>
|
||||
<Select defaultValue="option1">
|
||||
<SelectTrigger id="select-purple" color="purple" className="mt-1">
|
||||
<SelectTrigger id={selectPurpleId} color="purple" className="mt-1">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
@@ -125,8 +139,8 @@ export const StaticForms = () => {
|
||||
<h4 className="text-sm font-semibold mb-3 text-gray-900 dark:text-white">Form Submission</h4>
|
||||
<div className="space-y-3">
|
||||
<div>
|
||||
<Label htmlFor="form-input">Email</Label>
|
||||
<Input id="form-input" type="email" placeholder="email@example.com" className="mt-1" />
|
||||
<Label htmlFor={formInputId}>Email</Label>
|
||||
<Input id={formInputId} type="email" placeholder="email@example.com" className="mt-1" />
|
||||
</div>
|
||||
<Button variant="default" className="w-full">
|
||||
Submit
|
||||
|
||||
@@ -9,55 +9,57 @@ export const StaticTables = () => {
|
||||
{/* Standard Table - matching TaskView pattern */}
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold mb-3 text-gray-800 dark:text-gray-200">Standard Table</h3>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr className="bg-gradient-to-r from-gray-50 to-gray-100 dark:from-gray-900 dark:to-gray-800 border-b-2 border-gray-200 dark:border-gray-700">
|
||||
<th className="px-4 py-3 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Name</th>
|
||||
<th className="px-4 py-3 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Status</th>
|
||||
<th className="px-4 py-3 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Count</th>
|
||||
<th className="px-4 py-3 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr className="bg-white/50 dark:bg-black/50 hover:bg-gradient-to-r hover:from-cyan-50/70 hover:to-purple-50/70 dark:hover:from-cyan-900/20 dark:hover:to-purple-900/20 border-b border-gray-200 dark:border-gray-800 transition-all duration-200">
|
||||
<td className="px-4 py-2">
|
||||
<span className="font-medium text-sm text-gray-900 dark:text-white">React Documentation</span>
|
||||
</td>
|
||||
<td className="px-4 py-2">
|
||||
<span className="px-2 py-1 text-xs rounded-md font-medium bg-green-500/10 text-green-600 dark:text-green-400">
|
||||
Active
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-4 py-2 text-sm text-gray-600 dark:text-gray-400">145</td>
|
||||
<td className="px-4 py-2 text-sm text-gray-600 dark:text-gray-400">2024-01-15</td>
|
||||
</tr>
|
||||
<tr className="bg-gray-50/80 dark:bg-gray-900/30 hover:bg-gradient-to-r hover:from-cyan-50/70 hover:to-purple-50/70 dark:hover:from-cyan-900/20 dark:hover:to-purple-900/20 border-b border-gray-200 dark:border-gray-800 transition-all duration-200">
|
||||
<td className="px-4 py-2">
|
||||
<span className="font-medium text-sm text-gray-900 dark:text-white">API Integration</span>
|
||||
</td>
|
||||
<td className="px-4 py-2">
|
||||
<span className="px-2 py-1 text-xs rounded-md font-medium bg-yellow-500/10 text-yellow-600 dark:text-yellow-400">
|
||||
Processing
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-4 py-2 text-sm text-gray-600 dark:text-gray-400">89</td>
|
||||
<td className="px-4 py-2 text-sm text-gray-600 dark:text-gray-400">2024-01-18</td>
|
||||
</tr>
|
||||
<tr className="bg-white/50 dark:bg-black/50 hover:bg-gradient-to-r hover:from-cyan-50/70 hover:to-purple-50/70 dark:hover:from-cyan-900/20 dark:hover:to-purple-900/20 border-b border-gray-200 dark:border-gray-800 transition-all duration-200">
|
||||
<td className="px-4 py-2">
|
||||
<span className="font-medium text-sm text-gray-900 dark:text-white">TypeScript Guide</span>
|
||||
</td>
|
||||
<td className="px-4 py-2">
|
||||
<span className="px-2 py-1 text-xs rounded-md font-medium bg-cyan-500/10 text-cyan-600 dark:text-cyan-400">
|
||||
Complete
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-4 py-2 text-sm text-gray-600 dark:text-gray-400">203</td>
|
||||
<td className="px-4 py-2 text-sm text-gray-600 dark:text-gray-400">2024-01-20</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div className="w-full">
|
||||
<div className="overflow-x-auto scrollbar-hide">
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr className="bg-gradient-to-r from-gray-50 to-gray-100 dark:from-gray-900 dark:to-gray-800 border-b-2 border-gray-200 dark:border-gray-700">
|
||||
<th className="px-4 py-3 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Name</th>
|
||||
<th className="px-4 py-3 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Status</th>
|
||||
<th className="px-4 py-3 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Count</th>
|
||||
<th className="px-4 py-3 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr className="bg-white/50 dark:bg-black/50 hover:bg-gradient-to-r hover:from-cyan-50/70 hover:to-purple-50/70 dark:hover:from-cyan-900/20 dark:hover:to-purple-900/20 border-b border-gray-200 dark:border-gray-800 transition-all duration-200">
|
||||
<td className="px-4 py-2">
|
||||
<span className="font-medium text-sm text-gray-900 dark:text-white">React Documentation</span>
|
||||
</td>
|
||||
<td className="px-4 py-2">
|
||||
<span className="px-2 py-1 text-xs rounded-md font-medium bg-green-500/10 text-green-600 dark:text-green-400">
|
||||
Active
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-4 py-2 text-sm text-gray-600 dark:text-gray-400">145</td>
|
||||
<td className="px-4 py-2 text-sm text-gray-600 dark:text-gray-400">2024-01-15</td>
|
||||
</tr>
|
||||
<tr className="bg-gray-50/80 dark:bg-gray-900/30 hover:bg-gradient-to-r hover:from-cyan-50/70 hover:to-purple-50/70 dark:hover:from-cyan-900/20 dark:hover:to-purple-900/20 border-b border-gray-200 dark:border-gray-800 transition-all duration-200">
|
||||
<td className="px-4 py-2">
|
||||
<span className="font-medium text-sm text-gray-900 dark:text-white">API Integration</span>
|
||||
</td>
|
||||
<td className="px-4 py-2">
|
||||
<span className="px-2 py-1 text-xs rounded-md font-medium bg-yellow-500/10 text-yellow-600 dark:text-yellow-400">
|
||||
Processing
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-4 py-2 text-sm text-gray-600 dark:text-gray-400">89</td>
|
||||
<td className="px-4 py-2 text-sm text-gray-600 dark:text-gray-400">2024-01-18</td>
|
||||
</tr>
|
||||
<tr className="bg-white/50 dark:bg-black/50 hover:bg-gradient-to-r hover:from-cyan-50/70 hover:to-purple-50/70 dark:hover:from-cyan-900/20 dark:hover:to-purple-900/20 border-b border-gray-200 dark:border-gray-800 transition-all duration-200">
|
||||
<td className="px-4 py-2">
|
||||
<span className="font-medium text-sm text-gray-900 dark:text-white">TypeScript Guide</span>
|
||||
</td>
|
||||
<td className="px-4 py-2">
|
||||
<span className="px-2 py-1 text-xs rounded-md font-medium bg-cyan-500/10 text-cyan-600 dark:text-cyan-400">
|
||||
Complete
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-4 py-2 text-sm text-gray-600 dark:text-gray-400">203</td>
|
||||
<td className="px-4 py-2 text-sm text-gray-600 dark:text-gray-400">2024-01-20</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400 mt-3">
|
||||
Features: Gradient header, alternating rows, hover gradient, consistent spacing
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { useState } from "react";
|
||||
import { useId, useState } from "react";
|
||||
import { PowerButton } from "@/components/ui/PowerButton";
|
||||
import { Card } from "@/features/ui/primitives/card";
|
||||
import { Label } from "@/features/ui/primitives/label";
|
||||
import { Switch } from "@/features/ui/primitives/switch";
|
||||
|
||||
export const StaticToggles = () => {
|
||||
const toggle1Id = useId();
|
||||
const toggle2Id = useId();
|
||||
|
||||
const [powerStates, setPowerStates] = useState({
|
||||
purple: true,
|
||||
cyan: false,
|
||||
@@ -74,12 +77,12 @@ export const StaticToggles = () => {
|
||||
</p>
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<Label htmlFor="toggle-1">Enable Feature</Label>
|
||||
<Switch id="toggle-1" defaultChecked />
|
||||
<Label htmlFor={toggle1Id}>Enable Feature</Label>
|
||||
<Switch id={toggle1Id} defaultChecked />
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<Label htmlFor="toggle-2">Auto Save</Label>
|
||||
<Switch id="toggle-2" />
|
||||
<Label htmlFor={toggle2Id}>Auto Save</Label>
|
||||
<Switch id={toggle2Id} />
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400 mt-4 font-mono">{"<Switch />"}</p>
|
||||
|
||||
153
archon-ui-main/src/features/ui/primitives/pill-navigation.tsx
Normal file
153
archon-ui-main/src/features/ui/primitives/pill-navigation.tsx
Normal file
@@ -0,0 +1,153 @@
|
||||
import { ChevronRight } from "lucide-react";
|
||||
import type { ReactNode } from "react";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/features/ui/primitives/select";
|
||||
import { cn } from "@/features/ui/primitives/styles";
|
||||
|
||||
export interface PillNavigationItem {
|
||||
id: string;
|
||||
label: string;
|
||||
icon?: ReactNode;
|
||||
items?: string[];
|
||||
}
|
||||
|
||||
interface PillNavigationProps {
|
||||
items: PillNavigationItem[];
|
||||
activeSection: string;
|
||||
activeItem?: string;
|
||||
onSectionClick: (sectionId: string) => void;
|
||||
onItemClick?: (item: string) => void;
|
||||
colorVariant?: "blue" | "orange" | "cyan" | "purple" | "emerald";
|
||||
size?: "small" | "default" | "large";
|
||||
showIcons?: boolean;
|
||||
showText?: boolean;
|
||||
hasSubmenus?: boolean;
|
||||
openDropdown?: string | null;
|
||||
}
|
||||
|
||||
export const PillNavigation = ({
|
||||
items,
|
||||
activeSection,
|
||||
activeItem,
|
||||
onSectionClick,
|
||||
onItemClick,
|
||||
colorVariant = "cyan",
|
||||
size = "default",
|
||||
showIcons = true,
|
||||
showText = true,
|
||||
hasSubmenus = true,
|
||||
openDropdown,
|
||||
}: PillNavigationProps) => {
|
||||
const getColorClasses = (variant: string, isSelected: boolean) => {
|
||||
const colors = {
|
||||
blue: isSelected
|
||||
? "bg-blue-500/20 dark:bg-blue-400/20 text-blue-700 dark:text-blue-300 border border-blue-400/50 shadow-[0_0_10px_rgba(59,130,246,0.5)]"
|
||||
: "text-gray-700 dark:text-gray-300 hover:bg-white/10 dark:hover:bg-white/5",
|
||||
orange: isSelected
|
||||
? "bg-orange-500/20 dark:bg-orange-400/20 text-orange-700 dark:text-orange-300 border border-orange-400/50 shadow-[0_0_10px_rgba(251,146,60,0.5)]"
|
||||
: "text-gray-700 dark:text-gray-300 hover:bg-white/10 dark:hover:bg-white/5",
|
||||
cyan: isSelected
|
||||
? "bg-cyan-500/20 dark:bg-cyan-400/20 text-cyan-700 dark:text-cyan-300 border border-cyan-400/50 shadow-[0_0_10px_rgba(34,211,238,0.5)]"
|
||||
: "text-gray-700 dark:text-gray-300 hover:bg-white/10 dark:hover:bg-white/5",
|
||||
purple: isSelected
|
||||
? "bg-purple-500/20 dark:bg-purple-400/20 text-purple-700 dark:text-purple-300 border border-purple-400/50 shadow-[0_0_10px_rgba(147,51,234,0.5)]"
|
||||
: "text-gray-700 dark:text-gray-300 hover:bg-white/10 dark:hover:bg-white/5",
|
||||
emerald: isSelected
|
||||
? "bg-emerald-500/20 dark:bg-emerald-400/20 text-emerald-700 dark:text-emerald-300 border border-emerald-400/50 shadow-[0_0_10px_rgba(16,185,129,0.5)]"
|
||||
: "text-gray-700 dark:text-gray-300 hover:bg-white/10 dark:hover:bg-white/5",
|
||||
};
|
||||
return colors[variant as keyof typeof colors] || colors.cyan;
|
||||
};
|
||||
|
||||
const getSizeClasses = (sizeVariant: string) => {
|
||||
const sizes = {
|
||||
small: "px-4 py-2 text-xs",
|
||||
default: "px-6 py-3 text-sm",
|
||||
large: "px-8 py-4 text-base",
|
||||
};
|
||||
return sizes[sizeVariant as keyof typeof sizes] || sizes.default;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="backdrop-blur-sm bg-white/40 dark:bg-white/5 border border-white/30 dark:border-white/15 rounded-full p-1 shadow-lg transition-all duration-300 ease-in-out">
|
||||
<div className="flex gap-1 items-center">
|
||||
{items.map((item) => {
|
||||
const isSelected = activeSection === item.id;
|
||||
const hasDropdown = hasSubmenus && item.items && item.items.length > 0;
|
||||
const isThisExpanded = openDropdown === item.id && hasDropdown;
|
||||
|
||||
return (
|
||||
<div key={item.id} className="relative">
|
||||
{/* Extended pill for selected item with dropdown */}
|
||||
{isSelected && hasDropdown ? (
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center gap-2 rounded-full transition-all duration-200",
|
||||
"font-medium whitespace-nowrap",
|
||||
getSizeClasses(size),
|
||||
getColorClasses(colorVariant, true),
|
||||
)}
|
||||
>
|
||||
{showIcons && item.icon}
|
||||
{showText && item.label}
|
||||
|
||||
{/* Dropdown selector inside the pill */}
|
||||
{onItemClick && (
|
||||
<div className="flex items-center ml-4 pl-4 border-l border-current/30">
|
||||
<Select value={activeItem || ""} onValueChange={onItemClick}>
|
||||
<SelectTrigger
|
||||
className="bg-transparent border-none outline-none font-medium cursor-pointer text-inherit w-auto px-0 hover:border-none focus:border-none focus:shadow-none"
|
||||
showChevron={false}
|
||||
color={colorVariant}
|
||||
>
|
||||
<SelectValue placeholder="Select..." />
|
||||
</SelectTrigger>
|
||||
<SelectContent color={colorVariant}>
|
||||
{item.items?.map((subItem) => (
|
||||
<SelectItem key={subItem} value={subItem} color={colorVariant}>
|
||||
{subItem}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ChevronRight
|
||||
className={cn(
|
||||
"w-4 h-4 transition-transform duration-300 ml-2 cursor-pointer",
|
||||
isThisExpanded ? "-rotate-90" : "rotate-0",
|
||||
)}
|
||||
onClick={() => onSectionClick(item.id)}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
/* Regular pill for non-selected items */
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onSectionClick(item.id)}
|
||||
className={cn(
|
||||
"flex items-center gap-2 rounded-full transition-all duration-200",
|
||||
"font-medium whitespace-nowrap",
|
||||
getSizeClasses(size),
|
||||
getColorClasses(colorVariant, isSelected),
|
||||
)}
|
||||
>
|
||||
{showIcons && item.icon}
|
||||
{showText && item.label}
|
||||
{hasDropdown && (
|
||||
<ChevronRight
|
||||
className={cn(
|
||||
"w-4 h-4 transition-transform duration-300",
|
||||
isThisExpanded ? "-rotate-90" : "rotate-0",
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user