Initial commit

This commit is contained in:
Mendiburu 2025-03-23 11:46:42 +01:00
parent 2c53f653a8
commit 32519b92e5
13 changed files with 4006 additions and 0 deletions

3
.bolt/config.json Normal file
View File

@ -0,0 +1,3 @@
{
"template": "bolt-vite-react-ts"
}

8
.bolt/prompt Normal file
View File

@ -0,0 +1,8 @@
For all designs I ask you to make, have them be beautiful, not cookie cutter. Make webpages that are fully featured and worthy for production.
By default, this template supports JSX syntax with Tailwind CSS classes, React hooks, and Lucide React for icons. Do not install other packages for UI themes, icons, etc unless absolutely necessary or I request them.
Use icons from lucide-react for logos.
Use stock photos from unsplash where appropriate, only valid URLs you know exist. Do not download the images, only link to them in image tags.

24
.gitignore vendored Normal file
View File

@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

27
eslint.config.js Normal file
View File

@ -0,0 +1,27 @@
import js from '@eslint/js';
import globals from 'globals';
import reactHooks from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';
export default [
{ ignores: ['dist'] },
js.configs.recommended,
{
files: ['**/*.{js,jsx}'],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
rules: {
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
}
];

13
index.html Normal file
View File

@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>

3732
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

29
package.json Normal file
View File

@ -0,0 +1,29 @@
{
"name": "vite-react-javascript-starter",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"lucide-react": "^0.344.0",
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"devDependencies": {
"@eslint/js": "^9.9.1",
"@vitejs/plugin-react": "^4.3.1",
"autoprefixer": "^10.4.18",
"eslint": "^9.9.1",
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
"eslint-plugin-react-refresh": "^0.4.11",
"globals": "^15.9.0",
"postcss": "^8.4.35",
"tailwindcss": "^3.4.1",
"vite": "^5.4.2"
}
}

6
postcss.config.js Normal file
View File

@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};

134
src/App.jsx Normal file
View File

@ -0,0 +1,134 @@
import React, { useState } from 'react';
import { Search, MapPin, Calendar, Bus, ArrowRight, LogIn, UserPlus } from 'lucide-react';
function App() {
const [searchQuery, setSearchQuery] = useState('');
const [activeFilter, setActiveFilter] = useState('all');
return (
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-50">
{/* Header */}
<header className="bg-white shadow-sm">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4">
<div className="flex justify-between items-center">
<h1 className="text-2xl font-bold text-indigo-600">SmartCity Hub</h1>
<div className="flex gap-4">
<button className="flex items-center gap-2 text-gray-600 hover:text-indigo-600">
<LogIn size={20} />
<span>Login</span>
</button>
<button className="flex items-center gap-2 bg-indigo-600 text-white px-4 py-2 rounded-lg hover:bg-indigo-700">
<UserPlus size={20} />
<span>Sign Up</span>
</button>
</div>
</div>
</div>
</header>
{/* Hero Section */}
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<div className="text-center mb-12">
<h2 className="text-4xl font-bold text-gray-900 mb-4">
Welcome to Your Smart City
</h2>
<p className="text-xl text-gray-600 max-w-3xl mx-auto">
Discover everything your city has to offer - from local events to transportation schedules, all in one place.
</p>
</div>
{/* Search Section */}
<div className="max-w-3xl mx-auto mb-12">
<div className="relative">
<Search className="absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400" size={24} />
<input
type="text"
placeholder="Search for locations, events, or transport..."
className="w-full pl-12 pr-4 py-4 rounded-xl border border-gray-200 focus:outline-none focus:ring-2 focus:ring-indigo-500"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
/>
</div>
<div className="flex gap-4 mt-4 justify-center">
<button
onClick={() => setActiveFilter('all')}
className={`px-4 py-2 rounded-lg ${
activeFilter === 'all' ? 'bg-indigo-600 text-white' : 'bg-white text-gray-600'
}`}
>
All
</button>
<button
onClick={() => setActiveFilter('locations')}
className={`px-4 py-2 rounded-lg ${
activeFilter === 'locations' ? 'bg-indigo-600 text-white' : 'bg-white text-gray-600'
}`}
>
Locations
</button>
<button
onClick={() => setActiveFilter('events')}
className={`px-4 py-2 rounded-lg ${
activeFilter === 'events' ? 'bg-indigo-600 text-white' : 'bg-white text-gray-600'
}`}
>
Events
</button>
<button
onClick={() => setActiveFilter('transport')}
className={`px-4 py-2 rounded-lg ${
activeFilter === 'transport' ? 'bg-indigo-600 text-white' : 'bg-white text-gray-600'
}`}
>
Transport
</button>
</div>
</div>
{/* Features Grid */}
<div className="grid md:grid-cols-3 gap-8">
<div className="bg-white p-6 rounded-xl shadow-sm hover:shadow-md transition-shadow">
<div className="w-12 h-12 bg-indigo-100 rounded-lg flex items-center justify-center mb-4">
<MapPin className="text-indigo-600" size={24} />
</div>
<h3 className="text-xl font-semibold mb-2">Points of Interest</h3>
<p className="text-gray-600 mb-4">
Discover the best locations in your city, from restaurants to parks and cultural venues.
</p>
<a href="#" className="flex items-center text-indigo-600 hover:text-indigo-700">
Explore places <ArrowRight size={16} className="ml-2" />
</a>
</div>
<div className="bg-white p-6 rounded-xl shadow-sm hover:shadow-md transition-shadow">
<div className="w-12 h-12 bg-indigo-100 rounded-lg flex items-center justify-center mb-4">
<Calendar className="text-indigo-600" size={24} />
</div>
<h3 className="text-xl font-semibold mb-2">Local Events</h3>
<p className="text-gray-600 mb-4">
Stay updated with the latest events, festivals, and community gatherings in your area.
</p>
<a href="#" className="flex items-center text-indigo-600 hover:text-indigo-700">
View events <ArrowRight size={16} className="ml-2" />
</a>
</div>
<div className="bg-white p-6 rounded-xl shadow-sm hover:shadow-md transition-shadow">
<div className="w-12 h-12 bg-indigo-100 rounded-lg flex items-center justify-center mb-4">
<Bus className="text-indigo-600" size={24} />
</div>
<h3 className="text-xl font-semibold mb-2">Public Transport</h3>
<p className="text-gray-600 mb-4">
Access real-time schedules and routes for buses, trains, and other public transportation.
</p>
<a href="#" className="flex items-center text-indigo-600 hover:text-indigo-700">
Check schedules <ArrowRight size={16} className="ml-2" />
</a>
</div>
</div>
</div>
</div>
);
}
export default App;

3
src/index.css Normal file
View File

@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

10
src/main.jsx Normal file
View File

@ -0,0 +1,10 @@
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.jsx';
import './index.css';
createRoot(document.getElementById('root')).render(
<StrictMode>
<App />
</StrictMode>
);

8
tailwind.config.js Normal file
View File

@ -0,0 +1,8 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
theme: {
extend: {},
},
plugins: [],
};

9
vite.config.js Normal file
View File

@ -0,0 +1,9 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
optimizeDeps: {
exclude: ['lucide-react'],
},
});