Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 35 additions & 18 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// src/App.tsx
import { BrowserRouter, Routes, Route, Navigate, Link } from "react-router-dom";
import { BrowserRouter, Routes, Route, Navigate, Link, useLocation } from "react-router-dom";
import ConnectPage from "./pages/ConnectPage";
import ConfigurePage from "./pages/ConfigurePage";
import SecretsPage from "./pages/SecretsPage";
Expand All @@ -8,42 +8,59 @@ import Jenkins from "./routes/Jenkins";
import { useRepoStore } from "./store/useRepoStore";
import { usePipelineStore } from "./store/usePipelineStore";

// (optional) ShadCN test
// import { Button } from "@/components/ui/button";

function NeedRepo({ children }: { children: JSX.Element }) {
const { repo, branch } = useRepoStore();
return !repo || !branch ? <Navigate to="/connect" replace /> : children;
}
function NeedPipeline({ children }: { children: JSX.Element }) {
const { result } = usePipelineStore();
const hasYaml =
result?.generated_yaml || result?.yaml || result?.data?.generated_yaml;
const hasYaml = result?.generated_yaml || result?.yaml || result?.data?.generated_yaml;
return !hasYaml ? <Navigate to="/configure" replace /> : children;
}

// optional: simple active-link helper
function NavLink({ to, children }: { to: string; children: React.ReactNode }) {
const { pathname } = useLocation();
const active = pathname.startsWith(to);
return (
<Link
to={to}
className={
"transition-colors " +
(active
? "text-white"
: "text-slate-200/80 hover:text-white")
}
>
{children}
</Link>
);
}

export default function App() {
return (
<div className="relative min-h-screen text-white overflow-hidden">
{/* Base gradient (covers entire viewport) */}
<div className="fixed inset-0 -z-10 bg-gradient-to-br from-slate-900 via-slate-800 to-gray-900" />
{/* Frosted glass overlay */}
<div className="fixed inset-0 -z-10 bg-white/10 backdrop-blur-3xl" />
<div className="relative min-h-screen text-slate-100 overflow-hidden">
{/* Base gradient */}
<div className="fixed inset-0 -z-20 bg-gradient-to-br from-slate-900 via-slate-800 to-gray-900" />
{/* Subtle dark veil for contrast */}
<div className="fixed inset-0 -z-10 bg-black/20" />
{/* Frosted glass shimmer – IMPORTANT: pointer-events-none so it never blocks clicks */}
<div className="fixed inset-0 -z-10 bg-white/10 backdrop-blur-3xl pointer-events-none" />

{/* App content above blur */}
<div className="relative z-10">
<BrowserRouter>
<header className="border-b border-white/15 px-4 py-3 bg-white/5 backdrop-blur">
<nav className="flex gap-5 text-sm">
<Link className="text-white/80 hover:text-white" to="/connect">1 Connect</Link>
<Link className="text-white/80 hover:text-white" to="/configure">2 Configure</Link>
<Link className="text-white/80 hover:text-white" to="/secrets">3 Secrets</Link>
<Link className="text-white/80 hover:text-white" to="/dashboard">4 Dashboard</Link>
<Link className="text-white/80 hover:text-white" to="/jenkins">5 Jenkins</Link>
</nav>
<NavLink to="/connect">1 Connect</NavLink>
<NavLink to="/configure">2 Configure</NavLink>
<NavLink to="/secrets">3 Secrets</NavLink>
<NavLink to="/dashboard">4 Dashboard</NavLink>
<NavLink to="/jenkins">5 Jenkins</NavLink>
</nav>
</header>

<main className="p-4 max-w-[960px] mx-auto">
<main className="p-4 md:p-6 max-w-[960px] mx-auto">
<Routes>
<Route path="/" element={<Navigate to="/connect" replace />} />
<Route path="/connect" element={<ConnectPage />} />
Expand Down
10 changes: 10 additions & 0 deletions client/src/components/ui/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ const buttonVariants = cva(
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",

// ✅ Glass (matches Connect page look)
glass:
"border border-white/30 bg-white/10 text-slate-100 " +
"hover:bg-white/20 backdrop-blur-md shadow-glass",

// optional: a slightly stronger white version for primary actions
glassSolid:
"border border-white/40 bg-white/20 text-slate-900 " +
"hover:bg-white/30 backdrop-blur-md shadow-glass",
},
size: {
default: "h-9 px-4 py-2",
Expand Down
13 changes: 13 additions & 0 deletions client/src/components/ui/GlassButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export function GlassButton({ children, onClick }: any) {
return (
<button
onClick={onClick}
className="px-4 py-2 rounded-lg border border-white/30
bg-white/10 backdrop-blur-md text-slate-100
hover:bg-white/20 hover:shadow-glass
transition-all duration-300"
>
{children}
</button>
);
}
222 changes: 42 additions & 180 deletions client/src/index.css
Original file line number Diff line number Diff line change
@@ -1,195 +1,57 @@
/* 1️⃣ Import Tailwind */
@import "tailwindcss";
@plugin "tailwindcss-animate";

@custom-variant dark (&:is(.dark *));
/* 2️⃣ Import Satoshi font from Fontshare */
@import url("https://api.fontshare.com/v2/css?f[]=satoshi@400,500,700&display=swap");

@tailwind base;
@tailwind components;
@tailwind utilities;
/* 3️⃣ Define theme variables (font + glass shadow) */
@theme {
--font-sans: "Satoshi", system-ui, -apple-system, BlinkMacSystemFont,
"Segoe UI", Roboto, Helvetica, Arial, sans-serif;

/* src/index.css */
html, body, #root { height: 100%; }
body { background: transparent; }


/* :root {
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;

color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;

font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
--radius: 0.625rem;
--background: oklch(1 0 0);
--foreground: oklch(0.13 0.028 261.692);
--card: oklch(1 0 0);
--card-foreground: oklch(0.13 0.028 261.692);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.13 0.028 261.692);
--primary: oklch(0.21 0.034 264.665);
--primary-foreground: oklch(0.985 0.002 247.839);
--secondary: oklch(0.967 0.003 264.542);
--secondary-foreground: oklch(0.21 0.034 264.665);
--muted: oklch(0.967 0.003 264.542);
--muted-foreground: oklch(0.551 0.027 264.364);
--accent: oklch(0.967 0.003 264.542);
--accent-foreground: oklch(0.21 0.034 264.665);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.928 0.006 264.531);
--input: oklch(0.928 0.006 264.531);
--ring: oklch(0.707 0.022 261.325);
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
--sidebar: oklch(0.985 0.002 247.839);
--sidebar-foreground: oklch(0.13 0.028 261.692);
--sidebar-primary: oklch(0.21 0.034 264.665);
--sidebar-primary-foreground: oklch(0.985 0.002 247.839);
--sidebar-accent: oklch(0.967 0.003 264.542);
--sidebar-accent-foreground: oklch(0.21 0.034 264.665);
--sidebar-border: oklch(0.928 0.006 264.531);
--sidebar-ring: oklch(0.707 0.022 261.325);
--shadow-glass: 0 12px 40px rgba(0, 0, 0, 0.35);
}

a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
/* 4️⃣ Base styles that apply globally */
@layer base {
html {
font-size: 19px; /* slightly larger base */
}

body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}
body {
@apply font-sans antialiased text-slate-100 bg-transparent selection:bg-white/20;
text-shadow: 0 1px 2px rgba(0,0,0,0.4);
}

h1 {
font-size: 3.2em;
line-height: 1.1;
/* ✨ Ensure all inputs, selects, and buttons use white text */
input, select, textarea, button {
@apply text-slate-100 placeholder:text-slate-400;
}
}

button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}

@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}

@theme inline {
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--color-sidebar: var(--sidebar);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
}

.dark {
--background: oklch(0.13 0.028 261.692);
--foreground: oklch(0.985 0.002 247.839);
--card: oklch(0.21 0.034 264.665);
--card-foreground: oklch(0.985 0.002 247.839);
--popover: oklch(0.21 0.034 264.665);
--popover-foreground: oklch(0.985 0.002 247.839);
--primary: oklch(0.928 0.006 264.531);
--primary-foreground: oklch(0.21 0.034 264.665);
--secondary: oklch(0.278 0.033 256.848);
--secondary-foreground: oklch(0.985 0.002 247.839);
--muted: oklch(0.278 0.033 256.848);
--muted-foreground: oklch(0.707 0.022 261.325);
--accent: oklch(0.278 0.033 256.848);
--accent-foreground: oklch(0.985 0.002 247.839);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.551 0.027 264.364);
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08);
--chart-4: oklch(0.627 0.265 303.9);
--chart-5: oklch(0.645 0.246 16.439);
--sidebar: oklch(0.21 0.034 264.665);
--sidebar-foreground: oklch(0.985 0.002 247.839);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0.002 247.839);
--sidebar-accent: oklch(0.278 0.033 256.848);
--sidebar-accent-foreground: oklch(0.985 0.002 247.839);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.551 0.027 264.364);
/* @import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap");

@import "tailwindcss";
@plugin "tailwindcss-animate";



/* Global font + smoothing */
/* html,
body {
@apply font-sans antialiased text-slate-100;
font-family: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
Roboto, Helvetica, Arial, sans-serif;
}

@layer base {
* {
@apply border-border outline-ring/50;
}
body {
@apply bg-background text-foreground;
}
} */
@custom-variant dark (&:is(.dark *));

@tailwind base;
@tailwind components;
@tailwind utilities;

html, body, #root { height: 100%; }
body { background: transparent; } */
Empty file added client/src/lib/ai.ts
Empty file.
Loading
Loading