NextJS Templates
Back4App, Next.js 및 Vercel을 이용한 회의실 예약 앱 튜토리얼
23 분
이 튜토리얼에서는 bookit , 회의실 예약 시스템을 구축할 것입니다 프론트엔드 프레임워크로는 next js 를 사용하고, 백엔드 서비스로는 back4app 을 사용합니다 사용자 인증, 방 관리 및 예약 기능을 구현하고, 앱을 vercel 에 배포할 것입니다 1 필수 조건 이 튜토리얼을 완료하려면 다음이 필요합니다 back4app 계정 (가입은 https //www back4app com/ ) back4app 프로젝트 ( https //www back4app com/docs/get started/welcome ) 로컬 머신에 node js 설치 ( https //nodejs org/ ) javascript, next js 및 rest api에 대한 기본 지식 (필요한 경우, https //www back4app com/docs/javascript guide ) 2 back4app 설정하기 back4app 계정에 로그인하고 프로젝트 대시보드로 이동합니다 왼쪽 사이드바에서 데이터베이스 를 클릭하여 데이터 브라우저에 접근합니다 데이터 모델링을 위해 다음 클래스를 생성해야 합니다 2 1 사용자 클래스 생성하기 기본적으로 parse는 사용자 인증을 처리하므로 이 클래스를 수동으로 생성할 필요가 없습니다 parse는 다음 필드를 자동으로 관리합니다 이메일 로그인용 이메일 주소 비밀번호 비밀번호 (해시됨) 사용자 이름 선택적 사용자 이름 2 2 방 클래스 만들기 데이터 브라우저에서 data browser , 클릭하여 클래스 만들기 , 선택하고 사용자 정의 , 그리고 클래스를 룸 , 이름을 지정합니다 다음 열을 추가합니다 true left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type 2 3 예약 클래스 만들기 또 다른 사용자 정의 클래스를 만들기 예약 다음 열을 추가하세요 true left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type 3 next js 및 parse sdk 설정하기 새로운 next js 프로젝트 생성하기 npx create next app bookit app cd bookit app parse js sdk 설치하기 npm install parse pages/ app js 파일에서 back4app 자격증명으로 parse 초기화하기 import parse from 'parse'; parse initialize('your app id', 'your javascript key'); parse serverurl = 'https //parseapi back4app com'; function myapp({ component, pageprops }) { return \<component { pageprops} /> } export default myapp; 'your app id' 및 'your javascript key' 를 back4app 앱 자격증명으로 교체하세요 4 사용자 인증 구현하기 4 1 사용자 등록 등록 양식이 있는 새 페이지 pages/signup js 생성하기 import { usestate } from 'react'; import parse from 'parse'; export default function signup() { const \[email, setemail] = usestate(''); const \[password, setpassword] = usestate(''); const handlesignup = async (e) => { e preventdefault(); const user = new parse user(); user set('username', email); user set('email', email); user set('password', password); try { await user signup(); alert('signup successful!'); } catch (error) { alert('error ' + error message); } }; return ( \<form onsubmit={handlesignup}> \<input type="email" value={email} onchange={(e) => setemail(e target value)} placeholder="email" /> \<input type="password" value={password} onchange={(e) => setpassword(e target value)} placeholder="password" /> \<button type="submit">sign up\</button> \</form> ); } 4 2 사용자 로그인 사용자 로그인을 위한 pages/login js 생성하기 import { usestate } from 'react'; import parse from 'parse'; export default function login() { const \[email, setemail] = usestate(''); const \[password, setpassword] = usestate(''); const handlelogin = async (e) => { e preventdefault(); try { await parse user login(email, password); alert('login successful!'); } catch (error) { alert('error ' + error message); } }; return ( \<form onsubmit={handlelogin}> \<input type="email" value={email} onchange={(e) => setemail(e target value)} placeholder="email" /> \<input type="password" value={password} onchange={(e) => setpassword(e target value)} placeholder="password" /> \<button type="submit">login\</button> \</form> ); } 4 3 보호된 경로 보호된 경로의 경우, next js api 경로를 사용하고 사용자가 인증되었는지 확인할 수 있습니다 import parse from 'parse'; export default async function handler(req, res) { const user = parse user current(); if (!user) { return res status(401) json({ message 'unauthorized' }); } // proceed with the request } 5 방 관리 5 1 사용 가능한 방 표시 다음과 같이 사용 가능한 방을 나열하기 위해 pages/index js 를 생성하세요 import { useeffect, usestate } from 'react'; import parse from 'parse'; export default function home() { const \[rooms, setrooms] = usestate(\[]); useeffect(() => { const fetchrooms = async () => { const room = parse object extend('room'); const query = new parse query(room); const results = await query find(); setrooms(results); }; fetchrooms(); }, \[]); return ( \<div> \<h1>available rooms\</h1> {rooms map(room => ( \<div key={room id}> \<h2>{room get('name')}\</h2> \<img src={room get('image') url()} alt={room get('name')} /> \<p>capacity {room get('capacity')}\</p> \<p>price ${room get('price')} per hour\</p> \</div> ))} \</div> ); } 5 2 방 추가하기 새 방을 추가하기 위해 pages/add room js 를 생성합니다 (권한이 있는 사용자용) import { usestate } from 'react'; import parse from 'parse'; export default function addroom() { const \[name, setname] = usestate(''); const \[description, setdescription] = usestate(''); const \[capacity, setcapacity] = usestate(0); const \[price, setprice] = usestate(0); const handleaddroom = async (e) => { e preventdefault(); const room = parse object extend('room'); const room = new room(); room set('name', name); room set('description', description); room set('capacity', capacity); room set('price', price); try { await room save(); alert('room added successfully!'); } catch (error) { alert('error ' + error message); } }; return ( \<form onsubmit={handleaddroom}> \<input type="text" value={name} onchange={(e) => setname(e target value)} placeholder="room name" /> \<textarea value={description} onchange={(e) => setdescription(e target value)} placeholder="description">\</textarea> \<input type="number" value={capacity} onchange={(e) => setcapacity(parseint(e target value))} placeholder="capacity" /> \<input type="number" value={price} onchange={(e) => setprice(parseint(e target value))} placeholder="price" /> \<button type="submit">add room\</button> \</form> ); } 5 3 방 세부정보 방에 대한 자세한 정보를 보려면 pages/rooms/\[id] js 를 생성합니다 import { userouter } from 'next/router'; import { useeffect, usestate } from 'react'; import parse from 'parse'; export default function roomdetails() { const router = userouter(); const { id } = router query; const \[room, setroom] = usestate(null); useeffect(() => { if (!id) return; const fetchroom = async () => { const room = parse object extend('room'); const query = new parse query(room); query equalto('objectid', id); const result = await query first(); setroom(result); }; fetchroom(); }, \[id]); if (!room) return \<div>loading \</div>; return ( \<div> \<h1>{room get('name')}\</h1> \<img src={room get('image') url()} alt={room get('name')} /> \<p>{room get('description')}\</p> \<p>capacity {room get('capacity')}\</p> \<p>price ${room get('price')} per hour\</p> \</div> ); } 6 예약 시스템 6 1 방 예약하기 예약 양식을 추가하여 pages/rooms/\[id] js 에 예약 기능을 추가하세요 const \[checkin, setcheckin] = usestate(''); const \[checkout, setcheckout] = usestate(''); const handlebooking = async () => { const booking = parse object extend('booking'); const booking = new booking(); booking set('room', room); booking set('user', parse user current()); booking set('checkin', new date(checkin)); booking set('checkout', new date(checkout)); // check for double booking (example logic) const query = new parse query(booking); query equalto('room', room); query greaterthanorequalto('checkin', new date(checkin)); query lessthanorequalto('checkout', new date(checkout)); const overlap = await query first(); if (!overlap) { try { await booking save(); alert('booking successful!'); } catch (error) { alert('error ' + error message); } } else { alert('room is already booked for the selected time range '); } }; 6 2 예약 보기 및 취소하기 예약을 보기 위해 pages/my bookings js 를 생성하세요 import { useeffect, usestate } from 'react'; import parse from 'parse'; export default function mybookings() { const \[bookings, setbookings] = usestate(\[]); useeffect(() => { const fetchbookings = async () => { const booking = parse object extend('booking'); const query = new parse query(booking); query equalto('user', parse user current()); const results = await query find(); setbookings(results); }; fetchbookings(); }, \[]); const handlecancel = async (id) => { const booking = bookings find(b => b id === id); if (booking) { await booking destroy(); setbookings(bookings filter(b => b id !== id)); } }; return ( \<div> \<h1>my bookings\</h1> {bookings map(booking => ( \<div key={booking id}> \<p>room {booking get('room') get('name')}\</p> \<p>check in {new date(booking get('checkin')) tolocalestring()}\</p> \<p>check out {new date(booking get('checkout')) tolocalestring()}\</p> \<button onclick={() => handlecancel(booking id)}>cancel booking\</button> \</div> ))} \</div> ); } 7 vercel에 배포하기 vercel cli 설치 npm install g vercel 다음 js 앱을 배포하려면 vercel 프롬프트에 따라 앱을 vercel에 배포하세요 배포가 완료되면, 앱은 공개 url에서 실시간으로 제공됩니다 8 결론 이 튜토리얼에서는 bookit 앱을 next js 를 프론트엔드로 사용하고 back4app 을 백엔드로 사용하여 구축했습니다 사용자 인증, 방 관리 및 예약 기능을 구현했습니다 마지막으로, 앱을 vercel 에 배포했습니다 이제 검색, 결제 통합 또는 알림과 같은 추가 기능으로 앱을 확장할 수 있습니다