Implement authentication system with access control UI

This commit is contained in:
Mondo Diaz
2026-01-12 10:52:35 -06:00
committed by Dane Moss
parent 1cbd335443
commit 617bcbe89c
39 changed files with 8561 additions and 116 deletions

View File

@@ -7,8 +7,19 @@ import { SortDropdown, SortOption } from '../components/SortDropdown';
import { FilterDropdown, FilterOption } from '../components/FilterDropdown';
import { FilterChip, FilterChipGroup } from '../components/FilterChip';
import { Pagination } from '../components/Pagination';
import { useAuth } from '../contexts/AuthContext';
import './Home.css';
// Lock icon SVG component
function LockIcon() {
return (
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="lock-icon">
<rect x="3" y="11" width="18" height="11" rx="2" ry="2" />
<path d="M7 11V7a5 5 0 0 1 10 0v4" />
</svg>
);
}
const SORT_OPTIONS: SortOption[] = [
{ value: 'name', label: 'Name' },
{ value: 'created_at', label: 'Created' },
@@ -23,6 +34,7 @@ const VISIBILITY_OPTIONS: FilterOption[] = [
function Home() {
const [searchParams, setSearchParams] = useSearchParams();
const { user } = useAuth();
const [projectsData, setProjectsData] = useState<PaginatedResponse<Project> | null>(null);
const [loading, setLoading] = useState(true);
@@ -117,9 +129,15 @@ function Home() {
<div className="home">
<div className="page-header">
<h1>Projects</h1>
<button className="btn btn-primary" onClick={() => setShowForm(!showForm)}>
{showForm ? 'Cancel' : '+ New Project'}
</button>
{user ? (
<button className="btn btn-primary" onClick={() => setShowForm(!showForm)}>
{showForm ? 'Cancel' : '+ New Project'}
</button>
) : (
<Link to="/login" className="btn btn-secondary">
Login to create projects
</Link>
)}
</div>
{error && <div className="error-message">{error}</div>}
@@ -199,12 +217,32 @@ function Home() {
<div className="project-grid">
{projects.map((project) => (
<Link to={`/project/${project.name}`} key={project.id} className="project-card card">
<h3>{project.name}</h3>
<h3>
{!project.is_public && <LockIcon />}
{project.name}
</h3>
{project.description && <p>{project.description}</p>}
<div className="project-meta">
<Badge variant={project.is_public ? 'public' : 'private'}>
{project.is_public ? 'Public' : 'Private'}
</Badge>
<div className="project-badges">
<Badge variant={project.is_public ? 'public' : 'private'}>
{project.is_public ? 'Public' : 'Private'}
</Badge>
{user && project.access_level && (
<Badge
variant={
project.is_owner
? 'success'
: project.access_level === 'admin'
? 'success'
: project.access_level === 'write'
? 'info'
: 'default'
}
>
{project.is_owner ? 'Owner' : project.access_level.charAt(0).toUpperCase() + project.access_level.slice(1)}
</Badge>
)}
</div>
<div className="project-meta__dates">
<span className="date">Created {new Date(project.created_at).toLocaleDateString()}</span>
{project.updated_at !== project.created_at && (