Skip to content

Commit

Permalink
Merge branch 'develop/fe' into feature/fe/#448
Browse files Browse the repository at this point in the history
  • Loading branch information
jinyoung234 authored Sep 26, 2024
2 parents b3e8a39 + dedf12d commit 23b29a6
Show file tree
Hide file tree
Showing 12 changed files with 152 additions and 63 deletions.
2 changes: 1 addition & 1 deletion frontend/cypress/e2e/travelPlanRegister.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ describe("여행 계획 등록 테스트", () => {

// when
cy.get(CYPRESS_SELECTOR_MAP.googleSearchPopup.searchInput).type(INPUT_VALUE);
cy.get(".pac-item").first().click();
cy.get(".pac-item").first().click({ force: true });

// then
cy.get(CYPRESS_SELECTOR_MAP.googleSearchPopup.container).should("not.exist");
Expand Down
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"lint:styled": "stylelint './src/**/*.styled.ts' --fix",
"test": "jest --passWithNoTests",
"test-e2e": "cypress open",
"test-e2e:run": "cypress run",
"test-e2e:run": "cypress run --browser chrome",
"storybook": "storybook dev -p 6006",
"lint": "eslint src/",
"build-storybook": "storybook build"
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/common/Calendar/Calendar.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ export const DayCell = styled.td<{ $isCurrentMonth: boolean; $isSelectable: bool
}
`};
color: ${({ theme, $isCurrentMonth }) =>
$isCurrentMonth ? theme.colors.text.secondary : PRIMITIVE_COLORS.gray[300]};
color: ${({ theme, $isCurrentMonth, $isSelectable }) =>
$isCurrentMonth && $isSelectable ? theme.colors.text.secondary : PRIMITIVE_COLORS.gray[300]};
text-align: center;
`;

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/common/Calendar/Calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const Calendar = ({
onClick={() => isSelectable && onSelectDate(date)}
data-cy={CYPRESS_DATA_MAP.calendar.dayCell}
>
<Text textType="detail">{date.getDate()}</Text>
<Text textType="detail">{isCurrentMonth ? date.getDate() : ""}</Text>
</S.DayCell>
);
})}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export const GOOGLE_MAP_CONTAINER_STYLE = {
width: "100%",
height: "23rem",
};

export const INIT_CENTER_POSITION = {
lat: 37.5665,
lng: 126.978,
};

export const GOOGLE_MAP_OPTIONS = {
disableDefaultUI: true,
styles: [
{
featureType: "poi",
elementType: "labels",
stylers: [{ visibility: "off" }],
},
],
};

export const POLYLINE_OPTIONS = { strokeColor: "#72A2FFCC", strokeWeight: 3 };
87 changes: 31 additions & 56 deletions frontend/src/components/common/GoogleMapView/GoogleMapView.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { useCallback } from "react";
import { memo } from "react";

import { GoogleMap, MarkerF, Polyline } from "@react-google-maps/api";

import theme from "@styles/theme";
import {
GOOGLE_MAP_CONTAINER_STYLE,
GOOGLE_MAP_OPTIONS,
POLYLINE_OPTIONS,
} from "@components/common/GoogleMapView/GoogleMapView.constant";
import {
calculateCenter,
createMarkerLabelStyle,
} from "@components/common/GoogleMapView/GoogleMapView.util";

import { markerUrl } from "@assets/svg";
import useGoogleMap from "@hooks/useGoogleMap";

const containerStyle = {
width: "100%",
height: "23rem",
};
import { markerUrl } from "@assets/svg";

interface GoogleMapViewProps {
places: {
Expand All @@ -19,72 +23,43 @@ interface GoogleMapViewProps {
}[];
}

const calculateCenter = (places: { lat: number; lng: number }[]): { lat: number; lng: number } => {
const latSum = places.reduce((sum, place) => sum + place.lat, 0);
const lngSum = places.reduce((sum, place) => sum + place.lng, 0);
const count = places.length;

return {
lat: latSum / count,
lng: lngSum / count,
};
};

const GoogleMapView = ({ places }: GoogleMapViewProps) => {
const center = calculateCenter(places);

const onLoad = useCallback(
(map: google.maps.Map) => {
const bounds = new window.google.maps.LatLngBounds();
places.forEach((place) => {
bounds.extend(new window.google.maps.LatLng(place.lat, place.lng));
});
map.fitBounds(bounds);
},
[places],
);
const { onLoad, onUnmount, onBoundsChanged } = useGoogleMap(places);

/**
* 컴포넌트 내부에 위치시키지 않으면 "Uncaught TypeError: Cannot read properties of undefined (reading 'maps')"
* 에러가 발생하여 다음과 같은 위치로 변경
*/
const MARKER_ICON_STYLE = {
url: markerUrl,
scaledSize: new window.google.maps.Size(30, 30),
labelOrigin: new window.google.maps.Point(15, -10),
};

return (
<div>
<GoogleMap
options={{
disableDefaultUI: true,
styles: [
{
featureType: "poi",
elementType: "labels",
stylers: [{ visibility: "off" }],
},
],
}}
mapContainerStyle={containerStyle}
options={GOOGLE_MAP_OPTIONS}
mapContainerStyle={GOOGLE_MAP_CONTAINER_STYLE}
center={center}
zoom={10}
onLoad={onLoad}
onUnmount={onUnmount}
onBoundsChanged={onBoundsChanged}
>
{places.map((position, index) => (
<MarkerF key={`${index}-${position.lat}`} position={position} icon={markerUrl} />
))}
{places.map((position, index) => (
<MarkerF
key={`marker-${index}-${position.lat}-${position.lng}`}
position={position}
icon={{
url: markerUrl,
scaledSize: new window.google.maps.Size(30, 30),
labelOrigin: new window.google.maps.Point(15, -10),
}}
label={{
text: `${index + 1}`,
color: theme.colors.primary,
fontSize: "1.4rem",
}}
icon={MARKER_ICON_STYLE}
label={createMarkerLabelStyle(index)}
/>
))}
<Polyline path={places} options={{ strokeColor: "#72A2FFCC", strokeWeight: 3 }} />
<Polyline path={places} options={POLYLINE_OPTIONS} />
</GoogleMap>
</div>
);
};

export default React.memo(GoogleMapView);
export default memo(GoogleMapView);
27 changes: 27 additions & 0 deletions frontend/src/components/common/GoogleMapView/GoogleMapView.util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { INIT_CENTER_POSITION } from "@components/common/GoogleMapView/GoogleMapView.constant";

import theme from "@styles/theme";

export const calculateCenter = (
places: { lat: number; lng: number }[],
): { lat: number; lng: number } => {
if (places.length === 0) {
return { lat: INIT_CENTER_POSITION.lat, lng: INIT_CENTER_POSITION.lng };
}
const latSum = places.reduce((sum, place) => sum + place.lat, 0);
const lngSum = places.reduce((sum, place) => sum + place.lng, 0);
const count = places.length;

return {
lat: latSum / count,
lng: lngSum / count,
};
};

export const createMarkerLabelStyle = (markerOrder: number) => {
return {
text: `${markerOrder + 1}`,
color: theme.colors.primary,
fontSize: "1.4rem",
};
};
1 change: 1 addition & 0 deletions frontend/src/components/common/Input/Input.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const Input = styled.input<{ variant: InputVariants }>`
${({ theme }) => theme.typography.mobile.detail}
color: ${({ theme }) => theme.colors.text.primary};
font-size: 1.6rem;
&:disabled {
background-color: ${({ theme }) => theme.colors.background.disabled};
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/hooks/pages/useTravelPlanDays.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ export const useTravelPlanDays = (days: TravelTransformPlaces[]) => {
const travelPlanPlace = previousTravelPlanDays[dayIndex]?.places[placeIndex];

if (travelPlanPlace?.todos) {
travelPlanPlace.todos.splice(Number(todoId), 1);
travelPlanPlace.todos = travelPlanPlace.todos.filter((todo) => todo.id !== todoId);
}
});
},
Expand Down
43 changes: 43 additions & 0 deletions frontend/src/hooks/useGoogleMap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { useCallback, useState } from "react";

import { MapPosition } from "@type/domain/common";

const INIT_CENTER_POSITION = {
lat: 37.5665,
lng: 126.978,
};

const useGoogleMap = (places: MapPosition[]) => {
const [googleMap, setGoogleMap] = useState<google.maps.Map | null>(null);

const onLoad = useCallback((map: google.maps.Map) => {
setGoogleMap(map);
}, []);

const onUnmount = useCallback(() => {
setGoogleMap(null);
}, []);

const onBoundsChanged = useCallback(() => {
if (googleMap) {
if (places.length === 0) {
googleMap.setCenter(INIT_CENTER_POSITION);
googleMap.setZoom(7);
} else {
const bounds = new window.google.maps.LatLngBounds();
places.forEach((place) => {
bounds.extend(new window.google.maps.LatLng(place.lat, place.lng));
});
googleMap.fitBounds(bounds);
}
}
}, [places, googleMap]);

return {
onLoad,
onUnmount,
onBoundsChanged,
};
};

export default useGoogleMap;
12 changes: 11 additions & 1 deletion frontend/webpack.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,18 @@ module.exports = {
use: ["@svgr/webpack"],
},
{
test: /\.(png|jpg|jpeg|gif|woff|webp)$/i,
test: /\.(png|jpg|jpeg|gif|webp|avif)$/i,
type: "asset/resource",
generator: {
filename: "assets/images/[name].[contenthash:8][ext]",
},
},
{
test: /\.(woff)$/i,
type: "asset/resource",
generator: {
filename: "assets/fonts/[name].[contenthash:8][ext]",
},
},
{
test: /\.(ts|tsx)$/i,
Expand Down
11 changes: 11 additions & 0 deletions frontend/webpack.production.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@ const common = require("./webpack.common");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const dotenv = require("dotenv");
// const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
const path = require("path");

const env = dotenv.config({ path: ".env.production" }).parsed;

module.exports = merge(common, {
mode: "production",
output: {
publicPath: "/",
filename: "[name].[contenthash:8].js",
path: path.resolve(__dirname, "dist"),
},
devtool: "hidden-source-map",
cache: {
type: "filesystem",
Expand All @@ -31,4 +37,9 @@ module.exports = merge(common, {
// openAnalyzer: true,
// }),
],
optimization: {
splitChunks: {
chunks: "all",
},
},
});

0 comments on commit 23b29a6

Please sign in to comment.