Skip to content

adam3am/room-booking-apps

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Room Booking Apps

  • Mengetahui ruangan yang memiliki proyektor dengan mem-filter room yang tidak memiliki proyektor.
  • Jika Room Sudah Di-Book Pada Tanggal Dan Waktu Tertentu, Maka User Lain Tidak Dapat Booking Room Tersebut.
  • Admin Bisa Mengakses Page Admin. User Selain Admin Tidak Dapat Akses. Komunikasi Endpoint Menggunakan Token.

A Beginner's Journey

Pengalaman saya mengikuti final project dari HACKTIV8 online program.

Features

BOOKAPP adalah sebuah aplikasi yang memungkinkan User untuk melihat semua ruangan meeting atau konferensi atau dengan memilih ruangan yang ingin di pesan pada waktu dan tanggal tertentu. Di Bagian backend menggunakan postgreSQL database dan di setiap komunikasi endpoint juga menggunakan JSON Web Token (JWT):

  • Guest Bisa register.
  • User Bisa login.
  • User Bisa Melakukan Booking Room.
  • Admin Dapat menambah gedung, lantai, room, serta aset.
  • Admin Dapat Menambah User Baru.
  • Admin Dapat Memperbaharui Room.
  • Admin Dapat Memperbaharui informasi User.
  • Admin Dapat Menghapus Room Yang Tersedia.
  • Admin Dapat Menghapus User Yang Sudah Terdaftar.

Prerequisites

Mungkin perlu menginstal beberapa tools berikut sebelum menjalankan project:

  • nodejs
https://nodejs.org/en/download/
  • postgresql
https://www.postgresql.org/download

Frontend

  1. Di dalam project
cd frontend
  1. BOOKAPP memiliki component Login.vue dan Register.vue untuk Member user baru
<template>
  <div>
    <h1 class="subheading grey--text">Login</h1>
    <v-container class="my-5">
      <v-layout align-center justify-center>
        <v-flex xs12 sm8 md4>
          <v-card>
            <v-toolbar flat color="light">
              <v-toolbar-title>Sign In</v-toolbar-title>
            </v-toolbar>
            <v-card-text>
              <v-form @keyup.enter.native="handleLogin">
                <v-text-field v-model="user.username" prepend-icon="person" name="login" label="Login" type="text"></v-text-field>
                <v-text-field id="password" v-model="user.password" prepend-icon="lock" name="password" label="Password" type="password"></v-text-field>
              </v-form>
              <v-alert :value="validationerror" color="error" v-html="error.message"></v-alert>
            </v-card-text>
            <v-card-actions>
              <v-spacer></v-spacer>
              <v-btn flat color="primary" @click="handleLogin">Login</v-btn>
            </v-card-actions>
          </v-card>
        </v-flex>
      </v-layout>
    </v-container>
  </div>
</template>
<template>
  <div>
    <h1 class="subheading grey--text">Register</h1>
    <v-container class="my-5">
      <v-layout align-center justify-center>
        <v-flex xs12 sm8 md4>
          <v-card>
            <v-toolbar flat color="light">
              <v-toolbar-title>Sign Up</v-toolbar-title>
            </v-toolbar>
            <v-card-text>
              <v-form @keyup.enter.native="handleRegister">
                <v-text-field v-model="user.username" prepend-icon="person" name="username" label="Username" type="text"></v-text-field>
                <v-text-field v-model="user.email" prepend-icon="mail" name="email" label="Email" type="text"></v-text-field>
                <v-text-field id="password" v-model="user.password" prepend-icon="lock" name="password" label="Password" type="password"></v-text-field>
              </v-form>
              <v-alert :value="validationerror" color="error" v-html="message.message"></v-alert>
              <v-alert :value="successful" color="success" v-html="message.message"></v-alert>
            </v-card-text>
            <v-card-actions>
              <v-spacer></v-spacer>
              <v-btn flat color="primary" @click="handleRegister">Register</v-btn>
            </v-card-actions>
          </v-card>
        </v-flex>
      </v-layout>
    </v-container>
  </div>
</template>
  1. Navbar.vue yang berisikan Homepage, Login, Register, Logout, Status booking Serta tombol Admin (jika Admin login)
<template>
  <nav id="navbar">
    <v-toolbar flat app>
      <v-toolbar-side-icon class="grey--text" @click="drawer = !drawer"></v-toolbar-side-icon>
      <v-toolbar-title class="text-uppercase grey--text">
        <span class="font-weight-light">Book</span>
        <span>App</span>
      </v-toolbar-title>
      <v-spacer></v-spacer>

      <!-- dropdown menu -->
      <v-menu offset-y>
        <v-btn slot="activator" flat color="grey">
          <v-icon left>expand_more</v-icon>
          <span>Menu</span>
        </v-btn>
        <v-list>
          <v-list-tile v-for="link in links" :key="link.text" router :to="link.route">
            <v-list-tile-title>{{ link.text }}</v-list-tile-title>
          </v-list-tile>
          <v-list-tile v-if="!currentUser" router :to="{name: 'Register'}">
            <v-list-tile-title>Sign Up</v-list-tile-title>
          </v-list-tile>
          <v-list-tile v-if="showAdmin" router :to="{name: 'Admin'}">
            <v-list-tile-title>Admin</v-list-tile-title>
          </v-list-tile>
        </v-list>
      </v-menu>

      <v-btn v-if="!currentUser" flat color="grey" :to="{name: 'Login'}">
        <span>Sign In</span>
      </v-btn>
      <v-btn v-if="currentUser" flat color="grey">
        <span @click="logOut">Log Out</span>
        <v-icon right>exit_to_app</v-icon>
      </v-btn>
    </v-toolbar>

    <v-navigation-drawer v-model="drawer" app class="primary">
      <v-layout v-if="currentUser" column align-center>
        <v-flex class="mt-5">
          <v-avatar size="100">
            <img class="text-lg-center" src="/avatar-1.png"/>
          </v-avatar>
        </v-flex>
        <p class="white--text subheading mx-auto">{{currentUser.username}}</p>
      </v-layout>
      <v-list>
        <v-list-tile v-for="link in links" :key="link.text" router :to="link.route">
          <v-list-tile-action>
            <v-icon class="white--text">{{ link.icon }}</v-icon>
          </v-list-tile-action>
          <v-list-tile-content>
            <v-list-tile-title class="white--text">{{ link.text }}</v-list-tile-title>
          </v-list-tile-content>
        </v-list-tile>
        <v-list-tile v-if="showAdmin" router :to="{name: 'Admin'}">
          <v-list-tile-action>
            <v-icon class="white--text">https</v-icon>
          </v-list-tile-action>
          <v-list-tile-content>
            <v-list-tile-title class="white--text">Admin</v-list-tile-title>
          </v-list-tile-content>
        </v-list-tile>
        <v-list-tile v-if="!currentUser" router :to="{name: 'Register'}">
          <v-list-tile-action>
            <v-icon class="white--text">how_to_reg</v-icon>
          </v-list-tile-action>
          <v-list-tile-content>
            <v-list-tile-title class="white--text">Sign Up</v-list-tile-title>
          </v-list-tile-content>
        </v-list-tile>
      </v-list>
    </v-navigation-drawer>
  </nav>
</template>
  1. Komponen Home.vue Menampilkan List Room dan Search form yang berisikan: Date Time, Kapasitas dan Daftar Aset
<template>
  <div>
    <h1 class="subheading grey--text">Home</h1>
    <v-container class="my-5">
      <v-layout>
        <v-flex xs12 lg6>
          <v-menu ref="menu1" :close-on-content-click="false" :nudge-right="40" lazy transition="scale-transition" offset-y full-width max-width="290px" min-width="290px">
            <v-text-field slot="activator" label="Date" placeholder="Select Date" persistent-hint></v-text-field>
            <v-date-picker no-title @input="menu1 = false"></v-date-picker>
          </v-menu>
        </v-flex>
        <v-spacer></v-spacer>
        <v-flex xs11 sm5>
          <v-menu ref="menu" :close-on-content-click="false" :nudge-right="40" lazy transition="scale-transition" offset-y full-width max-width="290px" min-width="290px">
            <v-text-field slot="activator" label="Time" placeholder="Select Time" readonly></v-text-field>
            <v-time-picker></v-time-picker>
          </v-menu>
        </v-flex>
      </v-layout>
      <v-layout>
        <v-text-field label="Capacity" placeholder="Input Capacity" type="number" min="0"></v-text-field>
      </v-layout>
      <v-layout row wrap>
        <v-list-tile v-for="filter in possibleFilters" :key="filter">
          <v-checkbox color="primary" :checked="filters.includes(filter)" :label="filter" @change="toggleFilter(filter)"></v-checkbox>
        </v-list-tile>
      </v-layout>
      <v-layout row wrap>
        <v-flex>
          <v-btn flat class="primary" @click="initialize">
            <span>Search</span>
          </v-btn>
        </v-flex>
      </v-layout>
      <v-layout row wrap mt-4>
        <v-flex v-for="content in matchedContents" :key="content.name" xs12 sm6 md4 lg3>
          <v-card flat class="text-xs-center ma-2">
            <v-img class="white--text" height="170px" :src="content.pictures && content.pictures[0].url"></v-img>
            <v-card-text>
              <h3 class="subheading mb-2">{{ content.name }}</h3>
              <div class="grey--text">{{ content.description }}. {{ content.name }} Mempunyai {{ content.capacity }} Kapasitas dan {{content.assets}}</div>
            </v-card-text>
            <v-card-actions class="justify-center">
              <v-btn :to="{name: 'Room', params: {id: content.id}}" flat>
                <v-icon small left>meeting_room</v-icon>
                <span>Book Now</span>
              </v-btn>
            </v-card-actions>
          </v-card>
        </v-flex>
      </v-layout>
    </v-container>
  </div>
</template>
  1. Admin Bisa Mengakses page Admin.vue. Peran Admin: Membuat (create). Meng-update (update). Menghapus (delete)

Backend

  1. Masuk ke dalam project
cd backend
  1. File config database dan token secret key berada di dalam folder app/config
module.exports = {
  HOST: "localhost",
  DB: "H8_Room_Booking",
  dialect: "postgres",
  pool: {
    max: 5,
    min: 0,
    acquire: 30000,
    idle: 10000
  }
};
module.exports = {
  secret: "secret-key"
};
  1. API endpoint di Test menggunakan Postman
HTTPENDPOINTFUNCTIONALITY
POST /api/auth/signup Everyone can signup
POST /api/auth/login User can login
POST /api/api/room Admin can create a room with token
POST /api/booking Users can book a room with token
GET /api/room/all Everyone can view all rooms
GET /api/user/all Admin can view all users with token
GET /api/booking/all Users can view all bookings with token
GET /api/room/:id Users can view a room with token
PUT /api/room/:id Admin can update a room with token
PUT /api/user/:id Admin can update a user with token
DELETE /api/room/:id Admin can delete a room with token
DELETE /api/user/:id Admin can delete a user with token

Development

Untuk me-maintain project bisa di buka dengan VSCode. CSS dan assets terpisah di setiap Backend dan Frontend folder.

Backend Node

Buat database baru, Install NPM packages dan seed db (users, rooms, bookings)

createdb H8_Room_Booking
npm install
npm run seed
npm run dev
username: admin
password: admin123

Frontend Vue

Install NPM packages dan serve

npm install
npm run serve

Search form (capacity, datetime) dan update users (password, roles) belum berfungsi dengan baik. Silakan kasih masukan:

<v-layout>
	<v-flex xs12 lg6>
		<v-menu ref="menu1" :close-on-content-click="false" :nudge-right="40" lazy transition="scale-transition" offset-y full-width max-width="290px" min-width="290px">
			<v-text-field slot="activator" label="Date" placeholder="Select Date" persistent-hint></v-text-field>
			<v-date-picker no-title @input="menu1 = false"></v-date-picker>
		</v-menu>
	</v-flex>
	<v-spacer></v-spacer>
	<v-flex xs11 sm5>
		<v-menu ref="menu" :close-on-content-click="false" :nudge-right="40" lazy transition="scale-transition" offset-y full-width max-width="290px" min-width="290px">
			<v-text-field slot="activator" label="Time" placeholder="Select Time" readonly></v-text-field>
			<v-time-picker></v-time-picker>
		</v-menu>
	</v-flex>
</v-layout>
<v-layout>
	<v-text-field label="Capacity" placeholder="Input Capacity" type="number" min="0"></v-text-field>
</v-layout>
<v-layout row wrap>
	<v-list-tile v-for="filter in possibleFilters" :key="filter">
		<v-checkbox color="primary" :checked="filters.includes(filter)" :label="filter" @change="toggleFilter(filter)"></v-checkbox>
	</v-list-tile>
</v-layout>
<v-layout row wrap>
	<v-flex>
		<v-btn flat class="primary" @click="initialize">
			<span>Search</span>
		</v-btn>
	</v-flex>
</v-layout>
exports.update = function (req, res) {
  const id = parseInt(req.params.id);
  if (Number.isInteger(id) == false) {
    return res.status(400).send('id parameter should be an integer');
  }
  db.user
    .findByPk(id, { attributes: { exclude: ['password'] } })
    .then(user => {
      const { username, email } = req.body;
      user
        .update({ username, email })
        .then((user) => {
          return res.status(201).send(user);
        })
        .catch(err => {
          console.log('Error updating user', JSON.stringify(err));
          return res.status(400).send(err);
        });
    })
};

Built With

Authors

  • Adam Maulana

About

Room Booking Apps

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages