feat: add Phase 1 infrastructure skeleton

Backend (FastAPI):
- docker-compose with all 4 services
- FastAPI app with health endpoints
- SQLAlchemy models for all tables
- Placeholder API endpoints for all routes
- Config and database modules
- requirements.txt with all dependencies

Frontend (React):
- package.json with React, Tailwind, React Query, React Router
- Vite config with API proxy
- Tailwind and TypeScript configs
- Basic App with routing skeleton
- Placeholder pages (Dashboard, MealDetail, Pantry)

Infrastructure:
- nginx config for reverse proxy
- Dockerfile for backend and frontend
This commit is contained in:
2026-05-04 19:29:35 -07:00
parent 0c5b0aa5ed
commit 1328ec359d
26 changed files with 761 additions and 0 deletions
+41
View File
@@ -0,0 +1,41 @@
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import Dashboard from './pages/Dashboard'
import MealDetail from './pages/MealDetail'
import Pantry from './pages/Pantry'
const queryClient = new QueryClient()
function App() {
return (
<QueryClientProvider client={queryClient}>
<BrowserRouter>
<div className="min-h-screen bg-gray-50">
<nav className="bg-white shadow-sm">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between h-16">
<div className="flex space-x-8">
<Link to="/" className="inline-flex items-center px-1 pt-1 text-sm font-medium text-gray-900">
MealPlanner
</Link>
<Link to="/pantry" className="inline-flex items-center px-1 pt-1 text-sm font-medium text-gray-500 hover:text-gray-900">
Pantry
</Link>
</div>
</div>
</div>
</nav>
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="/meals/:id" element={<MealDetail />} />
<Route path="/pantry" element={<Pantry />} />
</Routes>
</main>
</div>
</BrowserRouter>
</QueryClientProvider>
)
}
export default App
+10
View File
@@ -0,0 +1,10 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
+10
View File
@@ -0,0 +1,10 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)
+8
View File
@@ -0,0 +1,8 @@
export default function Dashboard() {
return (
<div className="space-y-6">
<h1 className="text-2xl font-bold text-gray-900">This Week's Meal Plan</h1>
<p className="text-gray-500">Meal planning UI coming soon...</p>
</div>
)
}
+11
View File
@@ -0,0 +1,11 @@
import { useParams } from 'react-router-dom'
export default function MealDetail() {
const { id } = useParams()
return (
<div className="space-y-6">
<h1 className="text-2xl font-bold text-gray-900">Meal Detail</h1>
<p className="text-gray-500">Meal {id} details coming soon...</p>
</div>
)
}