CODEX_ADK/FRONTEND/lib/components/navigation_sidebar.dart
jean-philippe 3fae2fcbe1 Initial commit: CODEX_ADK (Svrnty Console) MVP v1.0.0
This is the initial commit for the CODEX_ADK project, a full-stack AI agent
management platform featuring:

BACKEND (ASP.NET Core 8.0):
- CQRS architecture with 6 commands and 7 queries
- 16 API endpoints (all working and tested)
- PostgreSQL database with 5 entities
- AES-256 encryption for API keys
- FluentValidation on all commands
- Rate limiting and CORS configured
- OpenAPI/Swagger documentation
- Docker Compose setup (PostgreSQL + Ollama)

FRONTEND (Flutter 3.x):
- Dark theme with Svrnty branding
- Collapsible sidebar navigation
- CQRS API client with Result<T> error handling
- Type-safe endpoints from OpenAPI schema
- Multi-platform support (Web, iOS, Android, macOS, Linux, Windows)

DOCUMENTATION:
- Comprehensive API reference
- Architecture documentation
- Development guidelines for Claude Code
- API integration guides
- context-claude.md project overview

Status: Backend ready (Grade A-), Frontend integration pending

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-26 18:32:38 -04:00

323 lines
10 KiB
Dart

import 'package:flutter/material.dart';
import 'package:animate_do/animate_do.dart';
import 'package:iconsax/iconsax.dart';
import 'package:getwidget/getwidget.dart';
class NavigationSidebar extends StatefulWidget {
final bool isExpanded;
final Function(String) onNavigate;
final String currentPage;
const NavigationSidebar({
super.key,
required this.isExpanded,
required this.onNavigate,
required this.currentPage,
});
@override
State<NavigationSidebar> createState() => _NavigationSidebarState();
}
class _NavigationSidebarState extends State<NavigationSidebar> {
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final width = widget.isExpanded ? 250.0 : 70.0;
return AnimatedContainer(
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
width: width,
decoration: BoxDecoration(
color: colorScheme.surfaceContainerLow,
border: Border(
right: BorderSide(
color: colorScheme.outline.withValues(alpha: 0.2),
width: 1,
),
),
),
child: Column(
children: [
// Svrnty Logo Section
_buildLogoSection(colorScheme),
const SizedBox(height: 20),
// Navigation Menu Items
Expanded(
child: ListView(
padding: const EdgeInsets.symmetric(horizontal: 8),
children: [
_buildMenuItem(
icon: Iconsax.home,
title: 'Dashboard',
pageId: 'dashboard',
colorScheme: colorScheme,
),
const SizedBox(height: 8),
_buildMenuItem(
icon: Iconsax.hierarchy_square,
title: 'The Architech',
pageId: 'architech',
colorScheme: colorScheme,
),
const SizedBox(height: 8),
_buildMenuItem(
icon: Iconsax.cpu,
title: 'Agents',
pageId: 'agents',
colorScheme: colorScheme,
),
const SizedBox(height: 8),
_buildMenuItem(
icon: Iconsax.chart_square,
title: 'Analytics',
pageId: 'analytics',
colorScheme: colorScheme,
),
const SizedBox(height: 8),
_buildMenuItem(
icon: Iconsax.box,
title: 'Tools',
pageId: 'tools',
colorScheme: colorScheme,
),
const SizedBox(height: 8),
_buildMenuItem(
icon: Iconsax.setting_2,
title: 'Settings',
pageId: 'settings',
colorScheme: colorScheme,
),
],
),
),
// User Profile Section (bottom)
_buildUserSection(colorScheme),
],
),
);
}
Widget _buildLogoSection(ColorScheme colorScheme) {
return Container(
padding: EdgeInsets.symmetric(
vertical: 20,
horizontal: widget.isExpanded ? 20 : 12,
),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: colorScheme.outline.withValues(alpha: 0.2),
width: 1,
),
),
),
child: widget.isExpanded
? FadeIn(
duration: const Duration(milliseconds: 200),
child: Row(
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: colorScheme.primary,
borderRadius: BorderRadius.circular(8),
),
child: const Text(
'S',
style: TextStyle(
color: Colors.white,
fontSize: 23,
fontWeight: FontWeight.bold,
),
),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Svrnty',
style: TextStyle(
fontSize: 20.7,
fontWeight: FontWeight.bold,
color: colorScheme.onSurface,
),
),
Text(
'Console',
style: TextStyle(
fontSize: 12.65,
color: colorScheme.onSurfaceVariant,
),
),
],
),
),
],
),
)
: Center(
child: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: colorScheme.primary,
borderRadius: BorderRadius.circular(8),
),
child: const Text(
'S',
style: TextStyle(
color: Colors.white,
fontSize: 23,
fontWeight: FontWeight.bold,
),
),
),
),
);
}
Widget _buildMenuItem({
required IconData icon,
required String title,
required String pageId,
required ColorScheme colorScheme,
}) {
final isActive = widget.currentPage == pageId;
return FadeInLeft(
duration: const Duration(milliseconds: 300),
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: () => widget.onNavigate(pageId),
borderRadius: BorderRadius.circular(12),
child: AnimatedContainer(
duration: const Duration(milliseconds: 200),
padding: EdgeInsets.symmetric(
vertical: 14,
horizontal: widget.isExpanded ? 16 : 12,
),
decoration: BoxDecoration(
color: isActive
? colorScheme.primary.withValues(alpha: 0.25)
: Colors.transparent,
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: isActive
? colorScheme.primary.withValues(alpha: 0.7)
: Colors.transparent,
width: 2,
),
),
child: Row(
children: [
Icon(
icon,
color: isActive
? Colors.white
: colorScheme.onSurfaceVariant,
size: 24,
),
if (widget.isExpanded) ...[
const SizedBox(width: 16),
Expanded(
child: FadeIn(
duration: const Duration(milliseconds: 200),
child: Text(
title,
style: TextStyle(
fontSize: 17.25,
fontWeight:
isActive ? FontWeight.w600 : FontWeight.w400,
color: isActive
? Colors.white
: colorScheme.onSurface,
),
),
),
),
],
],
),
),
),
),
);
}
Widget _buildUserSection(ColorScheme colorScheme) {
return Container(
padding: EdgeInsets.all(widget.isExpanded ? 16 : 12),
decoration: BoxDecoration(
border: Border(
top: BorderSide(
color: colorScheme.outline.withValues(alpha: 0.2),
width: 1,
),
),
),
child: widget.isExpanded
? FadeIn(
duration: const Duration(milliseconds: 200),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
GFAvatar(
radius: 18,
backgroundColor: colorScheme.primary.withValues(alpha: 0.3),
shape: GFAvatarShape.circle,
child: Icon(
Iconsax.user,
color: colorScheme.primary,
size: 18,
),
),
const SizedBox(width: 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Admin',
style: TextStyle(
fontSize: 14.95,
fontWeight: FontWeight.w600,
color: colorScheme.onSurface,
),
),
Text(
'admin@svrnty.ai',
style: TextStyle(
fontSize: 11.5,
color: colorScheme.onSurfaceVariant,
),
overflow: TextOverflow.ellipsis,
),
],
),
),
],
),
)
: Center(
child: GFAvatar(
radius: 20,
backgroundColor: colorScheme.primary.withValues(alpha: 0.2),
shape: GFAvatarShape.circle,
child: Icon(
Iconsax.user,
color: colorScheme.primary,
size: 20,
),
),
),
);
}
}