Skip to content

Commit

Permalink
added checkout better btn + location / cart item separator
Browse files Browse the repository at this point in the history
  • Loading branch information
MathisZerbib committed Jun 3, 2024
1 parent d4465ef commit a271888
Show file tree
Hide file tree
Showing 8 changed files with 423 additions and 120 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"axios": "^1.7.2",
"buffer": "^6.0.3",
"leaflet": "^1.9.4",
"nominatim-client": "^3.2.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-leaflet": "^4.2.1",
Expand Down
2 changes: 1 addition & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ function App() {
}
></NetworkBadge>
</div>
{network && wallet && <WalletBalanceTon walletAddress={wallet} />}
{/* {network && wallet && <WalletBalanceTon walletAddress={wallet} />} */}
</div>
</FlexBoxRowSpaceBetween>
<WelcomeStore />
Expand Down
19 changes: 18 additions & 1 deletion src/components/AddToCartButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,24 @@ export function AddToCartButton({ amount, item }: AddToCartButtonProps) {
</AddToCartButtonCard>
) : (
<CenterDiv>
<p style={{ color: "red" }}>Out of stock</p>
{/* display button out of stock */}

<AddToCartButtonCard disabled={true}>
<FlexBoxRow
style={{
justifyContent: "space-between",
alignItems: "center",
}}
>
<span
style={{
fontSize: "12px",
}}
>
Out of stock
</span>
</FlexBoxRow>
</AddToCartButtonCard>
</CenterDiv>
);
}
220 changes: 170 additions & 50 deletions src/components/AutoFetchGeolocation.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
// Existing imports...
import React, { useEffect, useState, useRef } from "react";
import { MapContainer, TileLayer, Marker, Popup, useMap } from "react-leaflet";
import L from "leaflet";
import "leaflet/dist/leaflet.css";
import styled from "styled-components";
import { Options, ReverseOptions, SearchResultItem } from "nominatim-client";
import nominatim from "nominatim-client";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faLocationArrow } from "@fortawesome/free-solid-svg-icons";

// Fix for default marker icon issues with Webpack
import icon from "leaflet/dist/images/marker-icon.png";
Expand Down Expand Up @@ -47,12 +50,35 @@ const SuggestionsList = styled.ul`
const SuggestionItem = styled.li`
padding: 10px;
cursor: pointer;
background-color: #f9f9f9;
color: #333;
&:hover {
background-color: #f0f0f0;
}
`;

const ButtonGeoLocation = styled.button`
padding: 10px;
border: none;
border-radius: 4px;
background-color: #333;
color: white;
cursor: pointer;
margin-bottom: 10px;
&:hover {
background-color: #555;
}
`;

const MapWrapper = styled.div`
height: 80vh;
width: 100%;
margin: 0 auto;
position: relative;
`;

const RecenterAutomatically = ({ lat, lng }: { lat: number; lng: number }) => {
const map = useMap();
useEffect(() => {
Expand All @@ -61,7 +87,13 @@ const RecenterAutomatically = ({ lat, lng }: { lat: number; lng: number }) => {
return null;
};

const AutoFetchGeolocation: React.FC = () => {
interface AutoFetchGeolocationProps {
onAddressClick: (address: string) => void;
}

const AutoFetchGeolocation: React.FC<AutoFetchGeolocationProps> = ({
onAddressClick,
}) => {
const [location, setLocation] = useState<{
latitude: number;
longitude: number;
Expand All @@ -72,7 +104,7 @@ const AutoFetchGeolocation: React.FC = () => {
longitude: number;
} | null>(null);
const [address, setAddress] = useState("");
const [suggestions, setSuggestions] = useState([]);
const [suggestions, setSuggestions] = useState<SearchResultItem[]>([]);
const [debounceTimeout, setDebounceTimeout] = useState<number | undefined>(
undefined
);
Expand All @@ -82,14 +114,14 @@ const AutoFetchGeolocation: React.FC = () => {
const getLocation = () => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
(position) => {
async (position) => {
const coords = {
latitude: position.coords.latitude,
longitude: position.coords.longitude,
};
setLocation(coords);
setChosenLocation(coords); // Set initial chosen location to current location
fetchAddress(coords.latitude, coords.longitude);
await fetchAddress(coords.latitude, coords.longitude);
},
(error) => {
setError(error.message);
Expand All @@ -105,11 +137,12 @@ const AutoFetchGeolocation: React.FC = () => {

const fetchAddress = async (lat: number, lng: number) => {
try {
const response = await fetch(
`https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lng}`
);
const data = await response.json();
setAddress(data.display_name);
const client = nominatim.createClient({
useragent: "MyApp", // The name of your application
referer: "http://example.com", // The referer link
});
const result = await client.reverse({ lat, lon: lng });
setAddress(result.display_name);
} catch (error) {
setError("Error fetching address");
}
Expand All @@ -131,10 +164,11 @@ const AutoFetchGeolocation: React.FC = () => {

const fetchSuggestions = async (query: string) => {
try {
const response = await fetch(
`https://nominatim.openstreetmap.org/search?format=json&q=${query}`
);
const data = await response.json();
const client = nominatim.createClient({
useragent: "react-app",
referer: "http://localhost",
});
const data = await client.search({ q: query, addressdetails: 1 });
setSuggestions(data);
} catch (error) {
setError("Error fetching address suggestions");
Expand All @@ -159,7 +193,7 @@ const AutoFetchGeolocation: React.FC = () => {
}
};

const handleSuggestionClick = (suggestion: any) => {
const handleSuggestionClick = (suggestion: SearchResultItem) => {
setAddress(suggestion.display_name);
const newChosenLocation = {
latitude: parseFloat(suggestion.lat),
Expand All @@ -173,6 +207,8 @@ const AutoFetchGeolocation: React.FC = () => {
13
);
}
// Call the onAddressClick callback with the selected address
onAddressClick(suggestion.display_name);
};

const centerMap = () => {
Expand All @@ -183,34 +219,32 @@ const AutoFetchGeolocation: React.FC = () => {
}
};

const handleGeolocationClick = () => {
// Trigger geolocation
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
async (position) => {
const coords = {
latitude: position.coords.latitude,
longitude: position.coords.longitude,
};
setLocation(coords);
setChosenLocation(coords); // Set chosen location to current
location;
await fetchAddress(coords.latitude, coords.longitude);
},
(error) => {
setError(error.message);
}
);
} else {
setError("Geolocation is not supported by this browser.");
}
};

return (
<Container>
<Title>Your Location</Title>
<div
style={{
marginBottom: "20px",
}}
>
<SearchInput
type="text"
value={address}
onChange={handleAddressChange}
placeholder="Enter address"
/>
{suggestions.length > 0 && (
<SuggestionsList>
{suggestions.map((suggestion: any) => (
<SuggestionItem
key={suggestion.place_id}
onClick={() => handleSuggestionClick(suggestion)}
>
{suggestion.display_name}
</SuggestionItem>
))}
</SuggestionsList>
)}
</div>
{location ? (
<MapWrapper>
<MapContainer
fadeAnimation={true}
ref={mapRef}
Expand All @@ -221,37 +255,123 @@ const AutoFetchGeolocation: React.FC = () => {
zoomAnimation={true}
zoom={18}
scrollWheelZoom={true}
style={{ height: "70vh", width: "70vw", margin: "0 auto" }}
style={{ height: "100%", width: "100%" }}
>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
/>
<Marker
position={[
chosenLocation?.latitude ?? location.latitude,
chosenLocation?.longitude ?? location.longitude,
chosenLocation?.latitude ?? location?.latitude ?? 0,
chosenLocation?.longitude ?? location?.longitude ?? 0,
]}
eventHandlers={{
dragend: handleMarkerDragEnd,
}}
draggable={true}
>
<Popup>
Delivery Location: <br />
Latitude: {chosenLocation?.latitude ?? location.latitude}
Location de livraison: <br />
Latitude: {chosenLocation?.latitude ?? location?.latitude ?? ""}
<br />
Longitude: {chosenLocation?.longitude ?? location.longitude}
Longitude:{" "}
{chosenLocation?.longitude ?? location?.longitude ?? ""}
</Popup>
</Marker>
<RecenterAutomatically
lat={chosenLocation?.latitude ?? location?.latitude ?? 0}
lng={chosenLocation?.longitude ?? location?.longitude ?? 0}
/>
</MapContainer>
) : (
<p>Error: {error}</p>
)}
<Container
style={{
zIndex: 1000,
}}
>
<div
style={{
position: "absolute",
top: "5%",
left: "5%",
margin: "20px",
backgroundColor: "#333",
padding: "10px",
borderRadius: "10px",
width: "420px",
zIndex: 1000,
}}
>
<Title
style={{
marginBottom: "20px",
color: "white",
}}
>
Choisissez une adresse de livraison
</Title>
<div style={{}}>
<SearchInput
type="text"
value={address}
onChange={handleAddressChange}
placeholder="Enter address"
/>
<button
style={{
padding: "10px",
border: "none",
borderRadius: "4px",
cursor: "pointer",
margin: "10px",
backgroundColor: "#333",
color: "white",
}}
onClick={() => onAddressClick(address)}
>
Valider l'adresse
</button>
</div>
{suggestions.length > 0 && (
<SuggestionsList>
{suggestions.map((suggestion: SearchResultItem) => (
<SuggestionItem
key={suggestion.place_id}
onClick={() => handleSuggestionClick(suggestion)}
>
{suggestion.display_name}
</SuggestionItem>
))}
</SuggestionsList>
)}
</div>
</Container>
</MapWrapper>
<Container
style={{
position: "absolute",
bottom: "5%",
right: "1%",
transform: "translate(-50%, -50%)",
zIndex: 1000,
display: "flex",
flexDirection: "column",
gap: "10px",
width: "100px",
}}
>
<ButtonGeoLocation onClick={handleGeolocationClick}>
<FontAwesomeIcon icon={faLocationArrow} />
</ButtonGeoLocation>

<ButtonGeoLocation
onClick={() => {
onAddressClick(address);
}}
>
Valider l'adresse
</ButtonGeoLocation>
</Container>
</Container>
);
};
Expand Down
Loading

0 comments on commit a271888

Please sign in to comment.