NextJS Templates
Tutorial de Aplicativo de Reserva de Sala de Reunião com Back4App, Next.js e Vercel
23 min
neste tutorial, você irá construir bookit , um sistema de reserva de salas de reunião usando next js como o framework frontend e back4app como o serviço backend você irá implementar autenticação de usuários, gerenciamento de salas e funcionalidade de reserva, e implantar o aplicativo no vercel 1 pré requisitos para completar este tutorial, você precisará uma conta no back4app (inscreva se em https //www back4app com/ ) um projeto no back4app (siga https //www back4app com/docs/get started/welcome ) node js instalado na sua máquina local ( https //nodejs org/ ) conhecimento básico de javascript, next js e rest apis (se necessário, veja https //www back4app com/docs/javascript guide ) 2 configurando o back4app faça login na sua conta do back4app e navegue até o painel do seu projeto na barra lateral esquerda, clique em banco de dados para acessar o navegador de dados você precisará criar as seguintes classes para modelar os dados 2 1 criar a classe usuário email endereço de email para login password senha (hash) username nome de usuário opcional 2 2 criar a room classe no data browser , clique em criar uma classe , selecione personalizado , e nomeie a classe sala adicione as seguintes colunas nome da coluna tipo descrição nome string nome da sala descrição string descrição do quarto capacidade número número de pessoas que a sala pode acomodar amenidades array lista de comodidades (tv, wifi, etc ) preço número preço por hora imagem arquivo url da imagem proprietário ponteiro aponta para o usuário classe 2 3 criar a booking classe criar outra classe personalizada chamada booking adicionar as seguintes colunas nome da coluna tipo descrição quarto ponteiro aponta para a classe quarto usuário ponteiro aponta para a classe usuário checkin data data/hora de início da reserva checkout data data/hora de término da reserva 3 configurando next js e parse sdk crie um novo projeto next js npx create next app bookit app cd bookit app instale o parse js sdk npm install parse no pages/ app js arquivo, inicialize o parse com suas credenciais do back4app 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; substitua 'your app id' e 'your javascript key' pelas credenciais do seu aplicativo back4app 4 implementando autenticação de usuário 4 1 registro de usuário crie uma nova página pages/signup js com um formulário de registro 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 login de usuário crie pages/login js para login de usuário 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 rotas protegidas para rotas protegidas, você pode usar as rotas da api do next js e verificar se o usuário está autenticado 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 gerenciamento de salas 5 1 exibindo salas disponíveis crie pages/index js para listar salas disponíveis 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 adicionando um quarto crie pages/add room js para adicionar novos quartos (para usuários autorizados) 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 detalhes do quarto crie pages/rooms/\[id] js para ver informações detalhadas sobre um quarto 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 sistema de reservas 6 1 reservando um quarto adicione a funcionalidade de reserva em pages/rooms/\[id] js adicionando um formulário de reserva 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 visualizando e cancelando reservas crie pages/my bookings js para visualizar e cancelar reservas 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 implantando no vercel instale o vercel cli npm install g vercel implante seu aplicativo next js com vercel siga as instruções para implantar seu aplicativo no vercel uma vez implantado, seu aplicativo estará ao vivo em uma url pública 8 conclusão neste tutorial, você construiu um bookit aplicativo com next js para o frontend e back4app como backend você implementou autenticação de usuário, gerenciamento de salas e funcionalidade de reserva finalmente, você implantou o aplicativo no vercel agora você pode expandir o aplicativo com recursos adicionais, como busca, integração de pagamento ou notificações