NextJS Templates
Tutorial de aplicación de reserva de salas de reuniones con Back4App, Next.js y Vercel
23 min
en este tutorial, construirás bookit , un sistema de reserva de salas de reuniones utilizando next js como el marco frontend y back4app como el servicio backend implementarás la autenticación de usuarios, la gestión de salas y la funcionalidad de reservas, y desplegarás la aplicación en vercel 1 requisitos previos para completar este tutorial, necesitarás una cuenta de back4app (regístrate en back4app https //www back4app com/ ) un proyecto de back4app (sigue esta guía https //www back4app com/docs/get started/welcome ) node js instalado en tu máquina local ( guía de instalación https //nodejs org/ ) conocimientos básicos de javascript, next js y apis rest (si es necesario, consulta fundamentos de javascript https //www back4app com/docs/javascript guide ) 2 configuración de back4app inicia sesión en tu cuenta de back4app y navega a tu panel de proyecto en la barra lateral izquierda, haz clic en base de datos para acceder al navegador de datos necesitarás crear las siguientes clases para modelar los datos 2 1 crear la clase usuario correo electrónico dirección de correo electrónico para iniciar sesión contraseña contraseña (hash) nombre de usuario nombre de usuario opcional 2 2 crear la clase sala en el data browser , haz clic en crear una clase , selecciona personalizado , y nombra la clase habitación agrega las siguientes columnas nombre de la columna tipo descripción nombre cadena nombre de la sala descripción cadena descripción de la habitación capacidad número número de personas que la sala puede albergar comodidades arreglo lista de comodidades (tv, wifi, etc ) precio número precio por hora imagen archivo url de la imagen propietario puntero señala el usuario clase 2 3 crear la clase de reserva crear otra clase personalizada llamada reserva agregar las siguientes columnas nombre de la columna tipo descripción habitación puntero apunta a la clase de habitación usuario puntero apunta a la clase de usuario checkin fecha fecha/hora de inicio de la reserva checkout fecha fecha/hora de finalización de la reserva 3 configuración de next js y parse sdk crea un nuevo proyecto de next js npx create next app bookit app cd bookit app instala parse js sdk npm install parse en el pages/ app js archivo, inicializa parse con tus credenciales de 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; reemplaza 'your app id' y 'your javascript key' con las credenciales de tu aplicación de back4app 4 implementación de la autenticación de usuarios 4 1 registro de usuarios crea una nueva página pages/signup js con un formulario 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 inicio de sesión de usuarios crea pages/login js para el inicio de sesión de usuarios 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 rutas protegidas para rutas protegidas, puedes usar las rutas api de next js y verificar si el usuario 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 gestión de habitaciones 5 1 mostrando habitaciones disponibles crea pages/index js para listar las habitaciones disponibles 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 agregar una habitación crear pages/add room js para agregar nuevas habitaciones (para usuarios 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 detalles de la habitación crear pages/rooms/\[id] js para ver información detallada sobre una habitación 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 reservar una habitación agrega la funcionalidad de reserva en pages/rooms/\[id] js añadiendo un formulario 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 ver y cancelar reservas crea pages/my bookings js para ver y 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 desplegando en vercel instala el cli de vercel npm install g vercel despliega tu aplicación next js con vercel sigue las indicaciones para desplegar tu aplicación en vercel una vez desplegada, tu aplicación estará disponible en una url pública 8 conclusión en este tutorial, construiste una bookit aplicación con next js para el frontend y back4app como backend implementaste autenticación de usuarios, gestión de habitaciones y funcionalidad de reservas finalmente, desplegaste la aplicación en vercel ahora puedes expandir la aplicación con características adicionales como búsqueda, integración de pagos o notificaciones