project init

This commit is contained in:
2025-12-01 02:29:08 +01:00
commit 78a0f6c646
106 changed files with 13132 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
"use client"
import { createContext, useContext, useState, useEffect, type ReactNode } from "react"
import { useRouter } from "next/navigation"
interface AuthContextType {
isAuthenticated: boolean
isLoading: boolean
login: (email: string, password: string) => Promise<boolean>
logout: () => void
}
const AuthContext = createContext<AuthContextType | null>(null)
// Mock credentials - replace with real API auth
const MOCK_CREDENTIALS = {
email: "admin@atticl.com",
password: "admin123",
}
export function AuthProvider({ children }: { children: ReactNode }) {
const [isAuthenticated, setIsAuthenticated] = useState(false)
const [isLoading, setIsLoading] = useState(true)
const router = useRouter()
useEffect(() => {
// Check for existing session
const session = localStorage.getItem("atticl_admin_session")
if (session === "authenticated") {
setIsAuthenticated(true)
}
setIsLoading(false)
}, [])
const login = async (email: string, password: string): Promise<boolean> => {
// Mock API call - replace with real auth
await new Promise((resolve) => setTimeout(resolve, 500))
if (email === MOCK_CREDENTIALS.email && password === MOCK_CREDENTIALS.password) {
localStorage.setItem("atticl_admin_session", "authenticated")
setIsAuthenticated(true)
return true
}
return false
}
const logout = () => {
localStorage.removeItem("atticl_admin_session")
setIsAuthenticated(false)
router.push("/admin/login")
}
return <AuthContext.Provider value={{ isAuthenticated, isLoading, login, logout }}>{children}</AuthContext.Provider>
}
export function useAuth() {
const context = useContext(AuthContext)
if (!context) {
throw new Error("useAuth must be used within an AuthProvider")
}
return context
}

View File

@@ -0,0 +1,76 @@
"use client"
import { createContext, useContext, useState, type ReactNode } from "react"
import type { Project, StackCategory } from "./types"
import { mockProjects, mockStackCategories } from "./mock-data"
interface DataStore {
projects: Project[]
stackCategories: StackCategory[]
// Project CRUD
addProject: (project: Omit<Project, "id">) => void
updateProject: (id: string, project: Partial<Project>) => void
deleteProject: (id: string) => void
// Stack CRUD
addStackCategory: (category: Omit<StackCategory, "id">) => void
updateStackCategory: (id: string, category: Partial<StackCategory>) => void
deleteStackCategory: (id: string) => void
}
const DataStoreContext = createContext<DataStore | null>(null)
export function DataStoreProvider({ children }: { children: ReactNode }) {
const [projects, setProjects] = useState<Project[]>(mockProjects)
const [stackCategories, setStackCategories] = useState<StackCategory[]>(mockStackCategories)
const addProject = (project: Omit<Project, "id">) => {
const newProject = { ...project, id: crypto.randomUUID() }
setProjects((prev) => [...prev, newProject])
}
const updateProject = (id: string, updates: Partial<Project>) => {
setProjects((prev) => prev.map((p) => (p.id === id ? { ...p, ...updates } : p)))
}
const deleteProject = (id: string) => {
setProjects((prev) => prev.filter((p) => p.id !== id))
}
const addStackCategory = (category: Omit<StackCategory, "id">) => {
const newCategory = { ...category, id: crypto.randomUUID() }
setStackCategories((prev) => [...prev, newCategory])
}
const updateStackCategory = (id: string, updates: Partial<StackCategory>) => {
setStackCategories((prev) => prev.map((c) => (c.id === id ? { ...c, ...updates } : c)))
}
const deleteStackCategory = (id: string) => {
setStackCategories((prev) => prev.filter((c) => c.id !== id))
}
return (
<DataStoreContext.Provider
value={{
projects,
stackCategories,
addProject,
updateProject,
deleteProject,
addStackCategory,
updateStackCategory,
deleteStackCategory,
}}
>
{children}
</DataStoreContext.Provider>
)
}
export function useDataStore() {
const context = useContext(DataStoreContext)
if (!context) {
throw new Error("useDataStore must be used within a DataStoreProvider")
}
return context
}

91
frontend/lib/mock-data.ts Normal file
View File

@@ -0,0 +1,91 @@
import type { Project, StackCategory } from "./types"
// Mock data store - will be replaced with API calls
export const mockProjects: Project[] = [
{
id: "1",
name: "crowware.com",
role: "Co-founder & Backend Lead",
description:
"A developer tools platform built for teams who ship. I designed and built the core backend infrastructure from scratch.",
highlights: [
"Distributed API architecture handling 10k+ requests/sec",
"PostgreSQL with custom indexing strategy for complex queries",
"Event-driven microservices with Redis pub/sub",
"Zero-downtime deployments with blue-green strategy",
"Comprehensive observability stack (Prometheus, Grafana, OpenTelemetry)",
],
stack: ["Go", "PostgreSQL", "Redis", "Kubernetes", "Terraform"],
website: "https://crowware.com",
github: null,
featured: true,
},
{
id: "2",
name: "api-gateway",
role: "Creator",
description:
"High-performance API gateway with rate limiting, auth, and request transformation. Built for internal use, battle-tested in production.",
highlights: [],
stack: ["Go", "Redis", "Docker"],
website: null,
github: "#",
featured: false,
},
{
id: "3",
name: "pg-migrate",
role: "Creator",
description:
"Zero-downtime PostgreSQL migration tool. Handles large tables without locking, with automatic rollback support.",
highlights: [],
stack: ["Python", "PostgreSQL"],
website: null,
github: "#",
featured: false,
},
{
id: "4",
name: "logpipe",
role: "Creator",
description: "Structured logging pipeline that routes logs to multiple destinations based on severity and content.",
highlights: [],
stack: ["Rust", "Kafka"],
website: null,
github: "#",
featured: false,
},
]
export const mockStackCategories: StackCategory[] = [
{
id: "1",
title: "Backend",
items: ["Go", "Python", "Node.js", "Rust"],
},
{
id: "2",
title: "Databases",
items: ["PostgreSQL", "Redis", "SQLite", "ClickHouse"],
},
{
id: "3",
title: "Infrastructure",
items: ["Docker", "Kubernetes", "Terraform", "AWS"],
},
{
id: "4",
title: "APIs & Protocols",
items: ["REST", "GraphQL", "gRPC", "WebSockets"],
},
{
id: "5",
title: "Observability",
items: ["Prometheus", "Grafana", "OpenTelemetry", "Sentry"],
},
{
id: "6",
title: "Tooling",
items: ["Git", "CI/CD", "Make", "Nix"],
},
]

23
frontend/lib/types.ts Normal file
View File

@@ -0,0 +1,23 @@
export interface Project {
id: string
name: string
role: string
description: string
highlights: string[]
stack: string[]
website: string | null
github: string | null
featured: boolean
}
export interface StackCategory {
id: string
title: string
items: string[]
}
export interface User {
id: string
email: string
name: string
}

6
frontend/lib/utils.ts Normal file
View File

@@ -0,0 +1,6 @@
import { clsx, type ClassValue } from 'clsx'
import { twMerge } from 'tailwind-merge'
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}