Book Notes

Book Notes to aplikacja internetowa stworzona z myślą o miłośnikach książek, którzy chcą w jednym miejscu przechowywać informacje o przeczytanych pozycjach, dodawać do nich własne notatki oraz recenzje. Aplikacja umożliwia łatwe zarządzanie kolekcją przeczytanych książek, ich edycję oraz sortowanie według różnych kryteriów.

Kluczowe Funkcjonalności:

Formatowanie Daty: Daty przeczytania książek są automatycznie formatowane dla lepszej czytelności.

Wyświetlanie Listy Książek: Główna strona aplikacji dynamicznie pobiera i prezentuje listę wszystkich dodanych książek.

Dodawanie Notatek i Opisów: Użytkownik może do każdej książki dodać szczegółowy opis oraz własne przemyślenia czy ważne cytaty w sekcji notatek.

Edycja Danych: Istnieje możliwość edycji opisu oraz notatek dla każdej książki. Zmiany są zapisywane bezpośrednio w bazie danych.

Usuwanie Książek: Użytkownik może usunąć wybrane pozycje ze swojej kolekcji.

Sortowanie: Aplikacja pozwala na sortowanie zgromadzonych książek.

Aspekty Techniczne i Działanie:

Aplikacja została zbudowana w oparciu o nowoczesne technologie webowe, co zapewnia jej wydajność i skalowalność.

Backend (Node.js z Express.js):

  • Serwer aplikacji oparty jest na środowisku Node.js oraz frameworku Express.js.
  • Połączenie z bazą danych PostgreSQL: Aplikacja łączy się z bazą danych book-notes przy użyciu biblioteki pg.
JavaScript
// index.js
import pg from "pg";

const db = new pg.Client({
  user: "postgres",
  host: "localhost",
  database: "book-notes",
  password: "qwerty123", // Przykładowe hasło, powinno być zabezpieczone
  port: 5432,
});

db.connect();
  • Wyświetlanie książek (Endpoint /): Po wejściu na stronę główną, aplikacja pobiera wszystkie książki z tabeli books i przekazuje je do szablonu EJS.
JavaScript
// index.js
app.get("/", async (req, res) => {
  try {
    const dbRes = await db.query("SELECT * FROM books");
    let books = dbRes.rows;
    books.forEach((book) => {
      let date = getFormattedDate(book.readdate); // Formatowanie daty
      book.date = date;
    });
    res.render("index.ejs", {
      books: books
    });
  } catch (err) {
    console.error("Error executing query", err.stack);
  }
});
  • Formatowanie daty: Używana jest pomocnicza funkcja do formatowania daty.
JavaScript
// index.js
function getFormattedDate(date) {
  const year = date.getFullYear();
  const month = (date.getMonth() + 1).toString().padStart(2, '0');
  const day = date.getDate().toString().padStart(2, '0');
  return `<span class="math-inline">\{year\}\-</span>{month}-${day}`;
}
  • Sortowanie książek (Endpoint /sort): Użytkownik może wybrać kryterium sortowania, a aplikacja dynamicznie odpytuje bazę danych z odpowiednią klauzulą ORDER BY.
JavaScript
// index.js
app.post("/sort", async (req, res) => {
  try {
    let sortType = req.body.sortType;
    let dbRes;
    if(sortType === "title"){
      dbRes = await db.query("SELECT * FROM books ORDER BY title ASC");
    } else if (sortType === "newest") {
      dbRes = await db.query("SELECT * FROM books ORDER BY readdate DESC");
    } else if (sortType === "best") {
      dbRes = await db.query("SELECT * FROM books ORDER BY recomendationratio DESC");
    }
    // ... reszta kodu renderująca widok ...
    let books = dbRes.rows;
    books.forEach((book) => {
      let date = getFormattedDate(book.readdate);
      book.date = date;
    });
    res.render("index.ejs", {
      books: books
    });
  } catch (err) {
    console.error("Error executing query", err.stack);
  }
});
  • Edycja szczegółów książki (Endpoint /editDetails): Po przesłaniu formularza edycji, dane książki (opis i notatki) są aktualizowane w bazie.
JavaScript
// index.js
app.post("/editDetails", async (req, res) => {
  const updatedId = req.body.updatedBookId;
  const updatedDescription = req.body.updatedBookDescription.trim();
  const updatedNotes = req.body.updatedBookNotes.trim();
  try {
    await db.query(
      "UPDATE books SET description = $1, notes = $2  WHERE id = $3",
      [updatedDescription, updatedNotes, updatedId]
    );
    res.redirect("/"); // Przekierowanie na stronę główną
  } catch (err) {
    console.error("Error updating book details.", err.stack);
  }
});
  • Usuwanie książki (Endpoint /delete): Wybrana książka jest usuwana z bazy danych na podstawie jej ID.
JavaScript
// index.js
app.post("/delete", async (req, res) => {
  const deletedItemId = req.body.deletedBookId;
  try {
    await db.query("DELETE FROM books WHERE id = $1", [deletedItemId]);
    res.redirect("/"); // Przekierowanie na stronę główną
  } catch (err) {
    console.log(err);
  }
});
  • Middleware: Wykorzystywany jest body-parser do przetwarzania danych z formularzy oraz express.static do serwowania plików statycznych (np. CSS).
JavaScript
// index.js
import bodyParser from "body-parser";

app.use(express.static("public"));
app.use(bodyParser.urlencoded({extended: true}));
  • EJS (Embedded JavaScript templating): Strony HTML są dynamicznie generowane. Serwer przekazuje dane do szablonów .ejs, które następnie renderują finalny kod HTML. Przykładem jest przekazywanie listy książek do index.ejs.
  • HTML5 i CSS3: Struktura (HTML) i wygląd (CSS) aplikacji są zdefiniowane w standardowy sposób. Plik public/styles/main.css zawiera reguły stylów. Przykładowy fragment CSS dla pojedynczej książki:
JavaScript
/* public/styles/main.css */
.book {
  display: flex;
  gap: 20px;
  border: 1px solid #000;
  padding: 15px;
  margin-bottom: 20px;
  background-color: #f9f9f9;
  align-items: flex-start;
}

.bookDetails {
  display: grid;
  grid-template-rows: 187px auto auto auto;
  grid-template-columns: 125px minmax(125px, 675px);
  gap: 10px;
}

Frontend:

Środowisko Uruchomieniowe i Narzędzia:

  • Nodemon: Używany do automatycznego restartu serwera przy zmianach w kodzie.
  • npm: Służy do zarządzania zależnościami projektu.

Jak to Działa (Podsumowanie Przepływu):

  1. Uruchomienie serwera za pomocą nodemon index.js.
  2. Użytkownik otwiera stronę główną (/).
  3. Express.js obsługuje żądanie, pobiera dane książek z PostgreSQL.
  4. Dane są przekazywane do szablonu index.ejs, który generuje HTML.
  5. Interakcje użytkownika (sortowanie, edycja, usuwanie) wysyłają żądania POST.
  6. Serwer przetwarza żądanie, modyfikuje dane w bazie (jeśli to konieczne) i odświeża widok lub przekierowuje.

Projekt “Book Notes” stanowi praktyczne zastosowanie popularnych technologii backendowych i frontendowych do stworzenia użytecznej aplikacji do zarządzania osobistą kolekcją książek.

GITHUB

https://github.com/szymonMCS/bookNotes.git

Udostępnij jeśli spodobał Ci się mój projekt