-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #24 from 4bujak-4bujak/feature/office
feat: 지점 설정 기능
- Loading branch information
Showing
9 changed files
with
292 additions
and
18 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import React, { useState, useEffect, useRef } from 'react'; | ||
import { Branch } from '@/api/types/branch'; | ||
import Image from 'next/image'; | ||
import { getBranchInfo } from '@/api/map/getOffice'; | ||
import SelectOfficeMap from './SelectOfficeMap'; | ||
|
||
interface SearchModalProps { | ||
onClose: () => void; | ||
// eslint-disable-next-line no-unused-vars | ||
onBranchSelect: (branch: Branch) => void; | ||
} | ||
|
||
const SearchModal: React.FC<SearchModalProps> = ({ onClose, onBranchSelect }) => { | ||
const [searchTerm, setSearchTerm] = useState(''); | ||
const [allBranches, setAllBranches] = useState<Branch[]>([]); | ||
const [selectedBranch, setSelectedBranch] = useState<Branch | null>(null); | ||
const inputRef = useRef<HTMLInputElement>(null); | ||
|
||
useEffect(() => { | ||
if (inputRef.current) { | ||
inputRef.current.focus(); | ||
} | ||
}, []); | ||
|
||
useEffect(() => { | ||
const fetchData = async () => { | ||
try { | ||
const data = await getBranchInfo(); | ||
const branchInfo = data.data; | ||
const branchesArray = Array.isArray(branchInfo) ? branchInfo : []; | ||
setAllBranches(branchesArray); | ||
} catch (error) { | ||
console.error('Error fetching branch info:', error); | ||
} | ||
}; | ||
|
||
fetchData(); | ||
}, []); | ||
|
||
const filteredResults = allBranches.filter(branch => branch.branchName.includes(searchTerm)); | ||
|
||
const handleItemClick = (branch: Branch) => { | ||
setSelectedBranch(branch); | ||
onBranchSelect(branch); | ||
}; | ||
|
||
return ( | ||
<div className='fixed inset-0 flex justify-center items-center'> | ||
<section className="w-[393px] mx-auto h-full bg-white" style={{ zIndex: '101' }}> | ||
<div className="relative p-4"> | ||
<input | ||
type="text" | ||
placeholder="지점을 검색해보세요." | ||
className="w-full p-3 shadow-lg pl-10 rounded-lg" | ||
style={{ backgroundColor: '#F0F0F0' }} | ||
value={searchTerm} | ||
onChange={e => setSearchTerm(e.target.value)} | ||
ref={inputRef} | ||
/> | ||
<img | ||
src="/map/Search.png" | ||
alt="Search Icon" | ||
className="absolute left-7 top-1/2 transform -translate-y-1/2 w-5 h-5" | ||
/> | ||
<button onClick={onClose} className="absolute top-7 right-8"> | ||
X | ||
</button> | ||
</div> | ||
{searchTerm && ( | ||
<div className="p-4"> | ||
{filteredResults.length === 0 ? ( | ||
<p className="text-gray-500">검색 결과가 없습니다.</p> | ||
) : ( | ||
<ul className="divide-y divide-gray-200"> | ||
{filteredResults.map(branch => ( | ||
<li key={branch.branchName} className="flex items-center py-4 cursor-pointer hover:bg-gray-100" onClick={() => handleItemClick(branch)}> | ||
<Image src="/map/OfficeLocationSmall1.svg" alt="Location" width={12} height={16} className="mr-4" /> | ||
<span>{branch.branchName}</span> | ||
</li> | ||
))} | ||
</ul> | ||
)} | ||
</div> | ||
)} | ||
</section> | ||
{selectedBranch && <SelectOfficeMap branch={selectedBranch} onClose={onClose} />} | ||
</div> | ||
); | ||
}; | ||
|
||
export default SearchModal; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import React, { useEffect, useRef } from 'react'; | ||
import { Branch } from '@/api/types/branch'; | ||
import Image from 'next/image'; | ||
import { useBranchStore } from '@/store/branch.store'; | ||
|
||
interface SelectOfficeMapProps { | ||
branch: Branch; | ||
onClose: () => void; | ||
} | ||
|
||
const SelectOfficeMap: React.FC<SelectOfficeMapProps> = ({ branch, onClose }) => { | ||
const mapRef = useRef<HTMLDivElement>(null); | ||
const setSelectedBranch = useBranchStore((state) => state.setSelectedBranch); | ||
|
||
const handleBranchSelection = () => { | ||
setSelectedBranch(branch); | ||
onClose(); | ||
}; | ||
|
||
useEffect(() => { | ||
const { naver } = window; | ||
if (naver && branch) { | ||
const mapOptions = { | ||
center: new naver.maps.LatLng(branch.branchLatitude, branch.branchLongitude), | ||
zoom: 16, | ||
}; | ||
const map = new naver.maps.Map(mapRef.current!, mapOptions); | ||
|
||
new naver.maps.Marker({ | ||
position: new naver.maps.LatLng(branch.branchLatitude, branch.branchLongitude), | ||
map, | ||
icon: { | ||
url: '/map/OfficeActive.svg', | ||
size: new naver.maps.Size(48, 48), | ||
scaledSize: new naver.maps.Size(48, 48), | ||
origin: new naver.maps.Point(0, 0), | ||
anchor: new naver.maps.Point(24, 24), | ||
}, | ||
}); | ||
} | ||
}, [branch]); | ||
|
||
useEffect(() => { | ||
console.log('branch', branch); | ||
}, [branch]); | ||
|
||
return ( | ||
<div className="fixed inset-0 bg-white z-50 flex items-center justify-center"> | ||
<div ref={mapRef} className="w-[393px] mx-auto h-full" /> | ||
<div className="absolute top-4 right-4"> | ||
<aside className="w-[373px] mx-auto fixed bottom-[85px] left-0 right-0 z-50"> | ||
<div className="bg-white px-4 py-6 rounded-lg shadow-lg"> | ||
<div className='flex'> | ||
<div className="flex-shrink-0 w-[88px] h-[88px] bg-gray-300 rounded-md"> | ||
<Image | ||
src="/map/OfficeDefaultImg.png" | ||
alt="Office" | ||
width={88} | ||
height={88} | ||
className="object-cover rounded-md w-full h-full" | ||
/> | ||
</div> | ||
<div className='ml-4 flex-1'> | ||
<h2 className="text-xl font-semibold">{branch.branchName}</h2> | ||
{branch.branchAddress && branch.branchLatitude && branch.branchLongitude && ( | ||
<div className="flex items-start"> | ||
<Image src="/map/OfficeLocationSmall1.svg" alt="Location" width={12} height={16} className="mt-[4px] mr-2" /> | ||
<p className="text-sm break-words">{branch.branchAddress}</p> | ||
</div> | ||
)} | ||
<div className="flex"> | ||
<Image src="/map/OfficeInfo.svg" alt="Location" width={12} height={12} className="mr-2" /> | ||
<p className="text-sm break-words">회의실 43개 중 현재 22개 사용중</p> | ||
</div> | ||
</div> | ||
</div> | ||
<div className="flex w-full pt-[25px]"> | ||
<button | ||
className="flex w-[326px] h-[36px] mx-auto bg-[#EDEBF8] text-[#3B268C] px-4 py-[6px] rounded-md justify-center items-center gap-2" | ||
onClick={handleBranchSelection} | ||
> | ||
지점 설정 | ||
</button> | ||
</div> | ||
</div> | ||
</aside> | ||
<button | ||
onClick={onClose} | ||
className="absolute top-4 right-4 w-8 h-8 rounded-full bg-white text-black flex items-center justify-center" | ||
> | ||
X | ||
</button> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default SelectOfficeMap; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/* eslint-disable no-unused-vars */ | ||
import { create } from 'zustand'; | ||
import { Branch } from '@/api/types/branch'; | ||
import { persist } from 'zustand/middleware'; | ||
|
||
interface BranchStore { | ||
selectedBranch: Branch | null; | ||
setSelectedBranch: (branch: Branch | null) => void; | ||
} | ||
|
||
export const useBranchStore = create( | ||
persist<BranchStore>( | ||
(set) => ({ | ||
selectedBranch: null, | ||
setSelectedBranch: (branch: Branch | null) => set({ selectedBranch: branch }), | ||
}), | ||
{ | ||
name: 'selectedBranch' | ||
} | ||
) | ||
); |