feat: add projects page route and navigation link

- Add GET /projects route in server.js with authentication check
- Serve projects.html when authenticated, redirect to login otherwise
- Add navigation header to both landing page and projects page
- Include Sessions, Projects navigation links with active state styling
- Add logout button to navigation header
- Style navigation with dark theme matching existing design
- Make navigation responsive for mobile devices

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
uroma
2026-01-19 17:15:00 +00:00
Unverified
parent 91e4835e03
commit 3aa4af93ff
3 changed files with 242 additions and 1 deletions

View File

@@ -6,8 +6,113 @@
<title>Claude Code</title> <title>Claude Code</title>
<link rel="stylesheet" href="/claude/css/style.css"> <link rel="stylesheet" href="/claude/css/style.css">
<link rel="stylesheet" href="/claude/claude-ide/sessions-landing.css"> <link rel="stylesheet" href="/claude/claude-ide/sessions-landing.css">
<style>
/* Navigation Header Styles */
.nav-header {
position: fixed;
top: 0;
left: 0;
right: 0;
background: rgba(13, 13, 13, 0.95);
backdrop-filter: blur(10px);
border-bottom: 1px solid #333;
padding: 16px 24px;
display: flex;
align-items: center;
justify-content: space-between;
z-index: 1000;
}
.nav-logo {
font-size: 20px;
font-weight: 700;
background: linear-gradient(135deg, #4a9eff 0%, #a78bfa 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.nav-links {
display: flex;
align-items: center;
gap: 8px;
}
.nav-link {
padding: 8px 16px;
background: transparent;
border: 1px solid #333;
border-radius: 8px;
color: #e0e0e0;
text-decoration: none;
font-size: 14px;
font-weight: 500;
transition: all 0.2s ease;
cursor: pointer;
}
.nav-link:hover {
background: #252525;
border-color: #4a9eff;
color: #4a9eff;
}
.nav-link.active {
background: rgba(74, 158, 255, 0.15);
border-color: #4a9eff;
color: #4a9eff;
}
.nav-logout {
padding: 8px 16px;
background: transparent;
border: none;
color: #888;
font-size: 14px;
cursor: pointer;
transition: color 0.2s ease;
}
.nav-logout:hover {
color: #e0e0e0;
}
/* Adjust hero section for fixed header */
.hero-section {
padding-top: 100px;
}
@media (max-width: 768px) {
.nav-header {
padding: 12px 16px;
}
.nav-logo {
font-size: 18px;
}
.nav-link {
padding: 6px 12px;
font-size: 13px;
}
.hero-section {
padding-top: 80px;
}
}
</style>
</head> </head>
<body class="sessions-page"> <body class="sessions-page">
<!-- Navigation Header -->
<nav class="nav-header">
<div class="nav-logo">Claude Code</div>
<div class="nav-links">
<a href="/claude/" class="nav-link active">Sessions</a>
<a href="/projects" class="nav-link">Projects</a>
<button class="nav-logout" onclick="logout()">Logout</button>
</div>
</nav>
<!-- Hero Section --> <!-- Hero Section -->
<section class="hero-section"> <section class="hero-section">
<h1 class="hero-title">Claude Code</h1> <h1 class="hero-title">Claude Code</h1>
@@ -57,5 +162,15 @@
<script src="/claude/js/app.js"></script> <script src="/claude/js/app.js"></script>
<script src="/claude/claude-ide/sessions-landing.js"></script> <script src="/claude/claude-ide/sessions-landing.js"></script>
<script>
async function logout() {
try {
await fetch('/claude/api/logout', { method: 'POST' });
window.location.href = '/claude/';
} catch (error) {
console.error('Logout failed:', error);
}
}
</script>
</body> </body>
</html> </html>

View File

@@ -6,14 +6,119 @@
<title>Projects - Claude Code Web Interface</title> <title>Projects - Claude Code Web Interface</title>
<link rel="stylesheet" href="/css/style.css"> <link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/claude-ide/projects.css"> <link rel="stylesheet" href="/claude-ide/projects.css">
<style>
/* Navigation Header Styles */
.nav-header {
position: fixed;
top: 0;
left: 0;
right: 0;
background: rgba(13, 13, 13, 0.95);
backdrop-filter: blur(10px);
border-bottom: 1px solid #333;
padding: 16px 24px;
display: flex;
align-items: center;
justify-content: space-between;
z-index: 1000;
}
.nav-logo {
font-size: 20px;
font-weight: 700;
background: linear-gradient(135deg, #4a9eff 0%, #a78bfa 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.nav-links {
display: flex;
align-items: center;
gap: 8px;
}
.nav-link {
padding: 8px 16px;
background: transparent;
border: 1px solid #333;
border-radius: 8px;
color: #e0e0e0;
text-decoration: none;
font-size: 14px;
font-weight: 500;
transition: all 0.2s ease;
cursor: pointer;
}
.nav-link:hover {
background: #252525;
border-color: #4a9eff;
color: #4a9eff;
}
.nav-link.active {
background: rgba(74, 158, 255, 0.15);
border-color: #4a9eff;
color: #4a9eff;
}
.nav-logout {
padding: 8px 16px;
background: transparent;
border: none;
color: #888;
font-size: 14px;
cursor: pointer;
transition: color 0.2s ease;
}
.nav-logout:hover {
color: #e0e0e0;
}
/* Adjust main content for fixed header */
.projects-header {
margin-top: 70px;
}
@media (max-width: 768px) {
.nav-header {
padding: 12px 16px;
}
.nav-logo {
font-size: 18px;
}
.nav-link {
padding: 6px 12px;
font-size: 13px;
}
.projects-header {
margin-top: 60px;
}
}
</style>
</head> </head>
<body> <body>
<!-- Navigation Header -->
<nav class="nav-header">
<div class="nav-logo">Claude Code</div>
<div class="nav-links">
<a href="/claude/" class="nav-link">Sessions</a>
<a href="/projects" class="nav-link active">Projects</a>
<button class="nav-logout" onclick="logout()">Logout</button>
</div>
</nav>
<div id="app"> <div id="app">
<!-- Header --> <!-- Header -->
<header class="projects-header"> <header class="projects-header">
<div class="header-left"> <div class="header-left">
<h1>Projects</h1> <h1>Projects</h1>
<a href="/" class="back-link">Back to Sessions</a> <a href="/claude/" class="back-link">Back to Sessions</a>
</div> </div>
<div class="header-right"> <div class="header-right">
<input type="text" id="search-input" class="search-input" placeholder="Search projects..."> <input type="text" id="search-input" class="search-input" placeholder="Search projects...">
@@ -96,5 +201,15 @@
</div> </div>
<script src="/claude-ide/projects.js"></script> <script src="/claude-ide/projects.js"></script>
<script>
async function logout() {
try {
await fetch('/claude/api/logout', { method: 'POST' });
window.location.href = '/claude/';
} catch (error) {
console.error('Logout failed:', error);
}
}
</script>
</body> </body>
</html> </html>

View File

@@ -89,6 +89,17 @@ app.get('/claude/ide/*', requireAuth, (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'claude-ide', 'index.html')); res.sendFile(path.join(__dirname, 'public', 'claude-ide', 'index.html'));
}); });
// Projects page route
app.get('/projects', (req, res) => {
if (req.session.userId) {
// Authenticated - serve projects page
res.sendFile(path.join(__dirname, 'public', 'projects.html'));
} else {
// Not authenticated - redirect to login
res.redirect('/claude/');
}
});
// Serve static files (must come after specific routes) // Serve static files (must come after specific routes)
app.use('/claude', express.static(path.join(__dirname, 'public'))); app.use('/claude', express.static(path.join(__dirname, 'public')));