Веб дизајн/Јун 2020

Извор: SI Wiki
Пређи на навигацију Пређи на претрагу

Junski rok 2020. godine održan je 19. juna. Postavka je dostupna sa stranice predmeta.

1. zadatak

Postavka

Napraviti sledeću mini internet aplikaciju za interni rad aerodroma Nikola Tesla. Veb aplikaciju realizovati koristeći Vue tehnologiju.

Na početnoj strani aplikacije, napraviti HTML formu, preko koje mogu da se uloguju korisnici sistema, a to su zaposleni na aerodromu i posetioci. Zaposleni i posetilac treba da imaju mogućnost unošenja korisničkog imena i lozinke. U slučaju ispravno unetih podataka, korisniku treba omogućiti rad sa ostatkom sistema (za svaki tip treba prikazati posebnu početnu stranicu/komponentu nakon logovanja). Ukoliko korisnik ne unese neki od podataka ili unese pogrešne podatke, potrebno je ispisati poruku crvenim slovima sa mogućnošću ispravljanja greške.

Zaposleni na aerodromu nakon svake uspešne prijave na sistem ima mogućnost da doda novi let, tako što unosi identifikacioni broj leta, početnu destinaciju, krajnju destinaciju i dužinu trajanja leta u minutima. Sva polja moraju biti popunjena.

Posetilac nakon svake uspešne prijave na sistem vidi tabelarni prikaz svih letova koje postoje. Svi letovi koji traju duže od 200 minuta, potrebno je obojiti zelenom bojom. Posetilac može da označi koji let želi da rezerviše, tako što klikne na dugme Rezerviši pored svakog leta u tabeli. Klikom na dugme Rezerviši prikazuje se nova komponenta, na kojoj se ispisuju svi rezervisani letovi tog korisnika.

Podatke čuvati na nivou localStorage-a.

Korisnici koji postoje u sistemu:

  • Ime: Petar, Prezime: Petrović, Tip: zaposleni, Korisničko ime: pera, Lozinka: pera123
  • Ime: Nikola, Prezime: Nikolić, Tip: posetilac, Korisničko ime: nikola, Lozinka: nikola123
  • Ime: Lazar, Prezime: Lazić, Tip: posetilac, Korisničko ime: laza, Lozinka: laza123

Studenti treba da koriste podatke koji su navedeni u tekstu zadatka, u suprotnom gube 5 poena.

NAPOMENA: Po završetku kolokvijuma samo src folder projekta sačuvati na L disk.

Rešenje

App.vue

<template>
  <router-view />
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  display: flex;
  justify-content: center;
  color: #2c3e50;
}
</style>

views

Home.vue
<template>
<main>
  <h1>Login</h1>
  <form @submit.prevent="login()">
    <p>
      <label for="username">Username</label>
      <input type="text" name="username" id="username" v-model="username" required>
    </p>
    <p>
      <label for="password">Password</label>
      <input type="password" name="password" id="password" v-model="password" required>
    </p>
    <input type="submit" value="Login">
    <p class="error">{{error}}</p>
  </form>
</main>
</template>

<style scoped>
label {
  padding-right: 10px;
}
p {
  margin: 0;
  margin-bottom: 2px;
}
.error {
  color: red;
}
</style>

<script>
export default {
  name: 'Home',
  data() {
    return {
      username: '',
      password: '',
      error: '',
      users: []
    }
  },
  created() {
    const savedUsers = localStorage.getItem('users')
    this.users = savedUsers ? JSON.parse(savedUsers) : [
      {
        name: 'Petar',
        surname: 'Petrović',
        username: 'pera',
        password: 'pera123',
        type: 'employee'
      },
      {
        name: 'Nikola',
        surname: 'Nikolić',
        username: 'nikola',
        password: 'nikola123',
        type: 'visitor'
      },
      {
        name: 'Lazar',
        surname: 'Lazić',
        username: 'laza',
        password: 'laza123',
        type: 'visitor'
      }
    ]
  },
  methods: {
    login() {
      if (this.username === '') {
        this.error = 'Unesite korisničko ime.'
        return
      }
      if (this.password === '') {
        this.error = 'Unesite lozinku.'
        return
      }
      const user = this.users.find(({username}) => username === this.username)
      if (!user) {
        this.error = 'Korisničko ime ne postoji u sistemu.'
        return
      }
      const {username, password, type} = user
      if (password !== this.password) {
        this.error = 'Pogrešna lozinka.'
        return
      }
      this.$router.push(type)
      localStorage.setItem('user', username)
    }
  }
}
</script>
Employee.vue
<template>
<main>
  <h1>Zaposleni</h1>
  <form @submit.prevent="submit()">
    <p>
      <label for="id">Identifikacioni broj</label>
      <input type="number" name="id" id="id" v-model="id" required>
    </p>
    <p>
      <label for="start">Početna destinacija</label>
      <input type="text" name="start" id="start" v-model="start" required>
    </p>
    <p>
      <label for="end">Krajnja destinacija</label>
      <input type="text" name="end" id="end" v-model="end" required>
    </p>
    <p>
      <label for="duration">Trajanje u minutima</label>
      <input type="number" name="duration" id="duration" v-model="duration" required>
    </p>
    <input type="submit" value="Unesi">
    <p class="error">{{error}}</p>
  </form>
</main>
</template>

<style scoped>
label {
  padding-right: 10px;
}
p {
  margin: 0;
  margin-bottom: 2px;
}
.error {
  color: red;
}
</style>

<script>
export default {
  name: 'Employee',
  data() {
    return {
      id: '',
      start: '',
      end: '',
      duration: '',
      error: '',
      flights: []
    }
  },
  created() {
    this.flights = JSON.parse(localStorage.getItem('flights') || '[]')
  },
  methods: {
    submit() {
      if (
        this.id === '' ||
        this.start === '' ||
        this.end == '' ||
        this.duration == ''
      ) {
        return
      }
      const flight = this.flights.find(({id}) => id === Number(this.id))
      if (flight) {
        this.error = 'Let sa zadatim identifikatorom već postoji u sistemu.'
        return
      }
      this.flights.push({
        duration: Number(this.duration),
        end: this.end,
        id: Number(this.id),
        start: this.start
      })
      localStorage.setItem('flights', JSON.stringify(this.flights))
    }
  }
}
</script>
Visitor.vue
<template>
<section>
  <h1>Posetilac: {{username}}</h1>
  <table>
    <thead>
      <tr>
        <th>Identifikacioni broj</th>
        <th>Početna destinacija</th>
        <th>Krajnja destinacija</th>
        <th>Trajanje u minutima</th>
        <th>Akcija</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="flight of flights" :key="flight.id" :class="flight.duration > 200 ? 'long' : ''">
        <td>{{flight.id}}</td>
        <td>{{flight.start}}</td>
        <td>{{flight.end}}</td>
        <td>{{flight.duration}}</td>
        <td><button @click="book(flight)">Rezerviši</button></td>
      </tr>
    </tbody>
  </table>
  <p class="error">{{error}}</p>
</section>
</template>

<style scoped>
.error {
  color: red;
}
.long {
  color: green;
  font-weight: bold;
}
</style>

<script>
export default {
  name: 'Visitor',
  data() {
    return {
      error: '',
      flights: [],
      reservations: [],
      username: ''
    }
  },
  created() {
    this.username = localStorage.getItem('user')
    this.flights = JSON.parse(localStorage.getItem('flights') || '[]')
    this.reservations = JSON.parse(localStorage.getItem('reservations') || '{}')
  },
  methods: {
    book(flight) {
      const reservations = this.reservations[this.username] || []
      const reservation = reservations.find(({id}) => id === flight.id)
      if (reservation) {
        this.error = 'Već ste rezervisali taj let.'
        return
      }
      reservations.push({...flight})
      this.reservations[this.username] = reservations
      localStorage.setItem('reservations', JSON.stringify(this.reservations))
      this.$router.push('reservations')
    }
  }
}
</script>
Reservations.vue
<template>
<main>
  <h1>Rezervacije korisnika: {{username}}</h1>
  <table>
    <thead>
      <tr>
        <th>Identifikacioni broj</th>
        <th>Početna destinacija</th>
        <th>Krajnja destinacija</th>
        <th>Trajanje u minutima</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="reservation of reservations" :key="reservation.id">
        <td>{{reservation.id}}</td>
        <td>{{reservation.start}}</td>
        <td>{{reservation.end}}</td>
        <td>{{reservation.duration}}</td>
      </tr>
    </tbody>
  </table>
  <button @click="back()">Nazad</button>
</main>
</template>

<script>
export default {
  name: 'Reservations',
  data() {
    return {
      reservations : [],
      username: ''
    }
  },
  created() {
    this.username = localStorage.getItem('user')
    this.reservations = JSON.parse(localStorage.getItem('reservations'))[this.username]
  },
  methods: {
    back() {
      this.$router.back()
    }
  }
}
</script>

router

index.js
import { createRouter, createWebHistory } from 'vue-router'
import Employee from '../views/Employee.vue'
import Home from '../views/Home.vue'
import Reservations from '../views/Reservations.vue'
import Visitor from '../views/Visitor.vue'

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/employee',
    name: 'Employee',
    component: Employee
  },
  {
    path: '/visitor',
    name: 'Visitor',
    component: Visitor
  },
  {
    path: '/reservations',
    name: 'Reservations',
    component: Reservations
  }
]

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

export default router

2. zadatak

Овај задатак није решен. Помозите SI Wiki тако што ћете га решити.