NextJS Templates
使用 Back4App、Next.js 和 Vercel 的会议室预订应用程序教程
22 分
在本教程中,您将构建 bookit , 一个会议室预订系统,使用 next js 作为前端框架,使用 back4app 作为后端服务。您将实现用户身份验证、房间管理和预订功能,并将应用程序部署在 vercel 上。 1\ 前提条件 要完成本教程,您需要: 一个 back4app 账户(在 back4app https //www back4app com/ ) 一个 back4app 项目(请遵循 本指南 https //www back4app com/docs/get started/welcome ) 在您的本地计算机上安装 node js (请参见 安装指南 https //nodejs org/ ) 对 javascript、next js 和 rest api 的基本知识(如有需要,请参见 javascript 基础 https //www back4app com/docs/javascript guide ) 2\ 设置 back4app 登录到您的 back4app 账户并导航到您的项目仪表板。 在左侧边栏中,点击 数据库 以访问数据浏览器。 您需要创建以下类来建模数据: 2 1 创建 用户 类 默认情况下,parse 处理用户身份验证,因此无需手动创建此类。parse 会自动为您管理以下字段: email 登录用的电子邮件地址 password 密码(哈希) username 可选用户名 2 2 创建 room 类 在 数据浏览器 , 点击 创建一个类 , 选择 自定义 , 并命名该类为 房间 添加以下列 列名 类型 描述 名字 字符串 房间名称 描述 字符串 房间描述 容量 数字 房间可容纳的人数 设施 数组 设施清单(电视,wifi等) 价格 数字 每小时价格 图像 文件 图片网址 所有者 指针 指向 用户 类 2 3 创建 booking 类 创建另一个自定义类,名为 booking 添加以下列 列名 类型 描述 房间 指针 指向 room 类 用户 指针 指向 user 类 入住 日期 预订的开始日期/时间 退房 日期 预订的结束日期/时间 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 使用以下命令部署您的 next js 应用 vercel 按照提示将您的应用部署到 vercel。一旦部署,您的应用将在公共 url 上上线。 8\ 结论 在本教程中,您构建了一个 bookit 应用,前端使用 next js ,后端使用 back4app 。您实现了用户身份验证、房间管理和预订功能。最后,您将应用部署在 vercel 上。您现在可以通过添加搜索、支付集成或通知等额外功能来扩展应用。