Spring Boot 백엔드와 연동하는 이커머스 SPA. 상품 탐색, 장바구니, 주문, 공동구매 분석, 회원 관리 기능을 제공합니다.
| 검색 자동완성 | 빠르게 시작하기 |
|---|---|
![]() |
![]() |
| 키워드 입력 → 추천어 → 결과 목록 | 버튼 클릭 한 번으로 자동 로그인 |
| 홈 | 상품 탐색 |
|---|---|
![]() |
![]() |
| 히어로 섹션, 서비스 소개 | 전체 상품 페이징 목록 |
| 인증 | 로그인 필요 화면 |
|---|---|
![]() |
![]() |
| 로그인·회원가입 폼 | 비로그인 시 잠금 화면 |
Frontend
Backend (연동)
Infra
추천어 클릭 → setKeyword(suggestion) → 디바운스 300ms 후 API 재호출 → 추천 목록 재출력
// 해결: 클릭 시 skipNextRef를 true로 세팅, 다음 디바운스 effect에서 건너뜀
const skipNextRef = useRef(false);
const handleSuggestionClick = (suggestion) => {
skipNextRef.current = true; // 다음 fetch 1회 스킵
setKeyword(suggestion);
onSearch(suggestion);
setSuggestions([]);
};
useEffect(() => {
if (skipNextRef.current) { skipNextRef.current = false; return; }
// ... API 호출
}, [debouncedKeyword]);백엔드가 동일 이름의 상품을 여러 개 반환 (상품 ID는 다름)
// Set으로 이름 기준 중복 제거
const unique = [...new Set(response.data)];
setSuggestions(unique);localStorage에만 토큰을 저장해서 로그인해도 네비 버튼이 바뀌지 않는 문제
// AuthContext로 isLoggedIn 상태 관리
export function AuthProvider({ children }) {
const [isLoggedIn, setIsLoggedIn] = useState(() => !!getAccessToken());
const login = (token) => { _setToken(token); setIsLoggedIn(true); };
const logout = () => { _setToken(null); setIsLoggedIn(false); };
// ...
}빌드 결과물 업로드 단계에서 Google Drive 용량이 꽉 찬 것이 원인. Drive 정리 후 재트리거로 해결.
npm install
npm run dev.env
VITE_APP_BACKEND_URL=http://localhost:8080
push to master
→ CI (ubuntu-latest): npm build → rclone → Google Drive
→ CD (self-hosted) : Google Drive → Nginx /html
secrets: RCLONE_CONF_B64





