Skip to content

[UNI-119] 길찾기 결과 바텀 시트 아래로 내릴 시 스크롤 끝까지 안되는 현상 #51

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 5, 2025

Conversation

jpark0506
Copy link
Contributor

@jpark0506 jpark0506 commented Feb 5, 2025

#️⃣ 작업 내용

  1. 길찾기 결과 바텀 시트 아래로 내릴 시 스크롤 끝까지 안되는 현상

해결 방식

  • 기존에는 position을 이동시켰지만, height로 이동시키는 방식으로 바꿨습니다.

AS IS

2025-02-05.16.33.02.mov

TO BE

2025-02-05.16.31.35.mov

Summary by CodeRabbit

  • New Features

    • Launched a rebranded admin interface with an improved navigation bar for selecting universities.
    • Introduced interactive pages for reporting routes and hazards, including dedicated error and offline screens.
    • Added dynamic log displays and intuitive map interactions for a more engaging user experience.
  • Improvements

    • Enhanced overall UI responsiveness with smooth animations and updated layouts.
    • Integrated real‑time loading overlays and status updates to improve feedback during user interactions.

@jpark0506 jpark0506 added 🔧 fix 수정사항 및 버그관련 등 🧇 fe 프론트엔드 task labels Feb 5, 2025
@jpark0506 jpark0506 requested a review from dgfh0450 February 5, 2025 07:34
@jpark0506 jpark0506 self-assigned this Feb 5, 2025
@jpark0506 jpark0506 changed the base branch from main to fe February 5, 2025 07:34
@softeer5th softeer5th deleted a comment from coderabbitai bot Feb 5, 2025
Copy link
Contributor

@dgfh0450 dgfh0450 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다!

훨씬 자연스러운 바텀시트가 완성이 되고 있네요!

Comment on lines +109 to +141
<AnimatedSheetContainer
isVisible={isDetailView && !isLoading}
className="absolute bottom-0 w-full left-0 bg-white rounded-t-2xl shadow-xl overflow-auto"
positionDelta={MAX_SHEET_HEIGHT}
transition={{ type: "spring", damping: 20, duration: 0.3 }}
height={sheetHeight}
className="bg-white rounded-t-2xl shadow-xl"
transition={{ type: "tween", duration: 0.3 }}
motionProps={{
drag: "y",
dragControls,
dragListener: false,
dragConstraints: {
top: 0,
bottom: MIN_SHEET_HEIGHT,
bottom: 0,
},
onDrag: handleDrag,
onDragEnd: handleDrag,
}}
>
<BottomSheetHandle dragControls={dragControls} />

<div
className="w-full overflow-y-auto"
style={{
height: MAX_SHEET_HEIGHT - BOTTOM_SHEET_HANDLE_HEIGHT,
height: sheetHeight - BOTTOM_SHEET_HANDLE_HEIGHT,
}}
>
<NavigationDescription isDetailView={isDetailView && !isLoading} />
<NavigationDescription isDetailView={true} />
<RouteList
routes={route.route}
originBuilding={route.originBuilding}
destinationBuilding={route.destinationBuilding}
/>
</div>
</AnimatedContainer>
</AnimatedSheetContainer>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!
애니메이션의 달인이 되었네요!
바텀시트 완성이 된다면 지도 페이지에도 적용해보겠습니다!

@dgfh0450 dgfh0450 merged commit c8eda44 into fe Feb 5, 2025
1 check was pending
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments.

🛑 Comments failed to post (33)
uniro_admin_frontend/src/components/log/logList.tsx (1)

8-10: ⚠️ Potential issue

Add key prop to mapped elements.

React requires a unique key prop for elements in an iteration to maintain component state and optimize rendering.

-      {logCardData.map((log) => {
-        return <LogCard date={log.date} change={log.change} />;
+      {logCardData.map((log, index) => {
+        return <LogCard key={`log-${index}`} date={log.date} change={log.change} />;
       })}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

      {logCardData.map((log, index) => {
        return <LogCard key={`log-${index}`} date={log.date} change={log.change} />;
      })}
🧰 Tools
🪛 Biome (1.9.4)

[error] 9-9: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

uniro_admin_frontend/Dockerfile (2)

1-1: ⚠️ Potential issue

Use a more stable Node.js version.

node:22-slim is a very new and potentially unstable version. Consider using an LTS version like node:20-slim.

-FROM node:22-slim AS build
+FROM node:20-slim AS build
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

FROM node:20-slim AS build

6-6: ⚠️ Potential issue

Avoid using --legacy-peer-deps flag.

The --legacy-peer-deps flag can lead to dependency conflicts. Consider resolving peer dependencies properly or using npm install --strict-peer-deps instead.

-RUN npm install --legacy-peer-deps --no-audit && npm run build
+RUN npm install --strict-peer-deps --no-audit && npm run build
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

RUN npm install --strict-peer-deps --no-audit && npm run build
.github/workflows/fe-admin-deploy.yml (2)

62-62: ⚠️ Potential issue

Use safer Docker cleanup command.

The current Docker cleanup command might remove containers from other services. Use a more targeted approach.

-            sudo docker rm $(sudo docker ps -a -q) || true
+            sudo docker ps -a --format '{{.ID}} {{.Names}}' \
+                | egrep -v 'nginx-container|uniro-fe' \
+                | awk '{print $1}' \
+                | xargs -r sudo docker rm || true
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

            sudo docker ps -a --format '{{.ID}} {{.Names}}' \
                | egrep -v 'nginx-container|uniro-fe' \
                | awk '{print $1}' \
                | xargs -r sudo docker rm || true

22-24: ⚠️ Potential issue

Pin action version to SHA for security.

Using version tags like v2 can be insecure. Pin to specific SHA for better security.

-        uses: "google-github-actions/auth@v2"
+        uses: "google-github-actions/auth@ef5d53e30bbcd8d0836f4288f5e50ff3e086997d"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

        uses: "google-github-actions/auth@ef5d53e30bbcd8d0836f4288f5e50ff3e086997d"
        with:
          credentials_json: ${{ secrets.GCP_SA_KEY }}
uniro_frontend/src/pages/error.tsx (1)

1-1: ⚠️ Potential issue

Rename imported component to avoid shadowing global Error.

The current import shadows the global Error property. Consider renaming the import to be more specific.

-import Error from "../components/error/Error";
+import ErrorComponent from "../components/error/Error";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

import ErrorComponent from "../components/error/Error";
🧰 Tools
🪛 Biome (1.9.4)

[error] 1-1: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

uniro_frontend/src/hooks/useRedirectUndefined.tsx (1)

11-11: ⚠️ Potential issue

Fix dependency array spread in useEffect.

The spread operator in the dependency array is unnecessary and could cause performance issues. React's exhaustive-deps rule expects direct references.

-	}, [...deps]);
+	}, [deps, navigate, url]);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

	}, [deps, navigate, url]);
uniro_frontend/src/components/error/Error.tsx (1)

3-15: ⚠️ Potential issue

Rename component to avoid shadowing global Error property.

The component implementation looks good, but it shadows the global Error property. Consider renaming it to something more specific like ErrorMessage or ErrorDisplay.

Apply this diff to fix the shadowing issue:

-export default function Error() {
+export default function ErrorMessage() {
   return (
     <div className="w-[285px] h-[198px] flex flex-col items-center py-2 space-y-[14px]">
       <ErrorIcon />
       <div className="space-y-[6px]">
         <h3 className="text-kor-heading2 font-semibold text-gray-900">
           일시적인 오류로 <br /> 데이터를 불러올 수 없습니다.
         </h3>
         <p className="text-kor-body2 font-medium text-gray-700">잠시 후 다시 시도해 주세요.</p>
       </div>
     </div>
   );
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

export default function ErrorMessage() {
	return (
		<div className="w-[285px] h-[198px] flex flex-col items-center py-2 space-y-[14px]">
			<ErrorIcon />
			<div className="space-y-[6px]">
				<h3 className="text-kor-heading2 font-semibold text-gray-900">
					일시적인 오류로 <br /> 데이터를 불러올 수 없습니다.
				</h3>
				<p className="text-kor-body2 font-medium text-gray-700">잠시 후 다시 시도해 주세요.</p>
			</div>
		</div>
	);
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 3-3: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

uniro_admin_frontend/src/map/loader/googleMapLoader.ts (1)

9-14: 🛠️ Refactor suggestion

Avoid shadowing the global Map object.

The destructured Map variable shadows the global Map object, which could lead to confusion. Consider renaming it to be more specific.

 const loadGoogleMapsLibraries = async () => {
-  const { Map, OverlayView, Polyline } = await GoogleMapsLoader.importLibrary("maps");
+  const { Map: GoogleMap, OverlayView, Polyline } = await GoogleMapsLoader.importLibrary("maps");
   const { AdvancedMarkerElement } = await GoogleMapsLoader.importLibrary("marker");

-  return { Map, OverlayView, AdvancedMarkerElement, Polyline };
+  return { GoogleMap, OverlayView, AdvancedMarkerElement, Polyline };
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

const loadGoogleMapsLibraries = async () => {
	const { Map: GoogleMap, OverlayView, Polyline } = await GoogleMapsLoader.importLibrary("maps");
	const { AdvancedMarkerElement } = await GoogleMapsLoader.importLibrary("marker");

	return { GoogleMap, OverlayView, AdvancedMarkerElement, Polyline };
};
🧰 Tools
🪛 Biome (1.9.4)

[error] 10-10: Do not shadow the global "Map" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

uniro_admin_frontend/src/container/mapContainer.tsx (1)

10-10: 🛠️ Refactor suggestion

Replace hardcoded date/time with dynamic value.

The current implementation uses a static date/time string. Consider using a dynamic value that updates in real-time.

-        <div className="text-kor-heading2">2025년 2월 3일 15:34</div>
+        <div className="text-kor-heading2">
+          {new Date().toLocaleString('ko-KR', {
+            year: 'numeric',
+            month: 'long',
+            day: 'numeric',
+            hour: '2-digit',
+            minute: '2-digit',
+            hour12: false
+          })}
+        </div>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

        <div className="text-kor-heading2">
          {new Date().toLocaleString('ko-KR', {
            year: 'numeric',
            month: 'long',
            day: 'numeric',
            hour: '2-digit',
            minute: '2-digit',
            hour12: false
          })}
        </div>
uniro_frontend/src/hooks/useNetworkStatus.tsx (1)

18-26: ⚠️ Potential issue

Add dependency array to useEffect to prevent unnecessary re-renders

The useEffect hook is missing its dependency array, which could cause unnecessary re-renders and event listener re-attachments.

-	});
+	}, [navigate]);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

	useEffect(() => {
		window.addEventListener("offline", handleOffline);
		window.addEventListener("online", handleOnline);

		return () => {
			window.removeEventListener("offline", handleOffline);
			window.removeEventListener("online", handleOnline);
		};
	}, [navigate]);
uniro_frontend/src/utils/fetch/mockFetch.ts (1)

11-12: 🛠️ Refactor suggestion

Remove console logs from production code

Console logs should be removed or wrapped in a development-only condition.

+	const isDev = process.env.NODE_ENV === 'development';
+
 	return new Promise((resolve, reject) => {
-		console.log(`${delay / 1000}초 동안 로딩 중...`);
+		isDev && console.log(`${delay / 1000}초 동안 로딩 중...`);
 		setTimeout(() => {
 			if (shouldFail) {
-				console.error("네트워크 오류 발생!");
+				isDev && console.error("네트워크 오류 발생!");
 				reject(new Error("네트워크 오류 발생"));
 			} else {
-				console.log("데이터 로드 완료:", data);
+				isDev && console.log("데이터 로드 완료:", data);
 				resolve(data);
 			}
 		}, delay);

Also applies to: 18-19

uniro_admin_frontend/src/component/Map.tsx (1)

8-8: 🛠️ Refactor suggestion

Rename component to avoid shadowing global Map object.

The component name shadows the global Map object. Consider using a more specific name.

-const Map = ({ style }: MapProps) => {
+const MapComponent = ({ style }: MapProps) => {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

const MapComponent = ({ style }: MapProps) => {
🧰 Tools
🪛 Biome (1.9.4)

[error] 8-8: Do not shadow the global "Map" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

uniro_frontend/src/components/map/reportModal.tsx (3)

14-20: ⚠️ Potential issue

Prevent modal close when clicking links.

The modal currently closes when clicking anywhere including the links due to event bubbling.

 <Link
   to={"/report/route"}
   className="w-full h-[58px] flex items-center justify-between px-5 bg-gray-100 rounded-400 text-kor-body2 font-semibold text-primary-500"
+  onClick={(e) => e.stopPropagation()}
 >

Also applies to: 22-28


1-1: ⚠️ Potential issue

Fix the import statement for React Router.

The import statement for React Router appears incorrect. It should be react-router-dom instead of react-router.

-import { Link } from "react-router";
+import { Link } from "react-router-dom";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

import { Link } from "react-router-dom";

10-13: 🛠️ Refactor suggestion

Add accessibility attributes to the modal overlay.

The modal overlay should have proper ARIA attributes and keyboard handling for accessibility.

 <div
   className="fixed inset-0 flex flex-col items-center justify-end bg-[rgba(0,0,0,0.2)] z-20 py-6 px-4 space-y-[10px]"
   onClick={close}
+  role="dialog"
+  aria-modal="true"
+  onKeyDown={(e) => e.key === 'Escape' && close()}
+  tabIndex={-1}
 >
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

		<div
			className="fixed inset-0 flex flex-col items-center justify-end bg-[rgba(0,0,0,0.2)] z-20 py-6 px-4 space-y-[10px]"
			onClick={close}
			role="dialog"
			aria-modal="true"
			onKeyDown={(e) => e.key === 'Escape' && close()}
			tabIndex={-1}
		>
uniro_frontend/src/utils/polylines/createSubnodes.ts (1)

6-32: 🛠️ Refactor suggestion

Add edge case handling and improve mathematical accuracy.

The current implementation has several potential improvements:

  1. No validation for empty paths or invalid input
  2. Linear interpolation might not be accurate for long distances on Earth's surface
  3. No handling for the case when length is 0
 export default function createSubNodes(polyLine: google.maps.Polyline): google.maps.LatLngLiteral[] {
   const paths = polyLine.getPath();
+  if (paths.getLength() < 2) {
+    throw new Error('Polyline must have at least 2 points');
+  }
   const [startNode, endNode] = paths.getArray().map((el) => LatLngToLiteral(el));
 
   const length = distance(startNode, endNode);
+  if (length === 0) {
+    return [startNode];
+  }
 
   const subEdgesCount = Math.ceil(length / EDGE_LENGTH);
 
   const interval = {
     lat: (endNode.lat - startNode.lat) / subEdgesCount,
     lng: (endNode.lng - startNode.lng) / subEdgesCount,
   };
 
   const subNodes = [];
 
   for (let i = 0; i < subEdgesCount; i++) {
     const subNode: google.maps.LatLngLiteral = {
       lat: startNode.lat + interval.lat * i,
       lng: startNode.lng + interval.lng * i,
     };
     subNodes.push(subNode);
   }
 
   subNodes.push(endNode);
 
   return subNodes;
 }

Consider using spherical interpolation for better accuracy over long distances:

function sphericalInterpolate(start: google.maps.LatLngLiteral, end: google.maps.LatLngLiteral, fraction: number): google.maps.LatLngLiteral {
  const d = distance(start, end);
  const a = Math.sin((1 - fraction) * d) / Math.sin(d);
  const b = Math.sin(fraction * d) / Math.sin(d);
  return {
    lat: a * start.lat + b * end.lat,
    lng: a * start.lng + b * end.lng
  };
}
uniro_frontend/src/utils/polylines/findNearestEdge.ts (1)

4-32: 🛠️ Refactor suggestion

Add input validation and optimize performance.

The current implementation has several areas for improvement:

  1. No validation for empty edges array
  2. Unnecessary sorting of all edges when only the nearest is needed
  3. Type assertions could be replaced with proper typing
 export default function findNearestSubEdge(
   edges: [google.maps.LatLngLiteral, google.maps.LatLngLiteral][],
   point: google.maps.LatLngLiteral,
 ): {
   edge: [google.maps.LatLngLiteral, google.maps.LatLngLiteral];
   point: google.maps.LatLngLiteral;
 } {
+  if (edges.length === 0) {
+    throw new Error('Edges array cannot be empty');
+  }
+
+  let nearestEdge: [google.maps.LatLngLiteral, google.maps.LatLngLiteral] | null = null;
+  let minDistance = Infinity;
+
+  for (const [startNode, endNode] of edges) {
+    const center = centerCoordinate(startNode, endNode);
+    const dist = distance(point, center);
+    if (dist < minDistance) {
+      minDistance = dist;
+      nearestEdge = [startNode, endNode];
+    }
+  }
+
+  if (!nearestEdge) {
+    throw new Error('Failed to find nearest edge');
+  }
 
-  const edgesWithDistance = edges
-    .map(([startNode, endNode]) => {
-      return {
-        edge: [startNode, endNode] as [google.maps.LatLngLiteral, google.maps.LatLngLiteral],
-        distance: distance(point, centerCoordinate(startNode, endNode)),
-      };
-    })
-    .sort((a, b) => {
-      return a.distance - b.distance;
-    });
-
-  const nearestEdge = edgesWithDistance[0].edge;
-
   const distance0 = distance(nearestEdge[0], point);
   const distance1 = distance(nearestEdge[1], point);
   const nearestPoint = distance0 > distance1 ? nearestEdge[1] : nearestEdge[0];
 
   return {
     edge: nearestEdge,
     point: nearestPoint,
   };
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

export default function findNearestSubEdge(
	edges: [google.maps.LatLngLiteral, google.maps.LatLngLiteral][],
	point: google.maps.LatLngLiteral,
): {
	edge: [google.maps.LatLngLiteral, google.maps.LatLngLiteral];
	point: google.maps.LatLngLiteral;
} {
	if (edges.length === 0) {
		throw new Error('Edges array cannot be empty');
	}

	let nearestEdge: [google.maps.LatLngLiteral, google.maps.LatLngLiteral] | null = null;
	let minDistance = Infinity;

	for (const [startNode, endNode] of edges) {
		const center = centerCoordinate(startNode, endNode);
		const dist = distance(point, center);
		if (dist < minDistance) {
			minDistance = dist;
			nearestEdge = [startNode, endNode];
		}
	}

	if (!nearestEdge) {
		throw new Error('Failed to find nearest edge');
	}

	const distance0 = distance(nearestEdge[0], point);
	const distance1 = distance(nearestEdge[1], point);
	const nearestPoint = distance0 > distance1 ? nearestEdge[1] : nearestEdge[0];

	return {
		edge: nearestEdge,
		point: nearestPoint,
	};
}
uniro_frontend/src/map/initializer/googleMapInitializer.ts (1)

16-16: ⚠️ Potential issue

Avoid shadowing the global Map object.

The destructured variable name shadows the global Map object, which could lead to confusion.

-	const { Map, OverlayView, AdvancedMarkerElement, Polyline } = await loadGoogleMapsLibraries();
+	const { Map: GoogleMap, OverlayView, AdvancedMarkerElement, Polyline } = await loadGoogleMapsLibraries();

-	const map = new Map(mapElement, {
+	const map = new GoogleMap(mapElement, {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

	const { Map: GoogleMap, OverlayView, AdvancedMarkerElement, Polyline } = await loadGoogleMapsLibraries();

	// ... other code ...
	const map = new GoogleMap(mapElement, {
	  // map options
	});
🧰 Tools
🪛 Biome (1.9.4)

[error] 16-16: Do not shadow the global "Map" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

uniro_admin_frontend/src/hooks/useMap.tsx (2)

40-40: ⚠️ Potential issue

Add mapOptions to useEffect dependencies.

The useEffect hook should include mapOptions in its dependencies array to properly handle updates to map options.

-}, []);
+}, [mapOptions]);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

  }, [mapOptions]);

28-30: 🛠️ Refactor suggestion

Improve error handling.

Using alert for error handling is not ideal for production. Consider implementing a more robust error handling mechanism.

-alert("Error while initializing map: " + e);
+console.error("Map initialization failed:", e);
+// Consider using a proper error boundary or error state
+setMapLoaded(false);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

      } catch (e) {
        console.error("Map initialization failed:", e);
        // Consider using a proper error boundary or error state
        setMapLoaded(false);
      }
uniro_frontend/src/utils/fetch/fetch.ts (2)

20-31: 🛠️ Refactor suggestion

Add Content-Type header for POST/PUT requests.

The POST and PUT methods are sending JSON data but missing the Content-Type header. This could cause issues with the server interpreting the request body correctly.

Apply this diff to both POST and PUT methods:

 const post = async <T, K>(url: string, body?: Record<string, K>): Promise<T> => {
   const response = await fetch(`${baseURL}${url}`, {
     method: "POST",
     body: JSON.stringify(body),
+    headers: {
+      'Content-Type': 'application/json',
+    },
   });

Also applies to: 33-44


17-17: 🛠️ Refactor suggestion

Add error handling for JSON parsing.

The response.json() calls could fail if the response is not valid JSON. Consider adding try-catch blocks to handle parsing errors gracefully.

Apply this diff to all methods:

-    return response.json();
+    try {
+      return await response.json();
+    } catch (error) {
+      throw new Error(`Failed to parse JSON response: ${error.message}`);
+    }

Also applies to: 30-30, 43-43

uniro_frontend/src/pages/universitySearch.tsx (1)

6-6: ⚠️ Potential issue

Fix incorrect import path.

The import path for react-router should be react-router-dom for web applications.

Apply this diff:

-import { Link } from "react-router";
+import { Link } from "react-router-dom";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

import { Link } from "react-router-dom";
uniro_frontend/src/components/report/secondaryForm.tsx (1)

32-42: 🛠️ Refactor suggestion

Replace array index with unique identifier as key prop.

Using array indices as keys in map functions can lead to rendering issues when the array items are reordered or modified.

The button value itself can be used as the key since it's an enum value and therefore unique:

-key={index}
+key={button}

Also applies to: 44-54

uniro_frontend/src/pages/reportForm.tsx (2)

110-112: 🛠️ Refactor suggestion

Add loading state to prevent multiple submissions.

The submit button doesn't handle loading state, which could lead to multiple submissions.

Consider adding loading state:

+const [isSubmitting, setIsSubmitting] = useState(false);

+const handleSubmit = async () => {
+  if (isSubmitting) return;
+  setIsSubmitting(true);
+  try {
+    await onReportSubmitSuccess();
+  } catch (error) {
+    onReportSubmitFail();
+  } finally {
+    setIsSubmitting(false);
+  }
+};

-<Button onClick={onReportSubmitSuccess} variant={disabled ? "disabled" : "primary"}>
+<Button 
+  onClick={handleSubmit} 
+  variant={disabled || isSubmitting ? "disabled" : "primary"}
+>
-  제보하기
+  {isSubmitting ? "제보 중..." : "제보하기"}
 </Button>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

import React, { useState } from "react";
// ... other imports

const ReportForm = (props) => {
  // ... other state declarations

  const [isSubmitting, setIsSubmitting] = useState(false);

  const handleSubmit = async () => {
    if (isSubmitting) return;
    setIsSubmitting(true);
    try {
      await onReportSubmitSuccess();
    } catch (error) {
      onReportSubmitFail();
    } finally {
      setIsSubmitting(false);
    }
  };

  // ... other functions and JSX

  return (
    // ... other JSX elements
    <Button 
      onClick={handleSubmit} 
      variant={disabled || isSubmitting ? "disabled" : "primary"}
    >
      {isSubmitting ? "제보 중..." : "제보하기"}
    </Button>
    // ... other JSX elements
  );
};

export default ReportForm;

39-45: 🛠️ Refactor suggestion

Consider removing console.log statement and adding proper error handling.

The useEffect hook contains a console.log statement and uses setTimeout without cleanup.

Apply this diff to improve the implementation:

 useEffect(() => {
-  console.log(reportType, startNode, endNode);
+  let timeoutId: NodeJS.Timeout;
   
-  setTimeout(() => {
+  timeoutId = setTimeout(() => {
     setReportMode("update");
   }, 2000);
+
+  return () => clearTimeout(timeoutId);
 }, []);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

	useEffect(() => {
		let timeoutId: NodeJS.Timeout;

		timeoutId = setTimeout(() => {
			setReportMode("update");
		}, 2000);

		return () => clearTimeout(timeoutId);
	}, []);
uniro_frontend/src/pages/demo.tsx (3)

73-74: 🛠️ Refactor suggestion

Add proper click handlers for toggle buttons.

The toggle buttons have empty click handlers.

Consider implementing proper handlers:

-<DangerToggleButton onClick={() => {}} isActive={false} />
-<DangerToggleButton onClick={() => {}} isActive={true} />
+<DangerToggleButton onClick={() => setDangerActive(prev => !prev)} isActive={dangerActive} />
+<DangerToggleButton onClick={() => setDangerActive(prev => !prev)} isActive={dangerActive} />

-<CautionToggleButton onClick={() => {}} isActive={false} />
-<CautionToggleButton onClick={() => {}} isActive={true} />
+<CautionToggleButton onClick={() => setCautionActive(prev => !prev)} isActive={cautionActive} />
+<CautionToggleButton onClick={() => setCautionActive(prev => !prev)} isActive={cautionActive} />

Also applies to: 78-79


20-25: 🛠️ Refactor suggestion

Add error handling to API calls.

The getTest function lacks proper error handling and type safety.

Consider adding error handling and proper typing:

+interface GetTestResponse {
+  postId: string;
+}

-const getTest = () => {
+const getTest = async (): Promise<GetTestResponse> => {
+  try {
     /** https://jsonplaceholder.typicode.com/comments?postId=1 */
-    return getFetch<{ postId: string }>("/comments", {
+    return await getFetch<GetTestResponse>("/comments", {
       postId: 1,
     });
+  } catch (error) {
+    console.error('Failed to fetch test data:', error);
+    throw error;
+  }
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

interface GetTestResponse {
  postId: string;
}

const getTest = async (): Promise<GetTestResponse> => {
  try {
    /** https://jsonplaceholder.typicode.com/comments?postId=1 */
    return await getFetch<GetTestResponse>("/comments", {
      postId: 1,
    });
  } catch (error) {
    console.error('Failed to fetch test data:', error);
    throw error;
  }
};

17-18: ⚠️ Potential issue

Rename imported Error component to avoid global name conflict.

The imported Error component shadows the global Error object.

Apply this diff to fix the naming conflict:

-import Error from "../components/error/Error";
+import ErrorComponent from "../components/error/Error";

// Update usage
-<Error />
+<ErrorComponent />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

import Offline from "../components/error/Offline";
import ErrorComponent from "../components/error/Error";
🧰 Tools
🪛 Biome (1.9.4)

[error] 18-18: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

uniro_frontend/src/pages/reportHazard.tsx (1)

164-186: ⚠️ Potential issue

Add cleanup for map event listeners.

Event listeners are added but never cleaned up, which could lead to memory leaks.

Consider adding cleanup:

 useEffect(() => {
+  const listeners: google.maps.MapsEventListener[] = [];
   if (map) {
-    map.addListener("click", () => {
+    listeners.push(map.addListener("click", () => {
       setReportMarker((prevMarker) => {
         if (prevMarker) {
           setMessage(ReportHazardMessage.DEFAULT);
           resetMarker(prevMarker);
         } else setMessage(ReportHazardMessage.ERROR);

         return undefined;
       });
-    });
+    }));
   }
+  return () => {
+    listeners.forEach(listener => listener.remove());
+  };
 }, [map, AdvancedMarker, Polyline]);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

	useEffect(() => {
		drawRoute(mockNavigationRoute.route);
		addHazardMarker();

+  const listeners: google.maps.MapsEventListener[] = [];
		if (map) {
-		map.addListener("click", () => {
+		listeners.push(map.addListener("click", () => {
			setReportMarker((prevMarker) => {
				if (prevMarker) {
					setMessage(ReportHazardMessage.DEFAULT);
					resetMarker(prevMarker);
				} else setMessage(ReportHazardMessage.ERROR);

				return undefined;
			});
-		});
+		}));
		}
+  return () => {
+    listeners.forEach(listener => listener.remove());
+  };
	}, [map, AdvancedMarker, Polyline]);
uniro_frontend/src/pages/reportRoute.tsx (1)

221-256: ⚠️ Potential issue

Add cleanup for map resources and event listeners.

Map resources and event listeners should be properly cleaned up.

Consider adding cleanup:

 useEffect(() => {
+  const markers: google.maps.Marker[] = [];
+  const polylines: google.maps.Polyline[] = [];
+  const listeners: google.maps.MapsEventListener[] = [];

   drawRoute(mockNavigationRoute.route);
   addHazardMarker();
   if (Polyline) {
     newPolyLine.current = new Polyline({ map: map, path: [], strokeColor: "#0367FB" });
+    polylines.push(newPolyLine.current);
   }

   if (map && AdvancedMarker) {
-    map.addListener("click", (e: ClickEvent) => {
+    listeners.push(map.addListener("click", (e: ClickEvent) => {
       // ... existing click handler code
-    });
+    }));
   }

+  return () => {
+    markers.forEach(marker => marker.setMap(null));
+    polylines.forEach(polyline => polyline.setMap(null));
+    listeners.forEach(listener => listener.remove());
+  };
 }, [map]);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

	useEffect(() => {
	  const markers: google.maps.Marker[] = [];
	  const polylines: google.maps.Polyline[] = [];
	  const listeners: google.maps.MapsEventListener[] = [];

	  drawRoute(mockNavigationRoute.route);
	  addHazardMarker();
	  if (Polyline) {
	    newPolyLine.current = new Polyline({ map: map, path: [], strokeColor: "#0367FB" });
	    polylines.push(newPolyLine.current);
	  }

	  if (map && AdvancedMarker) {
	    listeners.push(map.addListener("click", (e: ClickEvent) => {
	      if (originPoint.current) {
	        const point = LatLngToLiteral(e.latLng);
	        setNewPoints((prevPoints) => {
	          if (prevPoints.element) {
	            prevPoints.element.position = point;
	            return {
	              ...prevPoints,
	              coords: [...prevPoints.coords, point],
	            };
	          } else {
	            setIsActive(true);
	            return {
	              element: new AdvancedMarker({
	                map: map,
	                position: point,
	                content: createMarkerElement({
	                  type: Markers.DESTINATION,
	                }),
	              }),
	              coords: [...prevPoints.coords, point],
	            };
	          }
	        });
	      }
	    }));
	  }

	  return () => {
	    markers.forEach(marker => marker.setMap(null));
	    polylines.forEach(polyline => polyline.setMap(null));
	    listeners.forEach(listener => listener.remove());
	  };
	}, [map]);
uniro_frontend/src/constant/enum/routeEnum.ts (1)

1-4: ⚠️ Potential issue

Remove const modifier from enum declaration.

The const enum can cause issues with bundlers and is incompatible with the 'isolatedModules' mode. This could lead to importing non-existent values.

Apply this diff to fix the issue:

-export const enum RoutePoint {
+export enum RoutePoint {
 	ORIGIN = "origin",
 	DESTINATION = "destination",
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

export enum RoutePoint {
	ORIGIN = "origin",
	DESTINATION = "destination",
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 1-4: The enum declaration should not be const

Const enums are not supported by bundlers and are incompatible with the 'isolatedModules' mode. Their use can lead to import inexistent values.
See TypeScript Docs for more details.
Safe fix: Turn the const enum into a regular enum.

(lint/suspicious/noConstEnum)

Copy link

coderabbitai bot commented Feb 5, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@jpark0506 jpark0506 deleted the feat/UNI-119 branch February 6, 2025 09:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🧇 fe 프론트엔드 task 🔧 fix 수정사항 및 버그관련 등
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants