Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default [
"react/react-in-jsx-scope": "off", // React 17 이상에서는 불필요
"react/jsx-no-target-blank": ["error", { allowReferrer: true }], // 보안 문제 해결
"@typescript-eslint/no-explicit-any": "off",
"react/prop-types": "off",
},
},
];
1 change: 1 addition & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ function App() {
<NavBar />
<Routes>
<Route path="/" element={<HomePage />} />

</Routes>
</BrowserRouter>
</div>
Expand Down
80 changes: 67 additions & 13 deletions src/components/Building.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,76 @@
import styled from "@emotion/styled";
import Divider from "./Divider.tsx";
import { buildingData, BuildingInfo } from "./data/buildingData.ts";
import Overflow from "./Overflow.tsx";

interface BuildingProps {
onBuildingClick: (building: BuildingInfo) => void;
}
const Building: React.FC<BuildingProps> = ({ onBuildingClick }) => {
return (
<>
<Overflow>
<Container>
<Title>홍익대학교</Title>
</Container>
<Divider size={true} />
<Container>
<SubTitle>내부건물</SubTitle>
{buildingData.map((building) => (
<>
<BuildingItem
key={building.name}
onClick={() => onBuildingClick(building)}
>
<Image src={building.image} />
<Detail>
<Name>{building.name}</Name>
<div>운영 시간: {building.time}</div>
</Detail>
</BuildingItem>
<Divider size={false} />
</>
))}
</Container>
</Overflow>
</>
);
};
export default Building;

const Container = styled.div`
width: 400px;
position: relative;
padding: 45px;
overflow: hidden;
padding: 20px 30px;
`;
const Title = styled.div`
margin: 10px 0px;
width: 300px;
font-size: 30px;
font-size: 35px;
font-weight: 600;
`;
const Building = () => {
return (
<>
<Container>
<Title>홍익대학교</Title>
</Container>
</>
);
};
export default Building;
const SubTitle = styled.div`
font-size: 25px;
font-weight: 500;
margin-bottom: 10px;
`;
const BuildingItem = styled.a`
display: flex;
margin: 20px 0px;
color: black;
cursor: pointer;
`;
const Image = styled.img`
width: 100px;
height: 100px;
margin-right: 20px;
`;
const Detail = styled.div`
display: flex;
flex-direction: column;
gap: 10px;
`;
const Name = styled.div`
font-size: 20px;
font-weight: 500;
`;
187 changes: 187 additions & 0 deletions src/components/BuildingDetail.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
import styled from "@emotion/styled";
import { BuildingInfo, FacilityInfo } from "./data/buildingData";
import Divider from "./Divider";
import { useState } from "react";
import FacilityItem from "./FacilityItem.tsx";
import Overflow from "./Overflow.tsx";
interface BuildingDetailProps {
building: BuildingInfo;
onFacilityClick?: (facility: FacilityInfo) => void;
}
const BuildingDetail: React.FC<BuildingDetailProps> = ({
building,
onFacilityClick,
}) => {
const [selectedFloor, setSelectedFloor] = useState<string | null>(null);
const [selectedType, setSelectedType] = useState<number | null>(null);
const handleTypeChange = (type: number) => {
setSelectedType(Number(type));
if (selectedType == type) {
setSelectedType(null);
}
};
const handleFloorChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
setSelectedFloor(event.target.value);
};
return (
<>
<Overflow>
<Image src={building.image} alt={building.name} />
<Container>
<h2>{building.name}</h2>
<p>운영 시간: {building.time}</p>
<DropDown onChange={handleFloorChange}>
<option key={null} value="">
층수 선택
</option>
{building.floors.map((floor) => (
<option key={floor} value={floor}>
{floor}층
</option>
))}
</DropDown>
</Container>
<Divider size={true} />
<Container>
<DetailTitle>
{selectedFloor ? `${selectedFloor}층 내부 시설` : "내부 시설"}
</DetailTitle>
<Facilities>
<Button
onClick={() => handleTypeChange(1)}
selected={1 === selectedType}
>
화장실
</Button>
<Button
onClick={() => handleTypeChange(2)}
selected={2 === selectedType}
>
정수기
</Button>
<Button
onClick={() => handleTypeChange(3)}
selected={3 === selectedType}
>
카페
</Button>
</Facilities>

{building.facilities?.map((facility) => (
<>
<FacilityItems
key={facility.name}
onClick={() => onFacilityClick?.(facility)}
>
{selectedFloor ? (
<>
{selectedFloor === facility.floor && (
<>
{selectedType ? (
facility.type === selectedType && (
<>
<FacilityItem facility={facility} />
<Divider size={false} />
</>
)
) : (
<>
<FacilityItem facility={facility} />
<Divider size={false} />
</>
)}
</>
)}
</>
) : (
<>
{" "}
{selectedType ? (
facility.type === selectedType && (
<>
<FacilityItem facility={facility} />
<Divider size={false} />
</>
)
) : (
<>
<FacilityItem facility={facility} />
<Divider size={false} />
</>
)}
</>
)}
</FacilityItems>
</>
))}
</Container>
</Overflow>
</>
);
};

export default BuildingDetail;

const FacilityItems = styled.a`
display: flex;
flex-direction: column;
cursor: pointer;
`;

const Facilities = styled.div`
display: flex;
gap: 10px;
margin-bottom: 20px;
`;
const DetailTitle = styled.p`
font-size: 20px;
font-weight: 500;
margin-bottom: 10px;
`;
interface ButtonProps {
selected: boolean;
}
const Button = styled.button<ButtonProps>`
border: none;
background: #a7a7a7;
color: white;
padding: 5px 10px;
border-radius: 10px;
font-size: 17px;
font-weight: 300;
width: 84px;
cursor: pointer;
flex-shrink: 0;
white-space: nowrap;
&:hover {
background: rgb(0, 51, 99, 0.5);
}
${({ selected }) =>
selected &&
`
background: rgb(0, 51, 99, 0.5);
`}//
`;

const Image = styled.img`
width: 100%;
height: 200px;
object-fit: cover;
`;
const Container = styled.div`
width: 400px;
padding: 20px 30px;
`;
const DropDown = styled.select`
border: none;
margin: 10px 0px;
width: 100px;
padding: 4px 15px;
text-align: left;
border-radius: 10px;
font-size: 13.5px;
font-weight: 300;
background: #a7a7a7;
color: white;
appearance: none;
`;
12 changes: 12 additions & 0 deletions src/components/Divider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import styled from "@emotion/styled";
interface DividerProps {
size: boolean;
}
const Divider = styled.div<DividerProps>`
width: 100%;
height: ${({ size }) => (size ? "10px" : "1px")};
background: #e9e9e9;
margin-bottom: 10px;
`;

export default Divider;
Loading
Loading