Skip to content
This repository has been archived by the owner on May 4, 2024. It is now read-only.

Commit

Permalink
Redo road details page structure
Browse files Browse the repository at this point in the history
  • Loading branch information
zoi23333 committed Oct 6, 2023
1 parent 0c24413 commit f1e317b
Show file tree
Hide file tree
Showing 10 changed files with 479 additions and 72 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.idea/
.DS_Store
23 changes: 8 additions & 15 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,23 @@
import { FC } from 'react';
import {
BrowserRouter as Router,
Navigate,
Route,
Routes,
} from 'react-router-dom';

import Navbar from './Components/Navbar';
import RoadConditions from './pages/RoadConditions';
import Conditions from './pages/Conditions';
import { BrowserRouter as Router, Navigate } from 'react-router-dom';

import './App.css';
import { Route, Routes } from 'react-router-dom';
import RoadDetails from './pages/RoadDetails';

import Conditions from './pages/Conditions';

const App: FC = () => {
return (
<div className="App">
<Router>
<Navbar />
<Routes>
<Route index element={<Navigate to="/conditions" replace />} />
<Route path="/conditions" Component={Conditions} />
<Route path="/road_conditions" Component={RoadConditions} />
<Route index element={<Navigate to="/map" replace />} />
<Route path="/map" element={<Conditions />} />
<Route path="/road-details" element={<RoadDetails />} />
</Routes>
</Router>
</div>
);
};

export default App;
25 changes: 0 additions & 25 deletions frontend/src/Components/Navbar.test.tsx

This file was deleted.

32 changes: 0 additions & 32 deletions frontend/src/Components/Navbar.tsx

This file was deleted.

133 changes: 133 additions & 0 deletions frontend/src/Components/RoadDetails/ImageGallery.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import React, { useState } from 'react';

interface Image {
id: number;
url: string;
}

const images: Image[] = [
{
id: 1,
url: 'https://upload.wikimedia.org/wikipedia/commons/4/43/2015-04-02_18_21_50_View_north_along_U.S._Route_95_in_the_Forty_Mile_Desert_of_Churchill_County%2C_Nevada.JPG',
},
{
id: 2,
url: 'https://upload.wikimedia.org/wikipedia/commons/4/43/2015-04-02_18_21_50_View_north_along_U.S._Route_95_in_the_Forty_Mile_Desert_of_Churchill_County%2C_Nevada.JPG',
},
{
id: 3,
url: 'https://upload.wikimedia.org/wikipedia/commons/4/43/2015-04-02_18_21_50_View_north_along_U.S._Route_95_in_the_Forty_Mile_Desert_of_Churchill_County%2C_Nevada.JPG',
},
{
id: 4,
url: 'https://upload.wikimedia.org/wikipedia/commons/4/43/2015-04-02_18_21_50_View_north_along_U.S._Route_95_in_the_Forty_Mile_Desert_of_Churchill_County%2C_Nevada.JPG',
},
{
id: 5,
url: 'https://upload.wikimedia.org/wikipedia/commons/4/43/2015-04-02_18_21_50_View_north_along_U.S._Route_95_in_the_Forty_Mile_Desert_of_Churchill_County%2C_Nevada.JPG',
},
{
id: 6,
url: 'https://upload.wikimedia.org/wikipedia/commons/4/43/2015-04-02_18_21_50_View_north_along_U.S._Route_95_in_the_Forty_Mile_Desert_of_Churchill_County%2C_Nevada.JPG',
},
{
id: 7,
url: 'https://upload.wikimedia.org/wikipedia/commons/4/43/2015-04-02_18_21_50_View_north_along_U.S._Route_95_in_the_Forty_Mile_Desert_of_Churchill_County%2C_Nevada.JPG',
},
{
id: 8,
url: 'https://hips.hearstapps.com/hmg-prod/images/1/roadbootie-main-1520457496.jpg?crop=0.848xw:1xh;center,top&resize=1200:*',
},
{
id: 9,
url: 'https://hips.hearstapps.com/hmg-prod/images/1/roadbootie-main-1520457496.jpg?crop=0.848xw:1xh;center,top&resize=1200:*',
},
{
id: 10,
url: 'https://hips.hearstapps.com/hmg-prod/images/1/roadbootie-main-1520457496.jpg?crop=0.848xw:1xh;center,top&resize=1200:*',
},
{
id: 11,
url: 'https://hips.hearstapps.com/hmg-prod/images/1/roadbootie-main-1520457496.jpg?crop=0.848xw:1xh;center,top&resize=1200:*',
},
{
id: 12,
url: 'https://hips.hearstapps.com/hmg-prod/images/1/roadbootie-main-1520457496.jpg?crop=0.848xw:1xh;center,top&resize=1200:*',
},
{
id: 13,
url: 'https://hips.hearstapps.com/hmg-prod/images/1/roadbootie-main-1520457496.jpg?crop=0.848xw:1xh;center,top&resize=1200:*',
},
{
id: 14,
url: 'https://hips.hearstapps.com/hmg-prod/images/1/roadbootie-main-1520457496.jpg?crop=0.848xw:1xh;center,top&resize=1200:*',
},
{
id: 15,
url: 'https://hips.hearstapps.com/hmg-prod/images/1/roadbootie-main-1520457496.jpg?crop=0.848xw:1xh;center,top&resize=1200:*',
},
];

const ImageGallery: React.FC = () => {
const [scrollPosition, setScrollPosition] = useState(0);

const openImageInNewTab = (imageUrl: string) => {
window.open(imageUrl, '_blank');
};

const handleScroll = (scrollOffset: number) => {
const newScrollPosition = scrollPosition + scrollOffset;

// Calculate the maximum scroll limit based on the total image width
const maxScrollLimit = (images.length - 11.4) * 124; // 120 is the width of each image

// Ensure the scroll stays within bounds
const boundedScrollPosition = Math.max(
0,
Math.min(newScrollPosition, maxScrollLimit),
);

setScrollPosition(boundedScrollPosition);
};

return (
<div className="image-gallery-container">
<div className="image-gallery-page">
<div
className="image-container"
style={{ transform: `translateX(-${scrollPosition}px)` }}
>
{images.map((image) => (
<img
key={image.id}
src={image.url}
alt={`Image ${image.id}`}
onClick={() => openImageInNewTab(image.url)}
className="image-thumbnail"
/>
))}
</div>
</div>
<button
className={`arrow-button left-arrow ${
scrollPosition === 0 ? 'disabled' : ''
}`}
onClick={() => handleScroll(-120)}
disabled={scrollPosition === 0}
>
&#9658;
</button>
<button
className={`arrow-button right-arrow ${
scrollPosition === (images.length - 1) * 124 ? 'disabled' : ''
}`}
onClick={() => handleScroll(120)}
disabled={scrollPosition === (images.length - 1) * 124}
>
&#9658;
</button>
</div>
);
};

export default ImageGallery;
21 changes: 21 additions & 0 deletions frontend/src/Components/RoadDetails/MapArea.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import ImageGallery from './ImageGallery';
import MapWrapper from '../Map/MapWrapper';

/**
* The map area op the road details(road inspect) page
*/
const MapArea: React.FC = () => {
return (
<div className="map-area">
<div className="map_area" style={{ height: '100%' }}>
<MapWrapper></MapWrapper>
</div>
<div className="imageGallery_container">
<ImageGallery /> {/* Use the imageGallery component */}
</div>
</div>
);
};

export default MapArea;
15 changes: 15 additions & 0 deletions frontend/src/Components/RoadDetails/RoadImage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';

const maproadStyles = {
margin: 0,
padding: 20,
color: '#333',
};

const road_area = <h1 style={maproadStyles}>Road surface image</h1>;

const RoadImage: React.FC = () => {
return <div className="road-image">{road_area}</div>;
};

export default RoadImage;
63 changes: 63 additions & 0 deletions frontend/src/Components/RoadDetails/TopBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// The TopBar for RoadDetails page
import React from 'react';
import { Link, useNavigate } from 'react-router-dom'; // Import useNavigate

interface TopBarProps {
/**
* The toggle button value
*/
isToggleOn: React.Dispatch<React.SetStateAction<boolean>>;
}

const return_btn = (
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
className="btn bi bi-chevron-left btnWhite"
viewBox="0 0 16 16"
>
<path
fillRule="evenodd"
d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z"
/>
</svg>
);

/**
* The Topbar with return and toggle button inside
*/
const TopBar: React.FC<TopBarProps> = ({ isToggleOn }) => {
const navigate = useNavigate(); // Get the navigate function

const handleReturn = () => {
// Navigate back to the home page when the button is clicked
navigate('/');
};

const handleToggleMiddleArea = () => {
// Toggle the state to show/hide MiddleArea2
isToggleOn((prevState) => !prevState);
};

return (
<div className="top-bar topBar-container ">
<Link to="/" onClick={handleReturn} className="btnLinkContainer">
{return_btn}
</Link>
<div className="toggle-container">
<div className="toggle-label">
<span className="toggle-text">Map mode</span>
<label className="toggle-switch">
<input type="checkbox" onChange={handleToggleMiddleArea} />
<span className="slider"></span>
</label>
<span className="toggle-text">Road mode</span>
</div>
</div>
</div>
);
};

export default TopBar;
Loading

0 comments on commit f1e317b

Please sign in to comment.