728x90
반응형
Nextjs 화면을 반응형으로 만들기 위해 우리는 bootstrap5를 이용할 것이다.
리액트에서의 bootstrap5는 아래 링크를 확인하면 된다.
https://designmodo.com/bootstrap-react-sass/#bootstrap-5-with-react-js
SCSS에 관한 내용은 아래 링크를 참조하자.
먼저 bootstrap을 설치한다.
$ npm i bootstrap@5.0.0-alpha3
_app.tsx 파일에 추가해준다.
_app.tsx
import { AppProps } from "next/app";
import { NextPage } from "next";
//store
import wrapper from "../store";
//css
import "bootstrap/dist/css/bootstrap.min.css";
const MyApp: NextPage<AppProps> = ({ Component, pageProps }: AppProps) => {
return (
<>
<Component {...pageProps} />
</>
);
};
export default wrapper.withRedux(MyApp);
기존에 만들어 두었던 dashboard 페이지를 다시 확인하자.
src/dashboard/index.tsx
import axios from 'axios'
import type { GetServerSideProps, NextPage } from 'next'
import Link from 'next/link'
import cookies from 'next-cookies'
import jwtDecode, { JwtPayload } from 'jwt-decode'
interface Props {
data : any
}
const Dashboard:NextPage<Props> = ({data}) => {
const ClickHandler = () => {
}
return (
<div>
<div className='dashboard'>
Dashboard
</div>
</div>
)
}
export default Dashboard;
export const getServerSideProps:GetServerSideProps = async (context) => { // SSR
try {
const token = cookies(context).token;
const decodedToken: JwtPayload = jwtDecode<JwtPayload>(token ? token : '');
if(decodedToken) {
return {
props: {
}
}
}
else {
return {
redirect: {
destination: '/',
permanent: false,
},
}
}
}
catch(e) {
console.log(e)
return {
redirect: {
destination: '/',
permanent: false,
},
}
}
}
버튼을 눌렀을 경우 position이 "absolute"인 NavBar를 만들자.
dashboard/index.tsx
const Dashboard:NextPage<Props> = ({data}) => {
const [sidebarOpen,setSidebarOpen] = useState(false);
const SidebarOpen = () => {
if(sidebarOpen)
setSidebarOpen(false);
else
setSidebarOpen(true);
}
return (
<div>
{/* header */}
<div className={"w-100 d-flex align-items-center mx-auto border border-bottom-1"}
style={{
height: "50px"
}}>
<div style={{width: "5%"}}>
<button
style={{color:"blue"}}
onClick={SidebarOpen}>
o
</button>
</div>
<div
style={{ width: "75%"}}>
로고
</div>
<div style={{width: "20%"}}>
프로필
</div>
</div>
{/* nav */}
{sidebarOpen ?
<div
style={{
backgroundColor: "lightblue",
position: "absolute",
width: "200px",
height: "100%",
opacity: 1
}}>
we
</div>
: ""
}
{/* body */}
<div className='dashboard'>
Dashboard
</div>
{/* footer */}
</div>
)
}
화면을 확인해보자.
버튼을 누르면 Navbar가 뜨고, 다시 누르면 사라진다. 너무 딱딱하니까 효과를 좀 넣어주자.
SCSS와 styled-components를 사용하기 위해 다음 모듈을 설치해준다.
$ npm install sass styled-components @types/styled-components
next.config.js 파일에 path를 import 하고 sassOptions를 설정해준다.
next.config.js
/** @type {import('next').NextConfig} */
const path = require('path');
module.exports = {
sassOptions: {
includePaths: [path.join(__dirname, 'styles'), path.join(__dirname, 'src')],
},
reactStrictMode: true,
async rewrites() {
console.log(process.env.NODE_ENV)
if (process.env.NODE_ENV !== 'production') {
return [
{
source: process.env.SOURCE_PATH,
destination: process.env.DESTINATION_URL,
},
];
}
else {
return [
{
source: process.env.SOURCE_PATH,
destination: process.env.DESTINATION_URL,
},
];
}
},
}
dashboard 페이지에 SCSS와 styled-components를 활용해준다.
dashboard/index.tsx
import axios from 'axios'
import type { GetServerSideProps, NextPage } from 'next'
import Link from 'next/link'
import cookies from 'next-cookies'
import jwtDecode, { JwtPayload } from 'jwt-decode'
import { useState } from 'react'
import styled, {keyframes} from 'styled-components'
interface Props {
data : any
}
// 투명도 설정
const fadein = keyframes`
from {
opacity : 0
}
to {
opacity: 1
}
`
// NavDiv에 효과 설정
const NavDiv = styled.div`
animation-duration: 0.25s;
animation-timing-function: ease-out;
animation-name: ${fadein};
animation-fill-mode: forwards
`
const Dashboard:NextPage<Props> = ({data}) => {
const [sidebarOpen,setSidebarOpen] = useState(false);
const SidebarOpen = () => {
if(sidebarOpen)
setSidebarOpen(false);
else
setSidebarOpen(true);
}
return (
<div>
{/* header */}
<div className={"w-100 d-flex align-items-center mx-auto border border-bottom-1"}
style={{
height: "50px"
}}>
<div style={{width: "5%"}}>
<button
style={{color:"blue"}}
onClick={SidebarOpen}>
o
</button>
</div>
<div
style={{ width: "75%"}}>
로고
</div>
<div style={{width: "20%"}}>
프로필
</div>
</div>
{/* nav */}
{sidebarOpen ?
<NavDiv
style={{
backgroundColor: "lightblue",
position: "absolute",
width: "200px",
height: "100%",
opacity: 1
}}>
we
</NavDiv>
: ""
}
{/* body */}
<div className='dashboard'>
Dashboard
</div>
{/* footer */}
</div>
)
}
export default Dashboard;
export const getServerSideProps:GetServerSideProps = async (context) => { // SSR
try {
const token = cookies(context).token;
const decodedToken: JwtPayload = jwtDecode<JwtPayload>(token ? token : '');
if(decodedToken) {
return {
props: {
}
}
}
else {
return {
redirect: {
destination: '/',
permanent: false,
},
}
}
}
catch(e) {
console.log(e)
return {
redirect: {
destination: '/',
permanent: false,
},
}
}
}
inline-css가 좋지는 못하다고 하나 나중에 한꺼번에 정리하려고 일단 기능이 되는대로 넣어놨다.
다시 버튼을 눌러보면 효과가 적용되어 나타나는 것을 확인할 수 있다.
728x90
반응형
'Nest - Next' 카테고리의 다른 글
Nest - Next | n2server | Swagger (0) | 2021.11.01 |
---|---|
Nest - Next | n2server | Passport , JWT | decode in Client (0) | 2021.10.27 |
Nest - Next | n2server | Passport , JWT (0) | 2021.10.26 |
Nest - Next | n2server | Login (0) | 2021.10.25 |
Nest - Next | n2server | Signup | Complete (0) | 2021.10.25 |