Skip to content

Commit

Permalink
feat(dashboard): Created a interactive dashboard to be used with prod. (
Browse files Browse the repository at this point in the history
#4)

* Update cd-dev.yaml

* updates lint errors

* added test command

* added nginx.conf

* added better functionality

* added map page

* added place parsing funcitonality and massive refactor

* implemented useQuery, and better state management
  • Loading branch information
mikedegeofroy authored Nov 21, 2024
1 parent 7bc6c58 commit d91581e
Show file tree
Hide file tree
Showing 24 changed files with 740 additions and 209 deletions.
9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,22 @@
"@radix-ui/react-scroll-area": "^1.2.0",
"@radix-ui/react-select": "^2.1.2",
"@radix-ui/react-slot": "^1.1.0",
"@tanstack/react-query": "^5.61.0",
"@types/leaflet": "^1.9.14",
"@types/react-leaflet": "^3.0.0",
"axios": "^1.7.7",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"leaflet": "^1.9.4",
"lucide-react": "^0.446.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-hot-toast": "^2.4.1",
"react-leaflet": "^4.2.1",
"react-router-dom": "^6.28.0",
"tailwind-merge": "^2.5.2",
"tailwindcss-animate": "^1.0.7"
"tailwindcss-animate": "^1.0.7",
"zustand": "^5.0.1"
},
"devDependencies": {
"@eslint/js": "^9.9.0",
Expand Down
52 changes: 42 additions & 10 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,53 @@
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import './App.css';
import 'leaflet/dist/leaflet.css';
import { Sidebar } from './components/sidebar';
import Dashboard from './pages/dashboard.page';
import { TagsPage } from './pages/tags.page';
import { MapPage } from './pages/map.page';
import { Toaster } from 'react-hot-toast';
import { SettingsPage } from './pages/settings.page';
import DashboardSidebar from './modules/dashboard-sidebar.module';
import { DashboardPage } from './pages/dashboard.page';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { AddPlacePage } from './pages/add-place.page';


const queryClient = new QueryClient();

function App() {

return (
<BrowserRouter>
<Routes>
<Route path={"/"} element={<Sidebar />} >
<Route path="dashboard" element={<Dashboard />} />
<Route path="tags" element={<TagsPage />} />
<Route path="settings" element={<></>} />
</Route>
</Routes>
</BrowserRouter>
<QueryClientProvider client={queryClient}>
<BrowserRouter>
<Routes>
<Route path={"/"} element={<Sidebar />} >
<Route path="dashboard" element={<DashboardSidebar />} >
<Route path=":id" element={<DashboardPage />} />
</Route>
<Route path="tags" element={<TagsPage />} />
<Route path="map" element={<MapPage />} />
<Route path="add-place" element={<AddPlacePage />} />
<Route path="settings" element={<SettingsPage />} />
</Route>
</Routes>
<Toaster toastOptions={{
position: 'top-right',
className: '',
style: {
color: 'black',
padding: '5px',
boxShadow: 'none',
border: '1px solid #f3f4f6',
fontSize: '15px'
},
icon: null,
iconTheme: {
primary: 'black',
secondary: 'white'
}
}} />
</BrowserRouter>
</QueryClientProvider>
);
}

Expand Down
27 changes: 0 additions & 27 deletions src/api/places.api.ts

This file was deleted.

19 changes: 18 additions & 1 deletion src/components/sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import { Command, Inbox, Settings2, Tag } from "lucide-react"
import { useDashboardStore } from "@/shared/stores/places.store";
import { Command, Inbox, Map, MapPinPlus, Settings2, Tag } from "lucide-react"
import { useEffect } from "react";
import { Outlet, useNavigate } from "react-router-dom"
import { fetchTags } from "@/shared/api/tags.api";

export const Sidebar = () => {
const navigate = useNavigate();

const { setTags } = useDashboardStore();

useEffect(() => {
fetchTags().then((x) => {
if (x) setTags(x);
});
}, [setTags]);

return (

<div className="flex h-svh overflow-hidden text-left">
Expand All @@ -17,6 +28,12 @@ export const Sidebar = () => {
<div onClick={() => navigate('/tags')} className="h-8 w-8 hover:bg-gray-100 cursor-pointer p-2 rounded-md flex items-center justify-center">
<Tag />
</div>
<div onClick={() => navigate('/add-place')} className="h-8 w-8 hover:bg-gray-100 cursor-pointer p-2 rounded-md flex items-center justify-center">
<MapPinPlus />
</div>
<div onClick={() => navigate('/map')} className="h-8 w-8 hover:bg-gray-100 cursor-pointer p-2 rounded-md flex items-center justify-center">
<Map />
</div>
<div onClick={() => navigate('/settings')} className="h-8 w-8 hover:bg-gray-100 cursor-pointer p-2 rounded-md flex items-center justify-center">
<Settings2 />
</div>
Expand Down
6 changes: 3 additions & 3 deletions src/components/tag.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Tag } from "@/interfaces/place.interface"

export const TagComponent = ({ tag, onClick }: { tag: Tag, onClick?: () => void }) => {
return <div onClick={onClick} className="flex text-sm rounded-full cursor-pointer border w-fit px-2 py-1">
<img className="w-auto h-[20px] mr-2" src={tag.icon} />
<p className="pr-2">
return <div onClick={onClick} className="inline-flex w-fit h-fit text-sm rounded-full cursor-pointer border">
<img className="w-[20px] shrink-0 min-w-[20px] my-1 h-[20px] ml-2 mr-1" src={tag.icon} />
<p className="my-1 mr-3 text-nowrap">
{tag.name}
</p>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/textarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
return (
<textarea
className={cn(
"flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
"flex min-h-[120px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
className
)}
ref={ref}
Expand Down
5 changes: 5 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
@tailwind components;
@tailwind utilities;

.leaflet-container {
height: 100%;
width: 100%;
}

:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/place.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export interface Place {
address: string;
description: string;
id: number;
image: string[];
images: string[];
location: Location;
priceAvg: number;
reviewCount: number;
Expand Down
47 changes: 47 additions & 0 deletions src/modules/dashboard-sidebar.module.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useState } from 'react';
import { Input } from '@/components/ui/input';
import { Outlet, useNavigate } from 'react-router-dom';
import { usePlaces } from '@/shared/hooks/usePlaces';

export default function DashboardSidebar() {
const { data: places } = usePlaces();
const [filter, setFilter] = useState('');

const navigate = useNavigate();

const filteredPlaces = places?.filter((place) =>
place.title.toLowerCase().includes(filter.toLowerCase())
);

return (
<div className="w-full h-full flex">
<div className="flex flex-col w-[350px] border-gray-100 border-r">
<div className="p-5 pt-4 space-y-5 border-gray-100 border-b">
<h1 className="text-xl">All Places</h1>
<Input
placeholder="Filter places..."
value={filter}
onChange={(e) => setFilter(e.target.value)}
/>
</div>
<div className='h-full divide-gray-100 w-full overflow-y-scroll'>
{filteredPlaces?.map((x, index) => (
<div key={`${x.id}_${index}`} onClick={() => {
navigate(`${x.id}`);
}} className="cursor-pointer px-3 py-2 h-24 hover:bg-gray-100 w-full">
<p>
{x.title}
</p>
<p className="text-muted-foreground line-clamp-2 text-sm">
{x.address}
</p>
</div>
))}
</div>
</div>
<div className="w-full m-5">
<Outlet />
</div>
</div>
);
}
Loading

0 comments on commit d91581e

Please sign in to comment.