diff --git a/.gitignore b/.gitignore
index 73bfe95..ce8e5b5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,4 @@
-node_modules/
-UpImage/
-archive/
public/
.vscode/
-package-lock.json
-bundle.js
-*.sqlite
output/
resources/
\ No newline at end of file
diff --git a/Readme.md b/Readme.md
index f2b7a79..ee2974c 100644
--- a/Readme.md
+++ b/Readme.md
@@ -1,5 +1,8 @@
+# This is my personal website
+
+---
+
## Build
```
-bun run build.ts
-bun run build_app
+hugo
```
\ No newline at end of file
diff --git a/backend/app.ts b/backend/app.ts
deleted file mode 100644
index c68f87c..0000000
--- a/backend/app.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import express from "express";
-
-const hostname = '127.0.0.1';
-const httpPort = 4080;
-
-const app = express();
-
-app.set('views', 'views');
-app.set('view engine', 'hbs');
-
-// import morgan from 'morgan'
-// app.use(morgan('dev'));
-app.use(express.json());
-app.use(express.urlencoded({ extended: false }));
-app.use(express.static('public'));
-
-import mainRouter from './routes/main';
-import apiRouter from './routes/api/apiRouter';
-
-app.use('/', mainRouter);
-app.use('/api', apiRouter);
-
-app.listen(httpPort, () => {
- console.log(`Server running at http://${hostname}:${httpPort}/`);
-});
-
-import mediaController from "./controllers/mediaController";
-
-await mediaController.checkImages();
\ No newline at end of file
diff --git a/backend/controllers/mediaController.ts b/backend/controllers/mediaController.ts
deleted file mode 100644
index ce1ef18..0000000
--- a/backend/controllers/mediaController.ts
+++ /dev/null
@@ -1,246 +0,0 @@
-import { type Request, type Response } from "express";
-import UserModel, { values } from '../models/userModel';
-import MediaModel, { Table, Media } from '../models/mediaModel';
-import mediaModel from "../models/mediaModel";
-
-interface omdbRes {
- Title: string,
- Released: string,
- Response: string,
- Poster: string,
- Type: string,
- imdbID: string,
- Year: string,
-}
-
-function fromStringToTable(value: string): (Table | undefined) {
- if (value.localeCompare("games") == 0) return Table.games;
- if (value.localeCompare("movies") == 0) return Table.movies;
- if (value.localeCompare("series") == 0) return Table.series;
- return;
-}
-
-async function downloadImage(mData: Media, type: Table) {
- // Specify the path where you want to save the image
- const outputPath = '/poster/' + type + '/' + mData.code + '.jpg';
-
- // Use Bun's built-in fetch to download the image
- const response = await fetch(mData.poster);
-
- // Check if the request was successful
- if (!response.ok) {
- console.log("fetch image error");
- console.log(mData.title);
- return;
- }
-
- // Convert the response to a blob
- const imageBlob = await response.blob();
- // Use Bun's write to save the image to a file
- await Bun.write('./public/' + outputPath, await imageBlob.arrayBuffer());
- MediaModel.updateWebImg(type, mData.code, outputPath);
-
-}
-
-async function createMed(req: Request, res: Response) {
- const mediaCode: string = req.body.code;
-
- const omdb_key = UserModel.getValue(values.omdb_key);
-
- if (!omdb_key) {
- return res.status(500).json({ message: 'Error when creating media' });
- }
-
- try {
-
- const uri = `http://www.omdbapi.com/?i=${mediaCode}&apikey=${omdb_key}`;
- const mJson = await fetch(uri);
- const mData: omdbRes = await mJson.json();
-
- if (mData.Response == 'False') {
- return res.status(404).json({ message: 'wrong code' });
- }
-
- const media: Media = {
- id: 0,
- code: mData.imdbID,
- title: mData.Title,
- released: mData.Released,
- webImg: "",
- poster: mData.Poster,
- year: mData.Year
- };
-
- var tableType = Table.series;
-
- if (mData.Type.localeCompare("movie") == 0) {
- tableType = Table.movies;
- }
-
- const found = MediaModel.findOne(tableType, mediaCode);
- if (found.length != 0) {
- res.status(409).json({ message: 'Media already exists' });
- await downloadImage(media, tableType);
- return;
- }
-
-
- const savedMedia = MediaModel.save(tableType, mData.imdbID, mData.Title, mData.Released, "", mData.Poster, mData.Year);
- await downloadImage(media, tableType);
-
- res.status(201).json(media);
- } catch (err) {
- return res.status(500).json({ message: 'Error when creating media' });
- }
-}
-
-async function createGame(req: Request, res: Response) {
- var gameCode = req.body.code;
-
- const twitch_client_id = UserModel.getValue(values.twitch_client_id);
- const twitch_client_secret = UserModel.getValue(values.twitch_client_secret);
-
- if (!twitch_client_id || !twitch_client_secret) {
- return res.status(500).json({ message: 'Error when creating game' });
- }
-
- try {
- const gameFound = MediaModel.findOne(Table.games, gameCode);
- if (gameFound) {
- return res.status(409).json({ message: 'Game already exists' });
- }
-
- const uri = "https://id.twitch.tv/oauth2/token?client_id=" + twitch_client_id + "&client_secret=" + twitch_client_secret + "&grant_type=client_credentials";
- var response = await fetch(uri, { method: 'POST' });
- const mData = await response.json();
-
- const mheaders: HeadersInit = {
- 'Accept': 'application/json',
- 'Client-ID': twitch_client_id,
- 'Authorization': 'Bearer ' + mData.access_token
- }
-
- gameCode = parseInt(gameCode)
-
- response = await fetch(
- "https://api.igdb.com/v4/games",
- {
- method: 'POST',
- headers: mheaders,
- body: `fields name, first_release_date; where id = ${gameCode};`
- }
- )
- const gameData = await response.json()
- if (gameData.length == 0) {
- return res.status(404).json({ message: 'wrong code' });
- }
-
- const date = new Date(gameData[0].first_release_date * 1000);
- const options: Intl.DateTimeFormatOptions = { day: 'numeric', month: 'short', year: 'numeric' }
- const dateStr = date.toLocaleDateString(undefined, options);
-
-
- response = await fetch(
- "https://api.igdb.com/v4/covers",
- {
- method: 'POST',
- headers: mheaders,
- body: `fields image_id; where game = ${gameCode};`
- }
- )
- const coverData = await response.json()
- const game: Media = {
- id: 0,
- code: gameCode,
- title: gameData[0].name,
- released: dateStr,
- webImg: "",
- poster: `https://images.igdb.com/igdb/image/upload/t_cover_big/${coverData[0].image_id}.jpg`,
- year: date.getFullYear().toString(),
- };
-
- const savedGame = MediaModel.save(Table.games, game.code, game.title, game.released, game.webImg, game.poster, game.year);
- await downloadImage(game, Table.games);
- return res.status(201).json(game);
-
- } catch (error) {
-
- return res.status(500).json({ message: 'Error when creating game', error: error });
- }
-}
-
-function list(req: Request, res: Response) {
- const mediaTable = fromStringToTable(req.params.mediaType);
- if (!mediaTable) {
- return res.status(500).json({
- message: 'Error when getting media.'
- });
- }
-
- const media = MediaModel.find(mediaTable);
- return res.json(media);
-}
-
-async function create(req: Request, res: Response) {
- const mediaCode: string = req.body.code;
- if (mediaCode.startsWith("t")) {
- return await createMed(req, res);
- } else {
- return await createGame(req, res);
- }
-}
-function remove(req: Request, res: Response) {
- const mediaTable = fromStringToTable(req.params.mediaType);
- if (!mediaTable) {
- return res.status(500).json({
- message: 'Error when deleting the media.'
- });
- }
-
- const code = req.body.code;
-
- try {
- const mediaTable = req.baseUrl.includes('movies') ? Table.movies : Table.series;
- const media = MediaModel.findOneAndDelete(mediaTable, code);
- if (!media) {
- return res.status(404).json({ message: 'No such media' });
- }
-
- return res.status(204).json();
- }
- catch (err) {
- return res.status(500).json({ message: 'Error when deleting the media.' });
- }
-}
-
-async function checkImages() {
- await checkTableImages(Table.games);
- await checkTableImages(Table.movies);
- await checkTableImages(Table.series);
-}
-function delay(time:number) {
- return new Promise(resolve => setTimeout(resolve, time));
-}
-
-async function checkTableImages(table: Table) {
- const list = mediaModel.find(table);
-
- for (const element of list) {
-
- const path = "./public/" + element.webImg;
- const f = Bun.file(path);
- const exists = await f.exists();
- if (!exists){
- console.log(element.title);
- await downloadImage(element, table);
- await delay(1000);
- }
- }
-}
-
-export default {
- list,
- create,
- remove,
- checkImages
-};
diff --git a/backend/controllers/userController.ts b/backend/controllers/userController.ts
deleted file mode 100644
index f8893f3..0000000
--- a/backend/controllers/userController.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import { type Request, type Response } from "express";
-import UserModel, { values } from '../models/userModel';
-
-export default {
-
- render: function (req: Request, res: Response) {
- res.render('user', { keys: UserModel.namesOfValues });
- },
-
- create: function (req: Request, res: Response) {
-
- const reqPassword: string = req.body.reqPassword;
- if (!reqPassword) return res.render('user', { keys: UserModel.namesOfValues });
-
- const password = UserModel.getValue(values.pass);
-
- // if no password in db save reqPassword
- if (!password) {
- const affectedRows = UserModel.updateValue("pass", reqPassword);
- if (affectedRows > 0) {
- return res.redirect('/list');
- }
- return res.render('user', { keys: UserModel.namesOfValues });
- }
- // check if passwords equal
- if (password != reqPassword) {
- return res.render('user', { keys: UserModel.namesOfValues });
- }
-
- // update
- const name: string = req.body.name;
- const value: string = req.body.value;
-
- if (!name || !value) {
- return res.render('user', { keys: UserModel.namesOfValues });
- }
-
- const affectedRows = UserModel.updateValue(name, value);
- if (affectedRows == 0) {
- return res.render('user', { keys: UserModel.namesOfValues });
- }
-
- return res.redirect('/list');
- },
-
- get: function (req: Request, res: Response) {
- const usersFound = UserModel.getAll();
- return res.status(200).json(usersFound);
- },
-};
\ No newline at end of file
diff --git a/backend/miscellaneous/checkAuthenticated.ts b/backend/miscellaneous/checkAuthenticated.ts
deleted file mode 100644
index 016a62f..0000000
--- a/backend/miscellaneous/checkAuthenticated.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { type NextFunction, type Request, type Response } from "express";
-import userModel, { values } from 'backend/models/userModel';
-
-function checkAuthenticated(req: Request, res: Response, next: NextFunction) {
- const pass = req.body.pass;
- const password = userModel.getValue(values.pass);
- if (pass && password) {
- if (pass == password) {
- return next();
- }
- }
- return res.status(500).json({ message: 'Error when getting transactions.' });
-}
-
-export default checkAuthenticated;
\ No newline at end of file
diff --git a/backend/miscellaneous/db.ts b/backend/miscellaneous/db.ts
deleted file mode 100644
index e72afa0..0000000
--- a/backend/miscellaneous/db.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import { Database } from "bun:sqlite";
-
-const pool = new Database("mydb.sqlite", { strict: true });
-
-pool.run(`
-CREATE TABLE IF NOT EXISTS series (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- code TEXT NOT NULL,
- title TEXT NOT NULL,
- released TEXT NOT NULL,
- webImg TEXT NOT NULL,
- poster TEXT NOT NULL,
- year TEXT NOT NULL
-);
-`);
-
-pool.run(`
-CREATE TABLE IF NOT EXISTS movies (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- code TEXT NOT NULL,
- title TEXT NOT NULL,
- released TEXT NOT NULL,
- webImg TEXT NOT NULL,
- poster TEXT NOT NULL,
- year TEXT NOT NULL
-);
-`);
-
-pool.run(`
-CREATE TABLE IF NOT EXISTS games (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- code TEXT NOT NULL,
- title TEXT NOT NULL,
- released TEXT NOT NULL,
- webImg TEXT NOT NULL,
- poster TEXT NOT NULL,
- year TEXT NOT NULL
-);
-`);
-
-pool.run(`
-CREATE TABLE IF NOT EXISTS userData (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- name TEXT NOT NULL,
- value TEXT NOT NULL
-);
-`);
-
-function inset_keys() {
- class co {
- count!: number;
- }
- const result = pool.query("SELECT count(*) as count FROM userData;").as(co).get();
- if(result && result.count >= 4){
- return;
- }
-
- pool.run(`
- INSERT INTO userData (name, value) VALUES ("pass", "");
- INSERT INTO userData (name, value) VALUES ("omdb_key", "");
- INSERT INTO userData (name, value) VALUES ("twitch_client_id", "");
- INSERT INTO userData (name, value) VALUES ("twitch_client_secret", "");
- `);
-}
-
-inset_keys();
-
-export default pool;
\ No newline at end of file
diff --git a/backend/models/mediaModel.ts b/backend/models/mediaModel.ts
deleted file mode 100644
index ddf1f63..0000000
--- a/backend/models/mediaModel.ts
+++ /dev/null
@@ -1,84 +0,0 @@
-import pool from 'backend/miscellaneous/db'
-
-
-export class Media {
- id!: number;
- code!: string
- title!: string;
- released!: string;
- webImg!: string;
- poster!: string;
- year!: string;
-}
-
-export enum Table {
- movies = "movies",
- series = "series",
- games = "games",
-}
-
-function save(table: Table, code: string, title: string, released:string, webImg:string, poster: string, year: string): number {
- try {
- const sql = "INSERT INTO " + table + " (code, title, released, webImg, poster, year) VALUES (?,?,?,?,?,?)";
-
- const result = pool.query(sql).run(code, title, released, webImg, poster, year);
- return result.changes;
- }
- catch (err) {
- console.log(err);
- }
- return 0;
-}
-
-function updateWebImg(table: Table, code: string, webImg: string): number {
- try {
- const sql = "UPDATE " + table + " SET webImg = ? WHERE code = ?;";
- const result = pool.query(sql).run(webImg, code);
- return result.changes;
- }
- catch (err) {
- console.log(err);
- }
- return 0;
-}
-
-function findOneAndDelete(table: Table, code: string): number {
- try {
- const result = pool.query("DELETE FROM " + table + " WHERE code = ?;").run(code);
- return result.changes;
- }
- catch (err) {
- console.log(err);
- }
- return 0;
-}
-
-function findOne(table: Table, code: string): Media[] {
- try {
- const rows = pool.query("SELECT * FROM " + table + " WHERE code = ?;").as(Media).all(code);
- return rows;
- }
- catch (err) {
- console.log(err);
- }
- return [];
-}
-
-function find(table: Table): Media[] {
- try {
- const rows = pool.query("SELECT * FROM " + table + ";").as(Media).all();
- return rows;
- }
- catch (err) {
- console.log(err);
- }
- return [];
-}
-
-export default {
- save,
- updateWebImg,
- findOneAndDelete,
- findOne,
- find
-};
\ No newline at end of file
diff --git a/backend/models/userModel.ts b/backend/models/userModel.ts
deleted file mode 100644
index 9433af3..0000000
--- a/backend/models/userModel.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import pool from 'backend/miscellaneous/db'
-
-class UserD {
- name?: string;
- value?: string;
-}
-
-export enum values {
- pass = 1,
- omdb_key,
- twitch_client_id,
- twitch_client_secret,
-}
-
-const namesOfValues: string[] = ["", "pass", "omdb_key", "twitch_client_id", "twitch_client_secret"];
-
-function getValue(name: values): string | undefined {
- try {
- const rows = pool.query("SELECT name, value FROM userData where id = ?;").as(UserD).all(name);
- if (rows.length > 0)
- return rows[0].value;
- }
- catch (err) {
- console.log(err);
- }
- return;
-}
-
-function updateValue(name: string, value: string): number {
- try {
- const result = pool.query("UPDATE userData SET value = ? WHERE name = ?").run(value, name);
- return result.changes;
- }
- catch (err) {
- console.log(err);
- }
- return 0;
-}
-
-function getAll(): UserD[] {
- try {
- const rows = pool.query("SELECT name, value FROM userData;").as(UserD).all();
- return rows;
- }
- catch (err) {
- console.log(err);
- }
- return [];
-}
-
-export default {
- getValue,
- updateValue,
- getAll,
- namesOfValues
-};
diff --git a/backend/routes/api/apiRouter.ts b/backend/routes/api/apiRouter.ts
deleted file mode 100644
index b9144a9..0000000
--- a/backend/routes/api/apiRouter.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import express, { type Request, type Response } from "express";
-import mediaRouter from './mediaRouter';
-
-const router = express.Router();
-
-router.use('/media', mediaRouter);
-
-router.get('/', function (req: Request, res: Response) {
- res.status(200).json({ message: 'API is working' });
-});
-
-export default router;
\ No newline at end of file
diff --git a/backend/routes/api/mediaRouter.ts b/backend/routes/api/mediaRouter.ts
deleted file mode 100644
index a69bc68..0000000
--- a/backend/routes/api/mediaRouter.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import express from "express";
-import mediaController from '../../controllers/mediaController.js';
-import checkAuthenticated from '../../miscellaneous/checkAuthenticated.js';
-
-const router = express.Router();
-
-router.get('/:mediaType', mediaController.list);
-
-router.post('/:mediaType', checkAuthenticated, mediaController.create);
-
-router.delete('/:mediaType', checkAuthenticated, mediaController.remove);
-
-export default router;
\ No newline at end of file
diff --git a/backend/routes/main.ts b/backend/routes/main.ts
deleted file mode 100644
index 8ca7889..0000000
--- a/backend/routes/main.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import express, { type Request, type Response } from "express";
-import userData from '../userKnowledge.json';
-
-const router = express.Router();
-
-/* GET home page. */
-router.get('/2_0', function (req: Request, res: Response) {
- res.render('main/2_0', { userData });
-});
-
-router.get('/cv', function (req: Request, res: Response) {
- res.render('cv', { userData });
-});
-
-router.get('/1_0', function (req: Request, res: Response) {
- res.render('main/1_0');
-});
-
-router.get('/list', function (req: Request, res: Response) {
- res.render('list');
-});
-
-//import userRouter from './user';
-//router.use('/user', userRouter);
-
-export default router;
\ No newline at end of file
diff --git a/backend/routes/user.ts b/backend/routes/user.ts
deleted file mode 100644
index 877a0d1..0000000
--- a/backend/routes/user.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import express from "express";
-import userController from 'backend/controllers/userController';
-import checkAuthenticated from 'backend/miscellaneous/checkAuthenticated';
-
-const router = express.Router();
-
-/* GET home page. */
-router.get('/', userController.render);
-
-router.post('/', userController.create);
-
-router.put('/', checkAuthenticated, userController.get);
-
-export default router;
\ No newline at end of file
diff --git a/backend/userKnowledge.json b/backend/userKnowledge.json
deleted file mode 100644
index 2303d64..0000000
--- a/backend/userKnowledge.json
+++ /dev/null
@@ -1,111 +0,0 @@
-{
- "first_name": "Nikola",
- "last_name": "Petrov",
- "phone_number": "+38670749506",
- "occupation": "Student",
- "birth": "14, November, 2000",
- "living_location": "Ljubljana, Slovenia",
- "web_link": "https://petrovv.com",
- "git_link": "https://git.petrovv.com/explore",
- "email": "nikola@petrovv.com",
- "instagram_handle":"@nikolainsta7",
- "instagram_link":"https://www.instagram.com/nikolainsta7",
- "about_me": [
- "I am Nikola, currently pursuing my studies at the Faculty of Electrical Engineering and Computer Science (FERI) in Maribor. My academic journey is largely driven by my interest in application and web development. I find the process of creating functional and user-friendly digital solutions both challenging and rewarding. This field allows me to blend creativity with technical skills, which I find particularly engaging.",
- "Recently, I have developed an interest in the game of Go. The strategic depth and complexity of the game have captivated my attention, providing a stimulating mental exercise. Additionally, I have started exploring photography. Capturing moments and expressing visual stories through a lens has become a newfound passion, offering a different kind of creative outlet that complements my technical pursuits."
- ],
- "project": [
- {
- "img": "/images/projects/password_manager.jpeg",
- "title": "Password manager",
- "des": "CLI app",
- "link": "https://git.petrovv.com/nikola/password_manager"
- },
- {
- "img": "/images/projects/list.jpeg",
- "title": "My watch/game list",
- "des": "",
- "link": "/list"
- },
- {
- "img": "/images/logo.png",
- "title": "Server",
- "des": "Everything running on my server",
- "link": "https://git.petrovv.com/nikola/personal_website"
- },
- {
- "img": "/images/projects/projektna_naloga.jpeg",
- "title": "Highway Tracker",
- "des": "School project",
- "link": "https://git.petrovv.com/nikola/school/src/branch/master/projektna_naloga"
- },
- {
- "img": "/images/projects/bitshift.jpeg",
- "title": "BitShifters",
- "des": "unity",
- "link": "https://git.petrovv.com/nikola/school/src/branch/master/semester_4/razvoj_programskih_sistemov/bitshifters"
- },
- {
- "img": "/images/projects/tetris.jpeg",
- "title": "Tetris",
- "des": "WPF",
- "link": "https://git.petrovv.com/nikola/school/src/branch/master/semester_4/razvoj_programskih_sistemov/tetris"
- }
- ],
- "experience": [
- {
- "title": "HW Developer",
- "company": "Spica International",
- "time": "17/03/2025 - 01/08/2025",
- "des": "Worked on access menegment systems. Programed integrated devices, based on Buildroot using c++ and python web server."
- },
- {
- "title": "Backend/Frontend",
- "company": "RRC d.o.o",
- "time": "01/09/2024 - 31/12/2024",
- "des": "Worked on goverment websites for collage enrolment and student dorm requests."
- },
- {
- "title": "Developer",
- "company": "RRC d.o.o",
- "time": "18/03/2024 - 31/05/2024",
- "des": "Student practicum. Backend in java with frontend in ext JS and jQuery."
- },
- {
- "title": "Developer/IT",
- "company": "LightAct",
- "time": "01/07/2022 - 01/09/2022",
- "des": "I helped maintaining data base, worked on the application (integrated a capture card and IP camera), assembled new server rack, installed new UTP/power connectors in the office."
- },
- {
- "title": "Mentor",
- "company": "Institute 404",
- "time": "08/06/2020 - 19/06/2020",
- "des": "I helped primary school children with their projects with soldering, laser cutting, and building."
- },
- {
- "title": "Maintenance technician",
- "company": "Hella Saturnos d.o.o.",
- "time": "04/09/2018 - 18/01/2019",
- "des": "I maintained and repaired machines from plastic presses to personal stations."
- },
- {
- "title": "Maintenance technician",
- "company": "Best Western Premier Hotel Slon",
- "time": "01/03/2018 - 04/05/2018",
- "des": "I helped with setting up the conference/event rooms. I helped customers and fixed problems like replacing light bulbs, wall sockets, hair-dryers."
- }
- ],
- "education": [
- {
- "title": "(FERI) Faculty of Electrical Engineering and Computer Science, University of Maribor",
- "time": "01/10/2021 - CURRENT",
- "des": "Graduate engineer of computer science and information technology."
- },
- {
- "title": "(SSTS Siska) Secondary school of technical professions siska",
- "time": "01/09/2016 - 07/07/2021",
- "des": "Electrotechnician."
- }
- ]
-}
\ No newline at end of file
diff --git a/backend/views/cv.hbs b/backend/views/cv.hbs
deleted file mode 100644
index 5752781..0000000
--- a/backend/views/cv.hbs
+++ /dev/null
@@ -1,189 +0,0 @@
-
-
-
-
-
-
-
-
- CV
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{#with userData}}
-
-
-
-
-
-
-
-
-
-
-
-
-
{{first_name}} {{last_name}}
-
{{occupation}}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Experience
-
-
- {{#each experience}}
-
-
-
- {{#unless @last}}
-
- {{/unless}}
-
-
-
{{title}}
-
{{company}}
-
{{time}}
-
- {{des}}
-
-
-
- {{/each}}
-
-
-
-
-
- Education
-
-
-
- {{#each education}}
-
-
-
- {{#unless @last}}
-
- {{/unless}}
-
-
-
{{des}}
- {{title}}
- {{time}}
-
-
- {{/each}}
-
-
-
-
-
-
- {{/with}}
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/backend/views/list.hbs b/backend/views/list.hbs
deleted file mode 100644
index af371a3..0000000
--- a/backend/views/list.hbs
+++ /dev/null
@@ -1,74 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- List
-
-
-
-
-
-
-
-
-
-
-
-
-
- Movies
-
-
- Series
-
-
- Games
-
-
-
- Sort
-
-
-
-
- Edit
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/backend/views/user.hbs b/backend/views/user.hbs
deleted file mode 100644
index 17a835e..0000000
--- a/backend/views/user.hbs
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- User
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/build.sh b/build.sh
deleted file mode 100755
index a04751e..0000000
--- a/build.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-hugo -d output/public --minify
-bun build ./backend/app.ts --outfile=output/app.js --target=bun --minify
-bun build ./frontend/list/list.tsx --outfile=output/public/assets/build/list.js --minify
-
-cp -r backend/views/ output/
-
-rm -rf resources
\ No newline at end of file
diff --git a/bun.lock b/bun.lock
deleted file mode 100644
index 196b900..0000000
--- a/bun.lock
+++ /dev/null
@@ -1,221 +0,0 @@
-{
- "lockfileVersion": 1,
- "configVersion": 0,
- "workspaces": {
- "": {
- "name": "web",
- "dependencies": {
- "@types/express": "^5.0.3",
- "@types/morgan": "^1.9.10",
- "bun-types": "^1.2.22",
- "express": "^5.1.0",
- "hbs": "^4.2.0",
- "morgan": "~1.10.1",
- "typescript": "^5.9.2",
- },
- },
- },
- "packages": {
- "@types/body-parser": ["@types/body-parser@1.19.6", "", { "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g=="],
-
- "@types/connect": ["@types/connect@3.4.38", "", { "dependencies": { "@types/node": "*" } }, "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug=="],
-
- "@types/express": ["@types/express@5.0.3", "", { "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^5.0.0", "@types/serve-static": "*" } }, "sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw=="],
-
- "@types/express-serve-static-core": ["@types/express-serve-static-core@5.0.7", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-R+33OsgWw7rOhD1emjU7dzCDHucJrgJXMA5PYCzJxVil0dsyx5iBEPHqpPfiKNJQb7lZ1vxwoLR4Z87bBUpeGQ=="],
-
- "@types/http-errors": ["@types/http-errors@2.0.5", "", {}, "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg=="],
-
- "@types/mime": ["@types/mime@1.3.5", "", {}, "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="],
-
- "@types/morgan": ["@types/morgan@1.9.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-sS4A1zheMvsADRVfT0lYbJ4S9lmsey8Zo2F7cnbYjWHP67Q0AwMYuuzLlkIM2N8gAbb9cubhIVFwcIN2XyYCkA=="],
-
- "@types/node": ["@types/node@24.5.1", "", { "dependencies": { "undici-types": "~7.12.0" } }, "sha512-/SQdmUP2xa+1rdx7VwB9yPq8PaKej8TD5cQ+XfKDPWWC+VDJU4rvVVagXqKUzhKjtFoNA8rXDJAkCxQPAe00+Q=="],
-
- "@types/qs": ["@types/qs@6.14.0", "", {}, "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ=="],
-
- "@types/range-parser": ["@types/range-parser@1.2.7", "", {}, "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ=="],
-
- "@types/react": ["@types/react@19.1.13", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ=="],
-
- "@types/send": ["@types/send@0.17.5", "", { "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w=="],
-
- "@types/serve-static": ["@types/serve-static@1.15.8", "", { "dependencies": { "@types/http-errors": "*", "@types/node": "*", "@types/send": "*" } }, "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg=="],
-
- "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="],
-
- "basic-auth": ["basic-auth@2.0.1", "", { "dependencies": { "safe-buffer": "5.1.2" } }, "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg=="],
-
- "body-parser": ["body-parser@2.2.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.0", "http-errors": "^2.0.0", "iconv-lite": "^0.6.3", "on-finished": "^2.4.1", "qs": "^6.14.0", "raw-body": "^3.0.0", "type-is": "^2.0.0" } }, "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg=="],
-
- "bun-types": ["bun-types@1.2.22", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-hwaAu8tct/Zn6Zft4U9BsZcXkYomzpHJX28ofvx7k0Zz2HNz54n1n+tDgxoWFGB4PcFvJXJQloPhaV2eP3Q6EA=="],
-
- "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="],
-
- "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
-
- "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
-
- "content-disposition": ["content-disposition@1.0.0", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg=="],
-
- "content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="],
-
- "cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="],
-
- "cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="],
-
- "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
-
- "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
-
- "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
-
- "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
-
- "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
-
- "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="],
-
- "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
-
- "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
-
- "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
-
- "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="],
-
- "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="],
-
- "express": ["express@5.1.0", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.0", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA=="],
-
- "finalhandler": ["finalhandler@2.1.0", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q=="],
-
- "foreachasync": ["foreachasync@3.0.0", "", {}, "sha512-J+ler7Ta54FwwNcx6wQRDhTIbNeyDcARMkOcguEqnEdtm0jKvN3Li3PDAb2Du3ubJYEWfYL83XMROXdsXAXycw=="],
-
- "forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="],
-
- "fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="],
-
- "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
-
- "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
-
- "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
-
- "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
-
- "handlebars": ["handlebars@4.7.7", "", { "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.0", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, "optionalDependencies": { "uglify-js": "^3.1.4" }, "bin": { "handlebars": "bin/handlebars" } }, "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA=="],
-
- "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
-
- "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
-
- "hbs": ["hbs@4.2.0", "", { "dependencies": { "handlebars": "4.7.7", "walk": "2.3.15" } }, "sha512-dQwHnrfWlTk5PvG9+a45GYpg0VpX47ryKF8dULVd6DtwOE6TEcYQXQ5QM6nyOx/h7v3bvEQbdn19EDAcfUAgZg=="],
-
- "http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="],
-
- "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
-
- "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
-
- "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="],
-
- "is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="],
-
- "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
-
- "media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="],
-
- "merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="],
-
- "mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="],
-
- "mime-types": ["mime-types@3.0.1", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA=="],
-
- "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
-
- "morgan": ["morgan@1.10.1", "", { "dependencies": { "basic-auth": "~2.0.1", "debug": "2.6.9", "depd": "~2.0.0", "on-finished": "~2.3.0", "on-headers": "~1.1.0" } }, "sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A=="],
-
- "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
-
- "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
-
- "neo-async": ["neo-async@2.6.2", "", {}, "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="],
-
- "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
-
- "on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="],
-
- "on-headers": ["on-headers@1.1.0", "", {}, "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A=="],
-
- "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
-
- "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="],
-
- "path-to-regexp": ["path-to-regexp@8.3.0", "", {}, "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA=="],
-
- "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
-
- "qs": ["qs@6.14.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w=="],
-
- "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="],
-
- "raw-body": ["raw-body@3.0.1", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.7.0", "unpipe": "1.0.0" } }, "sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA=="],
-
- "router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="],
-
- "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
-
- "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
-
- "send": ["send@1.2.0", "", { "dependencies": { "debug": "^4.3.5", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.0", "mime-types": "^3.0.1", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.1" } }, "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw=="],
-
- "serve-static": ["serve-static@2.2.0", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ=="],
-
- "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="],
-
- "side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
-
- "side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="],
-
- "side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="],
-
- "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
-
- "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
-
- "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
-
- "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
-
- "type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="],
-
- "typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="],
-
- "uglify-js": ["uglify-js@3.19.3", "", { "bin": { "uglifyjs": "bin/uglifyjs" } }, "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ=="],
-
- "undici-types": ["undici-types@7.12.0", "", {}, "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ=="],
-
- "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="],
-
- "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="],
-
- "walk": ["walk@2.3.15", "", { "dependencies": { "foreachasync": "^3.0.0" } }, "sha512-4eRTBZljBfIISK1Vnt69Gvr2w/wc3U6Vtrw7qiN5iqYJPH7LElcYh/iU4XWhdCy2dZqv1ToMyYlybDylfG/5Vg=="],
-
- "wordwrap": ["wordwrap@1.0.0", "", {}, "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="],
-
- "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
-
- "basic-auth/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
-
- "http-errors/statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="],
-
- "morgan/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
-
- "morgan/on-finished": ["on-finished@2.3.0", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww=="],
-
- "raw-body/iconv-lite": ["iconv-lite@0.7.0", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ=="],
-
- "morgan/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
- }
-}
diff --git a/content/about_me.md b/content/about_me.md
index dfd7101..864be84 100644
--- a/content/about_me.md
+++ b/content/about_me.md
@@ -1,15 +1,15 @@
+++
title = "About Me"
-description = "Des"
+description = "About me page"
date = "2019-02-28"
author = "Nikola Petrov"
+++
-I’m Nikola, a student at the Faculty of Electrical Engineering and Computer Science (FERI) in Maribor. My academic focus is on application and web development, where I enjoy creating functional, user-friendly digital solutions. This field allows me to combine technical skills with creativity, which I find both challenging and fulfilling.
+I am Nikola, I have studied at the Faculty of Electrical Engineering and Computer Science (FERI) in Maribor. My focus is on application and web development, where I enjoy creating functional, user-friendly digital solutions. This field allows me to combine technical skills with creativity, which I find both challenging and fulfilling.
-Beyond my studies, I’ve recently developed a passion for the game of Go. Its strategic depth and complexity provide a stimulating mental challenge that I find incredibly engaging.
+Beyond my studies, I have developed a passion for the game of Go. Its strategic depth and complexity provide a stimulating mental challenge that I find incredibly engaging.
**Interests**
- **Backend Programming**: Specializing in server-side development, I work on data storage, processing, and business logic to power web and mobile applications.
-- **Embedded Systems**: I’m fascinated by specialized computing devices integrated into everyday products, designed to perform dedicated functions under real-time constraints.
+- **Embedded Systems**: I am fascinated by specialized computing devices integrated into everyday products, designed to perform dedicated functions under real-time constraints.
- **Application Programming**: I enjoy writing code to build software applications that solve specific problems or perform targeted tasks.
diff --git a/dev.ts b/dev.ts
deleted file mode 100644
index 61d5aa6..0000000
--- a/dev.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-
-const build_list = Bun.spawn(["bun", "build", "./frontend/list/list.tsx", "--outfile=public/assets/build/list/list.js", "--watch"]);
-const build_app = Bun.spawn(["bun", "--watch", "./app.ts"]);
-
diff --git a/frontend/elementcreate.tsx b/frontend/elementcreate.tsx
deleted file mode 100644
index a59a7f0..0000000
--- a/frontend/elementcreate.tsx
+++ /dev/null
@@ -1,71 +0,0 @@
-///
-///
-///
-
-export interface Children {
- children?: AttributeValue;
-}
-
-export interface CustomElementHandler {
- (attributes: Attributes, contents: (string | HTMLElement)[]): HTMLElement;
-}
-
-export interface Attributes {
- [key: string]: AttributeValue;
-}
-
-
-export function createElement(
- tag: string | CustomElementHandler,
- attrs: Attributes & Children | undefined = {},
- ...children: (string | HTMLElement)[]
-): HTMLElement {
-
- if (typeof tag === "function") {
- if (attrs == null) {
- attrs = { num: 0 };
- }
- if (children == null) {
- children = [""];
- }
- return tag(attrs, children);
- }
-
- const retElement = document.createElement(tag);
-
- for (let name in attrs) {
- if (name && attrs.hasOwnProperty(name)) {
-
- let value = attrs[name];
- if (typeof value === "number") {
- retElement.setAttribute(name, value.toString());
- } else if (typeof value === "function") {
- retElement.addEventListener(name.slice(2), value);
- }
- else {
- retElement.setAttribute(name, value);
- }
- }
- }
-
- for (let i = 2; i < arguments.length; i++) {
- let child = arguments[i];
-
- // check if child is a HTMLElement
- if (child.nodeType != undefined) {
- retElement.appendChild(child);
- continue;
- }
-
- if (child instanceof Array) {
- for (let j = 0; j < child.length; j++) {
- if (child[j].nodeType != undefined) retElement.appendChild(child[j]);
- else retElement.appendChild(document.createTextNode(child[j].toString()));
- }
- continue;
- }
- // child is a string
- retElement.appendChild(document.createTextNode(child.toString()));
- }
- return retElement;
-}
\ No newline at end of file
diff --git a/frontend/list/elements.tsx b/frontend/list/elements.tsx
deleted file mode 100644
index 8e9b06f..0000000
--- a/frontend/list/elements.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import type { Attributes } from "frontend/elementcreate";
-import * as elements from "frontend/elementcreate";
-
-function MediaElement(attributes: Attributes, contents: string[]) {
- const ret = ;
- return ret;
-}
-
-
-function MyHeader(attributes: Attributes, contents: string[]) {
- return
-
-
{attributes['title']} {attributes['num'] ? ": " + attributes['num'] : ""}
-
-
;
-}
-
-function MediaContainer(attributes: Attributes, contents: string[]) {
- return {contents[0]}
;
-}
-
-export { MediaElement, MyHeader, MediaContainer }
\ No newline at end of file
diff --git a/frontend/list/functions.tsx b/frontend/list/functions.tsx
deleted file mode 100644
index 4f82060..0000000
--- a/frontend/list/functions.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-
-function splitByTitle(movies: Array): { [s: string]: Movie[]; } {
- const result = movies.reduce((r, a) => {
- var letter = a.title[0].toUpperCase();
- if (!isNaN(parseInt(letter))) letter = "#";
- r[letter] = r[letter] || [];
- r[letter].push(a);
- return r;
- }, Object.create(null));
-
- return result;
-}
-
-function splitByYear(movies: Array): { [s: string]: Movie[]; } {
- const result = movies.reduce((r, a) => {
- const year = new Date(a.released).getFullYear();
- r[year] = r[year] || [];
- r[year].push(a);
- return r;
- }, Object.create(null));
-
- return result;
-}
-
-export { splitByTitle, splitByYear };
\ No newline at end of file
diff --git a/frontend/list/list.tsx b/frontend/list/list.tsx
deleted file mode 100644
index d000552..0000000
--- a/frontend/list/list.tsx
+++ /dev/null
@@ -1,287 +0,0 @@
-import { MediaElement, MyHeader, MediaContainer } from "frontend/list/elements";
-import { splitByTitle, splitByYear } from "frontend/list/functions";
-
-import * as elements from "frontend/elementcreate";
-
-var sortType = 0;
-var listType = 0;
-
-const sortTypeTitle = 0;
-const sortTypeYear = 1;
-const sortTypeId = 2;
-
-const moviesType = 0;
-const gamesType = 1;
-const seriesType = 2;
-
-var listButtons: Array = [];
-var sortButtons: Array = [];
-
-var root: HTMLElement | null;
-var editButton: HTMLElement | null;
-var movieElements: HTMLElement[] = [];
-
-function getLink(): string {
- switch (listType) {
- case moviesType:
- return "/api/media/movies";
- case gamesType:
- return "/api/media/games";
- case seriesType:
- return "/api/media/series";
- }
- return "/api/media/movies";
-}
-
-async function reload() {
- try {
- const response = await fetch(getLink());
- const movies = await response.json();
- renderMedias(movies);
- } catch (err) {
- console.log(err);
- }
-}
-
-function submitMedia(event: SubmitEvent) {
- event.preventDefault();
-
- const pass = document.getElementById("pass") as HTMLInputElement | null;
- if (!pass) return;
-
- const input_id = document.getElementById("input_id") as HTMLInputElement | null;
- if (!input_id) return;
-
-
- if (pass.value == "" || input_id.value == "") return;
-
-
- fetch(getLink(), {
- body: JSON.stringify({ pass: pass.value, code: input_id.value }),
- headers: { "Content-Type": "application/json" },
- method: "POST"
- })
- .then(async (response) => {
- if (response.status != 201) {
- const json = await response.json();
- console.log(json);
- alert(json.message);
- return;
- }
-
- await reload();
- })
- .catch(err => {
- console.log(err);
- });
-
- input_id.value = "";
-}
-
-function loadState() {
- const searchParams = new URLSearchParams(window.location.search);
- if (searchParams.has("listType")) {
- switch (searchParams.get("listType")) {
- case "movies":
- listType = moviesType;
- break;
- case "series":
- listType = seriesType;
- break;
- case "games":
- listType = gamesType;
- break;
- default:
- listType = moviesType;
- break;
- }
- }
-
- if (searchParams.has("sortType")) {
- switch (searchParams.get("sortType")) {
- case "title":
- sortType = sortTypeTitle;
- break;
- case "year":
- sortType = sortTypeYear;
- break;
- case "id":
- sortType = sortTypeId;
- break;
- default:
- sortType = sortTypeTitle;
- break;
- }
- }
-}
-
-function changeType(type: number) {
- listType = type;
- loadPage();
- const searchParams = new URLSearchParams(window.location.search);
- switch (listType) {
- case moviesType:
- searchParams.set("listType", "movies");
- break;
- case gamesType:
- searchParams.set("listType", "games");
- break;
- case seriesType:
- searchParams.set("listType", "series");
- break;
- }
- history.replaceState({}, '', window.location.pathname + '?' + searchParams.toString());
-}
-
-function changeSort(type: number) {
- sortType = type;
- loadPage();
- const searchParams = new URLSearchParams(window.location.search);
- switch (type) {
- case sortTypeTitle:
- searchParams.set("sortType", "title");
- break;
- case sortTypeYear:
- searchParams.set("sortType", "year");
- break;
- case sortTypeId:
- searchParams.set("sortType", "id");
- break;
- }
- history.replaceState({}, '', window.location.pathname + '?' + searchParams.toString());
-}
-
-
-function splitBySort(movies: Array): { [s: string]: Movie[]; } {
- switch (sortType) {
- case sortTypeYear:
- const sorted = movies.sort((a, b) => {
- const ay = Date.parse(a.released);
- const by = Date.parse(b.released);
- return ay - by;
- });
- return splitByYear(sorted);
- case sortTypeId:
- movies.sort((a, b) => a.id < b.id ? 1 : -1);
- return { "added": movies };
- default:
- return splitByTitle(movies.sort((a, b) => a.title.localeCompare(b.title)));
- }
-}
-
-function toggleEdit() {
- movieElements.forEach(element => {
- const div = element.querySelector(".d-none");
- if (!div) return;
- div.classList.remove("d-none");
- div.classList.add("d-flex");
- });
-}
-
-document.addEventListener('DOMContentLoaded', async () => {
- document.getElementById("myform")?.addEventListener("submit", submitMedia);
-
- listButtons.push(document.getElementById("movieButton"));
- listButtons.push(document.getElementById("gameButton"));
- listButtons.push(document.getElementById("seriesButton"));
- listButtons.forEach((button, index) => button?.addEventListener("click", () => changeType(index)));
-
- sortButtons.push(document.getElementById("titleButton"));
- sortButtons.push(document.getElementById("yearButton"));
- sortButtons.push(document.getElementById("idButton"));
- sortButtons.forEach((button, index) => button?.addEventListener("click", () => changeSort(index)));
-
- editButton = document.getElementById("editButton");
- editButton?.addEventListener("click", () => toggleEdit());
-
- loadState();
- loadPage();
-});
-
-async function loadPage() {
-
- listButtons.forEach(button => button?.classList.remove("active"));
- listButtons[listType]?.classList.add("active");
-
- await reload();
-}
-
-
-function removeMedia(evt: Event) {
- const password = document.getElementById("pass") as HTMLInputElement | null;
- if (!password) return;
- if (password.value == "") return;
-
- let elem = evt.target as HTMLElement | null;
-
- while (elem && !elem.classList.contains('media-element')) {
- elem = elem.parentElement;
- }
-
- if (!elem) return;
- const id = elem.id;
-
- fetch(getLink(), {
- body: JSON.stringify({ pass: password.value, code: id }),
- headers: { "Content-Type": "application/json" },
- method: "DELETE"
- })
- .then(async (response) => {
-
- if (response.status != 204) {
- console.log("error");
- console.log(response.body);
- return;
- }
- document.getElementById(id)?.remove();
- })
- .catch(err => {
- console.log(err);
- });
- password.value = "";
-}
-
-function onImgError(evt: Event) {
- const imgT = evt.target as HTMLImageElement;
- imgT.src = "/images/no_poster.jpg";
- console.log(imgT.parentElement?.parentElement?.id);
-}
-
-function renderMedias(unsorted_movies: Array) {
- root = document.getElementById('root');
- if (!root) return;
-
- root.innerHTML = "";
- movieElements = [];
-
- const splitMovies = splitBySort(unsorted_movies);
-
- let years;
- if (sortType == sortTypeTitle) {
- years = Object.keys(splitMovies).sort((a, b) => -b.localeCompare(a));
- } else {
- years = Object.keys(splitMovies).sort((a, b) => b.localeCompare(a));
- }
-
-
- root.appendChild( );
-
- for (const letter of years) {
-
- const movies = splitMovies[letter];
-
- const header = ;
- root.appendChild(header);
-
- const row =
-
- {movies.map(movie => {
- const med = ;
- movieElements.push(med);
- return med;
- })}
- ;
-
- root.appendChild(row);
- }
-}
\ No newline at end of file
diff --git a/frontend/list/types.d.ts b/frontend/list/types.d.ts
deleted file mode 100644
index 241d6b8..0000000
--- a/frontend/list/types.d.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-interface Movie {
- title: string;
- released: string;
- code: string;
- webImg: string;
- id: string;
-}
\ No newline at end of file
diff --git a/frontend/utils/attr.d.ts b/frontend/utils/attr.d.ts
deleted file mode 100644
index 3d06107..0000000
--- a/frontend/utils/attr.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-type AttributeValue = number | string | EventListener;
\ No newline at end of file
diff --git a/frontend/utils/element-types.d.ts b/frontend/utils/element-types.d.ts
deleted file mode 100644
index 932fc8c..0000000
--- a/frontend/utils/element-types.d.ts
+++ /dev/null
@@ -1,341 +0,0 @@
-declare namespace JSX {
- interface HtmlTag {
- accesskey?: string;
- class?: string;
- contenteditable?: string;
- dir?: string;
- hidden?: string | boolean;
- id?: AttributeValue;
- role?: string;
- lang?: string;
- draggable?: string | boolean;
- spellcheck?: string | boolean;
- style?: string;
- tabindex?: string;
- title?: string;
- translate?: string | boolean;
- }
- interface HtmlAnchorTag extends HtmlTag {
- href?: string;
- target?: string;
- download?: string;
- ping?: string;
- rel?: string;
- media?: string;
- hreflang?: string;
- type?: string;
- }
- interface HtmlAreaTag extends HtmlTag {
- alt?: string;
- coords?: string;
- shape?: string;
- href?: string;
- target?: string;
- ping?: string;
- rel?: string;
- media?: string;
- hreflang?: string;
- type?: string;
- }
- interface HtmlAudioTag extends HtmlTag {
- src?: string;
- autobuffer?: string;
- autoplay?: string;
- loop?: string;
- controls?: string;
- }
- interface BaseTag extends HtmlTag {
- href?: string;
- target?: string;
- }
- interface HtmlQuoteTag extends HtmlTag {
- cite?: string;
- }
- interface HtmlBodyTag extends HtmlTag {
- }
- interface HtmlButtonTag extends HtmlTag {
- action?: string;
- autofocus?: string;
- disabled?: string;
- enctype?: string;
- form?: string;
- method?: string;
- name?: string;
- novalidate?: string | boolean;
- target?: string;
- type?: string;
- value?: string;
- onClick?: Function;
- }
- interface HtmlDataListTag extends HtmlTag {
- }
- interface HtmlCanvasTag extends HtmlTag {
- width?: string;
- height?: string;
- }
- interface HtmlTableColTag extends HtmlTag {
- span?: string;
- }
- interface HtmlTableSectionTag extends HtmlTag {
- }
- interface HtmlTableRowTag extends HtmlTag {
- }
- interface DataTag extends HtmlTag {
- value?: string;
- }
- interface HtmlEmbedTag extends HtmlTag {
- src?: string;
- type?: string;
- width?: string;
- height?: string;
- }
- interface HtmlFieldSetTag extends HtmlTag {
- disabled?: string;
- form?: string;
- name?: string;
- }
- interface HtmlFormTag extends HtmlTag {
- acceptCharset?: string;
- action?: string;
- autocomplete?: string;
- enctype?: string;
- method?: string;
- name?: string;
- novalidate?: string | boolean;
- target?: string;
- }
- interface HtmlHtmlTag extends HtmlTag {
- manifest?: string;
- }
- interface HtmlIFrameTag extends HtmlTag {
- src?: string;
- srcdoc?: string;
- name?: string;
- sandbox?: string;
- seamless?: string;
- width?: string;
- height?: string;
- }
- interface HtmlImageTag extends HtmlTag {
- alt?: string;
- src?: AttributeValue;
- crossorigin?: string;
- usemap?: string;
- ismap?: string;
- width?: string;
- height?: string;
- }
- interface HtmlInputTag extends HtmlTag {
- accept?: string;
- action?: string;
- alt?: string;
- autocomplete?: string;
- autofocus?: string;
- checked?: string | boolean;
- disabled?: string | boolean;
- enctype?: string;
- form?: string;
- height?: string;
- list?: string;
- max?: string;
- maxlength?: string;
- method?: string;
- min?: string;
- multiple?: string;
- name?: string;
- novalidate?: string | boolean;
- pattern?: string;
- placeholder?: string;
- readonly?: string;
- required?: string;
- size?: string;
- src?: string;
- step?: string;
- target?: string;
- type?: string;
- value?: string;
- width?: string;
- }
- interface HtmlModTag extends HtmlTag {
- cite?: string;
- datetime?: string | Date;
- }
- interface KeygenTag extends HtmlTag {
- autofocus?: string;
- challenge?: string;
- disabled?: string;
- form?: string;
- keytype?: string;
- name?: string;
- }
- interface HtmlLabelTag extends HtmlTag {
- form?: string;
- for?: string;
- }
- interface HtmlLITag extends HtmlTag {
- value?: string | number;
- }
- interface HtmlLinkTag extends HtmlTag {
- href?: string;
- crossorigin?: string;
- rel?: string;
- media?: string;
- hreflang?: string;
- type?: string;
- sizes?: string;
- integrity?: string;
- }
- interface HtmlMapTag extends HtmlTag {
- name?: string;
- }
- interface HtmlMetaTag extends HtmlTag {
- name?: string;
- httpEquiv?: string;
- content?: string;
- charset?: string;
- }
- interface HtmlMeterTag extends HtmlTag {
- value?: string | number;
- min?: string | number;
- max?: string | number;
- low?: string | number;
- high?: string | number;
- optimum?: string | number;
- }
- interface HtmlObjectTag extends HtmlTag {
- data?: string;
- type?: string;
- name?: string;
- usemap?: string;
- form?: string;
- width?: string;
- height?: string;
- }
- interface HtmlOListTag extends HtmlTag {
- reversed?: string;
- start?: string | number;
- }
- interface HtmlOptgroupTag extends HtmlTag {
- disabled?: string;
- label?: string;
- }
- interface HtmlOptionTag extends HtmlTag {
- disabled?: string;
- label?: string;
- selected?: string;
- value?: string;
- }
- interface HtmlOutputTag extends HtmlTag {
- for?: string;
- form?: string;
- name?: string;
- }
- interface HtmlParamTag extends HtmlTag {
- name?: string;
- value?: string;
- }
- interface HtmlProgressTag extends HtmlTag {
- value?: string | number;
- max?: string | number;
- }
- interface HtmlCommandTag extends HtmlTag {
- type?: string;
- label?: string;
- icon?: string;
- disabled?: string;
- checked?: string;
- radiogroup?: string;
- default?: string;
- }
- interface HtmlLegendTag extends HtmlTag {
- }
- interface HtmlBrowserButtonTag extends HtmlTag {
- type?: string;
- }
- interface HtmlMenuTag extends HtmlTag {
- type?: string;
- label?: string;
- }
- interface HtmlScriptTag extends HtmlTag {
- src?: string;
- type?: string;
- charset?: string;
- async?: string;
- defer?: string;
- crossorigin?: string;
- integrity?: string;
- text?: string;
- }
- interface HtmlDetailsTag extends HtmlTag {
- open?: string;
- }
- interface HtmlSelectTag extends HtmlTag {
- autofocus?: string;
- disabled?: string;
- form?: string;
- multiple?: string;
- name?: string;
- required?: string;
- size?: string;
- }
- interface HtmlSourceTag extends HtmlTag {
- src?: string;
- type?: string;
- media?: string;
- }
- interface HtmlStyleTag extends HtmlTag {
- media?: string;
- type?: string;
- disabled?: string;
- scoped?: string;
- }
- interface HtmlTableTag extends HtmlTag {
- }
- interface HtmlTableDataCellTag extends HtmlTag {
- colspan?: string | number;
- rowspan?: string | number;
- headers?: string;
- }
- interface HtmlTextAreaTag extends HtmlTag {
- autofocus?: string;
- cols?: string;
- dirname?: string;
- disabled?: string;
- form?: string;
- maxlength?: string;
- minlength?: string;
- name?: string;
- placeholder?: string;
- readonly?: string;
- required?: string;
- rows?: string;
- wrap?: string;
- }
- interface HtmlTableHeaderCellTag extends HtmlTag {
- colspan?: string | number;
- rowspan?: string | number;
- headers?: string;
- scope?: string;
- }
- interface HtmlTimeTag extends HtmlTag {
- datetime?: string | Date;
- }
- interface HtmlTrackTag extends HtmlTag {
- default?: string;
- kind?: string;
- label?: string;
- src?: string;
- srclang?: string;
- }
- interface HtmlVideoTag extends HtmlTag {
- src?: string;
- poster?: string;
- autobuffer?: string;
- autoplay?: string;
- loop?: string;
- controls?: string;
- width?: string;
- height?: string;
- }
-}
-//# sourceMappingURL=element-types.d.ts.map
\ No newline at end of file
diff --git a/frontend/utils/events.d.ts b/frontend/utils/events.d.ts
deleted file mode 100644
index ef4ad00..0000000
--- a/frontend/utils/events.d.ts
+++ /dev/null
@@ -1,98 +0,0 @@
-declare namespace JSX {
- interface HtmlBodyTag {
- onafterprint?: string;
- onbeforeprint?: string;
- onbeforeonload?: string;
- onblur?: string;
- onerror?: string;
- onfocus?: string;
- onhaschange?: string;
- onload?: string;
- onmessage?: string;
- onoffline?: string;
- ononline?: string;
- onpagehide?: string;
- onpageshow?: string;
- onpopstate?: string;
- onredo?: string;
- onresize?: string;
- onstorage?: string;
- onundo?: string;
- onunload?: string;
- }
- interface HtmlTag {
- oncontextmenu?: string;
- onkeydown?: string;
- onkeypress?: string;
- onkeyup?: string;
- onclick?: AttributeValue;
- ondblclick?: string;
- ondrag?: string;
- ondragend?: string;
- ondragenter?: string;
- ondragleave?: string;
- ondragover?: string;
- ondragstart?: string;
- ondrop?: string;
- onmousedown?: string;
- onmousemove?: string;
- onmouseout?: string;
- onmouseover?: string;
- onmouseup?: string;
- onmousewheel?: string;
- onscroll?: string;
- }
- interface FormEvents {
- onblur?: string;
- onchange?: string;
- onfocus?: string;
- onformchange?: string;
- onforminput?: string;
- oninput?: string;
- oninvalid?: string;
- onselect?: string;
- onsubmit?: string;
- }
- interface HtmlInputTag extends FormEvents {
- }
- interface HtmlFieldSetTag extends FormEvents {
- }
- interface HtmlFormTag extends FormEvents {
- }
- interface MediaEvents {
- onabort?: string;
- oncanplay?: string;
- oncanplaythrough?: string;
- ondurationchange?: string;
- onemptied?: string;
- onended?: string;
- onerror?: AttributeValue;
- onloadeddata?: string;
- onloadedmetadata?: string;
- onloadstart?: string;
- onpause?: string;
- onplay?: string;
- onplaying?: string;
- onprogress?: string;
- onratechange?: string;
- onreadystatechange?: string;
- onseeked?: string;
- onseeking?: string;
- onstalled?: string;
- onsuspend?: string;
- ontimeupdate?: string;
- onvolumechange?: string;
- onwaiting?: string;
- }
- interface HtmlAudioTag extends MediaEvents {
- }
- interface HtmlEmbedTag extends MediaEvents {
- }
- interface HtmlImageTag extends MediaEvents {
- }
- interface HtmlObjectTag extends MediaEvents {
- }
- interface HtmlVideoTag extends MediaEvents {
- }
-}
-//# sourceMappingURL=events.d.ts.map
\ No newline at end of file
diff --git a/frontend/utils/intrinsic-elements.d.ts b/frontend/utils/intrinsic-elements.d.ts
deleted file mode 100644
index 0e66229..0000000
--- a/frontend/utils/intrinsic-elements.d.ts
+++ /dev/null
@@ -1,118 +0,0 @@
-declare namespace JSX {
- type Element = HTMLElement;
- interface IntrinsicElements {
- a: HtmlAnchorTag;
- abbr: HtmlTag;
- address: HtmlTag;
- area: HtmlAreaTag;
- article: HtmlTag;
- aside: HtmlTag;
- audio: HtmlAudioTag;
- b: HtmlTag;
- bb: HtmlBrowserButtonTag;
- base: BaseTag;
- bdi: HtmlTag;
- bdo: HtmlTag;
- blockquote: HtmlQuoteTag;
- body: HtmlBodyTag;
- br: HtmlTag;
- button: HtmlButtonTag;
- canvas: HtmlCanvasTag;
- caption: HtmlTag;
- cite: HtmlTag;
- code: HtmlTag;
- col: HtmlTableColTag;
- colgroup: HtmlTableColTag;
- commands: HtmlCommandTag;
- data: DataTag;
- datalist: HtmlDataListTag;
- dd: HtmlTag;
- del: HtmlModTag;
- details: HtmlDetailsTag;
- dfn: HtmlTag;
- div: HtmlTag;
- dl: HtmlTag;
- dt: HtmlTag;
- em: HtmlTag;
- embed: HtmlEmbedTag;
- fieldset: HtmlFieldSetTag;
- figcaption: HtmlTag;
- figure: HtmlTag;
- footer: HtmlTag;
- form: HtmlFormTag;
- h1: HtmlTag;
- h2: HtmlTag;
- h3: HtmlTag;
- h4: HtmlTag;
- h5: HtmlTag;
- h6: HtmlTag;
- head: HtmlTag;
- header: HtmlTag;
- hr: HtmlTag;
- html: HtmlHtmlTag;
- i: HtmlTag;
- iframe: HtmlIFrameTag;
- img: HtmlImageTag;
- input: HtmlInputTag;
- ins: HtmlModTag;
- kbd: HtmlTag;
- keygen: KeygenTag;
- label: HtmlLabelTag;
- legend: HtmlLegendTag;
- li: HtmlLITag;
- link: HtmlLinkTag;
- main: HtmlTag;
- map: HtmlMapTag;
- mark: HtmlTag;
- menu: HtmlMenuTag;
- meta: HtmlMetaTag;
- meter: HtmlMeterTag;
- nav: HtmlTag;
- noscript: HtmlTag;
- object: HtmlObjectTag;
- ol: HtmlOListTag;
- optgroup: HtmlOptgroupTag;
- option: HtmlOptionTag;
- output: HtmlOutputTag;
- p: HtmlTag;
- param: HtmlParamTag;
- pre: HtmlTag;
- progress: HtmlProgressTag;
- q: HtmlQuoteTag;
- rb: HtmlTag;
- rp: HtmlTag;
- rt: HtmlTag;
- rtc: HtmlTag;
- ruby: HtmlTag;
- s: HtmlTag;
- samp: HtmlTag;
- script: HtmlScriptTag;
- section: HtmlTag;
- select: HtmlSelectTag;
- small: HtmlTag;
- source: HtmlSourceTag;
- span: HtmlTag;
- strong: HtmlTag;
- style: HtmlStyleTag;
- sub: HtmlTag;
- sup: HtmlTag;
- table: HtmlTableTag;
- tbody: HtmlTag;
- td: HtmlTableDataCellTag;
- template: HtmlTag;
- textarea: HtmlTextAreaTag;
- tfoot: HtmlTableSectionTag;
- th: HtmlTableHeaderCellTag;
- thead: HtmlTableSectionTag;
- time: HtmlTimeTag;
- title: HtmlTag;
- tr: HtmlTableRowTag;
- track: HtmlTrackTag;
- u: HtmlTag;
- ul: HtmlTag;
- var: HtmlTag;
- video: HtmlVideoTag;
- wbr: HtmlTag;
- }
-}
-//# sourceMappingURL=intrinsic-elements.d.ts.map
\ No newline at end of file
diff --git a/hugo.toml b/hugo.toml
index 596850f..9e02b00 100644
--- a/hugo.toml
+++ b/hugo.toml
@@ -136,10 +136,10 @@ url = "about_me/"
#weight = 2
#url = "posts/"
-[[languages.en.menu.main]]
-name = "List"
-weight = 3
-url = "list/"
+#[[languages.en.menu.main]]
+#name = "List"
+#weight = 3
+#url = "list/"
[[languages.en.menu.main]]
name = "CV"
diff --git a/package.json b/package.json
deleted file mode 100644
index 952995f..0000000
--- a/package.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "name": "web",
- "version": "0.0.0",
- "private": true,
- "dependencies": {
- "@types/express": "^5.0.3",
- "@types/morgan": "^1.9.10",
- "express": "^5.1.0",
- "hbs": "^4.2.0",
- "morgan": "~1.10.1",
- "bun-types": "^1.2.22",
- "typescript": "^5.9.2"
- }
-}
\ No newline at end of file
diff --git a/static/assets/main/1_0/assets/WinBox/winbox.bundle.js b/static/1_0/assets/WinBox/winbox.bundle.js
similarity index 100%
rename from static/assets/main/1_0/assets/WinBox/winbox.bundle.js
rename to static/1_0/assets/WinBox/winbox.bundle.js
diff --git a/static/assets/main/1_0/assets/fontawesome/css/all.css b/static/1_0/assets/fontawesome/css/all.css
similarity index 100%
rename from static/assets/main/1_0/assets/fontawesome/css/all.css
rename to static/1_0/assets/fontawesome/css/all.css
diff --git a/static/assets/main/1_0/assets/fontawesome/webfonts/fa-solid-900.woff2 b/static/1_0/assets/fontawesome/webfonts/fa-solid-900.woff2
similarity index 100%
rename from static/assets/main/1_0/assets/fontawesome/webfonts/fa-solid-900.woff2
rename to static/1_0/assets/fontawesome/webfonts/fa-solid-900.woff2
diff --git a/static/assets/main/1_0/css/intro.css b/static/1_0/css/intro.css
similarity index 100%
rename from static/assets/main/1_0/css/intro.css
rename to static/1_0/css/intro.css
diff --git a/static/assets/main/1_0/css/styles.css b/static/1_0/css/styles.css
similarity index 100%
rename from static/assets/main/1_0/css/styles.css
rename to static/1_0/css/styles.css
diff --git a/backend/views/main/1_0.hbs b/static/1_0/index.html
similarity index 95%
rename from backend/views/main/1_0.hbs
rename to static/1_0/index.html
index 1e6694f..e3dd14c 100644
--- a/backend/views/main/1_0.hbs
+++ b/static/1_0/index.html
@@ -15,18 +15,15 @@
Nikola Petrov
-
-
-
-
-
+
+
+
+
+
-
-
-
Hi, I am Nikola Petrov
diff --git a/static/assets/main/1_0/js/main.js b/static/1_0/js/main.js
similarity index 100%
rename from static/assets/main/1_0/js/main.js
rename to static/1_0/js/main.js
diff --git a/static/assets/main/2_0/css/style.css b/static/2_0/css/style.css
similarity index 100%
rename from static/assets/main/2_0/css/style.css
rename to static/2_0/css/style.css
diff --git a/backend/views/main/2_0.hbs b/static/2_0/index.html
similarity index 50%
rename from backend/views/main/2_0.hbs
rename to static/2_0/index.html
index ba2ac41..b77531a 100644
--- a/backend/views/main/2_0.hbs
+++ b/static/2_0/index.html
@@ -1,369 +1,490 @@
-
-
-
-
-
-
-
-
- Nikola Petrov
-
-
-
-
-
-
-
-
-
-
-{{#with userData}}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- About
-
-
-
- Resume
-
-
-
-
- Portfolio
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{#each about_me}}
- {{this}}
- {{#unless @last}}
-
- {{/unless}}
- {{/each}}
-
-
-
-
-
-
-
-
- Interests
-
-
-
-
-
-
-
-
-
-
-
-
Backend programming
-
- Backend programming focuses on server-side development, handling data storage, processing, and
- business
- logic to support the functionality of web and mobile applications
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Embedded systems
-
-
- Embedded systems are specialized computing devices integrated into everyday products, performing
- dedicated functions with real-time constraints.
-
-
-
-
-
-
-
-
-
-
-
-
-
Application programming
-
- Application programming involves writing code to create software applications that perform specific
- tasks or functions.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{#each education}}
-
- {{title}}
- {{time}}
- {{des}}
-
- {{/each}}
-
-
-
-
-
-
-
-
-
- {{#each experience}}
-
- {{title}} [ {{company}} ]
- {{time}}
-
- {{des}}
-
-
- {{/each}}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-{{/with}}
-
+
+
+
+
+
+
+
+
+ Nikola Petrov
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ About
+
+
+
+ Resume
+
+
+
+
+ Portfolio
+
+
+
+
+
+
+
+
+
+
+
+
+
+ I am Nikola, currently pursuing my studies at the Faculty of Electrical Engineering and Computer Science (FERI) in Maribor. My academic journey is largely driven by my interest in application and web development. I find the process of creating functional and user-friendly digital solutions both challenging and rewarding. This field allows me to blend creativity with technical skills, which I find particularly engaging.
+
+ Recently, I have developed an interest in the game of Go. The strategic depth and complexity of the game have captivated my attention, providing a stimulating mental exercise. Additionally, I have started exploring photography. Capturing moments and expressing visual stories through a lens has become a newfound passion, offering a different kind of creative outlet that complements my technical pursuits.
+
+
+
+
+
+
+
+
+ Interests
+
+
+
+
+
+
+
+
+
+
+
+
Backend programming
+
+ Backend programming focuses on server-side development, handling data storage, processing, and
+ business
+ logic to support the functionality of web and mobile applications
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Embedded systems
+
+
+ Embedded systems are specialized computing devices integrated into everyday products, performing
+ dedicated functions with real-time constraints.
+
+
+
+
+
+
+
+
+
+
+
+
+
Application programming
+
+ Application programming involves writing code to create software applications that perform specific
+ tasks or functions.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (FERI) Faculty of Electrical Engineering and Computer Science, University of Maribor
+ 01/10/2021 - CURRENT
+ Graduate engineer of computer science and information technology.
+
+
+ (SSTS Siska) Secondary school of technical professions siska
+ 01/09/2016 - 07/07/2021
+ Electrotechnician.
+
+
+
+
+
+
+
+
+
+
+
+ HW Developer [ Spica International ]
+ 17/03/2025 - 01/08/2025
+
+ Worked on access menegment systems. Programed integrated devices, based on Buildroot using c++ and python web server.
+
+
+
+ Backend/Frontend [ RRC d.o.o ]
+ 01/09/2024 - 31/12/2024
+
+ Worked on goverment websites for collage enrolment and student dorm requests.
+
+
+
+ Developer [ RRC d.o.o ]
+ 18/03/2024 - 31/05/2024
+
+ Student practicum. Backend in java with frontend in ext JS and jQuery.
+
+
+
+ Developer/IT [ LightAct ]
+ 01/07/2022 - 01/09/2022
+
+ I helped maintaining data base, worked on the application (integrated a capture card and IP camera), assembled new server rack, installed new UTP/power connectors in the office.
+
+
+
+ Mentor [ Institute 404 ]
+ 08/06/2020 - 19/06/2020
+
+ I helped primary school children with their projects with soldering, laser cutting, and building.
+
+
+
+ Maintenance technician [ Hella Saturnos d.o.o. ]
+ 04/09/2018 - 18/01/2019
+
+ I maintained and repaired machines from plastic presses to personal stations.
+
+
+
+ Maintenance technician [ Best Western Premier Hotel Slon ]
+ 01/03/2018 - 04/05/2018
+
+ I helped with setting up the conference/event rooms. I helped customers and fixed problems like replacing light bulbs, wall sockets, hair-dryers.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/static/assets/main/2_0/js/script.js b/static/2_0/js/script.js
similarity index 100%
rename from static/assets/main/2_0/js/script.js
rename to static/2_0/js/script.js
diff --git a/static/images/projects/bitshift.jpeg b/static/2_0/projects/bitshift.jpeg
similarity index 100%
rename from static/images/projects/bitshift.jpeg
rename to static/2_0/projects/bitshift.jpeg
diff --git a/static/images/projects/list.jpeg b/static/2_0/projects/list.jpeg
similarity index 100%
rename from static/images/projects/list.jpeg
rename to static/2_0/projects/list.jpeg
diff --git a/static/images/projects/password_manager.jpeg b/static/2_0/projects/password_manager.jpeg
similarity index 100%
rename from static/images/projects/password_manager.jpeg
rename to static/2_0/projects/password_manager.jpeg
diff --git a/static/images/projects/projektna_naloga.jpeg b/static/2_0/projects/projektna_naloga.jpeg
similarity index 100%
rename from static/images/projects/projektna_naloga.jpeg
rename to static/2_0/projects/projektna_naloga.jpeg
diff --git a/static/images/projects/tetris.jpeg b/static/2_0/projects/tetris.jpeg
similarity index 100%
rename from static/images/projects/tetris.jpeg
rename to static/2_0/projects/tetris.jpeg
diff --git a/static/cv/index.html b/static/cv/index.html
new file mode 100644
index 0000000..27e926d
--- /dev/null
+++ b/static/cv/index.html
@@ -0,0 +1,272 @@
+
+
+
+
+
+
+
+
+ CV
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Nikola Petrov
+
Developer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Experience
+
+
+
+
+
+
+
+
+
HW Developer
+
Spica International
+
17/03/2025 - 01/08/2025
+
+ Worked on access menegment systems. Programed integrated devices, based on Buildroot using c++ and python web server.
+
+
+
+
+
+
+
+
+
+
Backend/Frontend
+
RRC d.o.o
+
01/09/2024 - 31/12/2024
+
+ Worked on goverment websites for collage enrolment and student dorm requests.
+
+
+
+
+
+
+
+
+
+
Developer
+
RRC d.o.o
+
18/03/2024 - 31/05/2024
+
+ Student practicum. Backend in java with frontend in ext JS and jQuery.
+
+
+
+
+
+
+
+
+
+
Developer/IT
+
LightAct
+
01/07/2022 - 01/09/2022
+
+ I helped maintaining data base, worked on the application (integrated a capture card and IP camera), assembled new server rack, installed new UTP/power connectors in the office.
+
+
+
+
+
+
+
+
+
+
Mentor
+
Institute 404
+
08/06/2020 - 19/06/2020
+
+ I helped primary school children with their projects with soldering, laser cutting, and building.
+
+
+
+
+
+
+
+
+
+
Maintenance technician
+
Hella Saturnos d.o.o.
+
04/09/2018 - 18/01/2019
+
+ I maintained and repaired machines from plastic presses to personal stations.
+
+
+
+
+
+
+
+
+
Maintenance technician
+
Best Western Premier Hotel Slon
+
01/03/2018 - 04/05/2018
+
+ I helped with setting up the conference/event rooms. I helped customers and fixed problems like replacing light bulbs, wall sockets, hair-dryers.
+
+
+
+
+
+
+
+
+ Education
+
+
+
+
+
+
+
+
+
+
Graduate engineer of computer science and information technology.
+ (FERI) Faculty of Electrical Engineering and Computer Science, University of Maribor
+ 01/10/2021 - CURRENT
+
+
+
+
+
+
+
+
Electrotechnician.
+ (SSTS Siska) Secondary school of technical professions siska
+ 01/09/2016 - 07/07/2021
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/static/assets/cv/javascripts/html2pdf.v0.9.3.bundle.min.js b/static/cv/javascripts/html2pdf.v0.9.3.bundle.min.js
similarity index 100%
rename from static/assets/cv/javascripts/html2pdf.v0.9.3.bundle.min.js
rename to static/cv/javascripts/html2pdf.v0.9.3.bundle.min.js
diff --git a/static/assets/cv/javascripts/main.js b/static/cv/javascripts/main.js
similarity index 100%
rename from static/assets/cv/javascripts/main.js
rename to static/cv/javascripts/main.js
diff --git a/static/assets/cv/stylesheets/layout.css b/static/cv/stylesheets/layout.css
similarity index 100%
rename from static/assets/cv/stylesheets/layout.css
rename to static/cv/stylesheets/layout.css
diff --git a/static/assets/cv/stylesheets/style.css b/static/cv/stylesheets/style.css
similarity index 100%
rename from static/assets/cv/stylesheets/style.css
rename to static/cv/stylesheets/style.css
diff --git a/static/images/no_poster.jpg b/static/images/no_poster.jpg
deleted file mode 100644
index 5befbc8..0000000
Binary files a/static/images/no_poster.jpg and /dev/null differ
diff --git a/static/images/projects/Advent_Of_Code_Logo.jpg b/static/images/projects/Advent_Of_Code_Logo.jpg
deleted file mode 100644
index 1c86ab0..0000000
Binary files a/static/images/projects/Advent_Of_Code_Logo.jpg and /dev/null differ
diff --git a/static/images/projects/games.jpeg b/static/images/projects/games.jpeg
deleted file mode 100644
index 8768c3d..0000000
Binary files a/static/images/projects/games.jpeg and /dev/null differ
diff --git a/static/images/projects/media_player.jpeg b/static/images/projects/media_player.jpeg
deleted file mode 100644
index 45b446a..0000000
Binary files a/static/images/projects/media_player.jpeg and /dev/null differ
diff --git a/tsconfig.json b/tsconfig.json
deleted file mode 100644
index 437d3b8..0000000
--- a/tsconfig.json
+++ /dev/null
@@ -1,34 +0,0 @@
-{
- "compilerOptions": {
- // Enable latest features
- "lib": [
- "ESNext",
- "DOM"
- ],
- "target": "ESNext",
- "module": "ESNext",
- "moduleDetection": "force",
- "jsx": "react",
- "jsxFactory": "elements.createElement",
- "allowJs": true,
- // Bundler mode
- "moduleResolution": "bundler",
- "allowImportingTsExtensions": true,
- "verbatimModuleSyntax": true,
- "noEmit": true,
- "resolveJsonModule": true,
- "esModuleInterop": true,
- // Best practices
- "strict": true,
- "skipLibCheck": true,
- "noFallthroughCasesInSwitch": true,
- // Some stricter flags (disabled by default)
- "noUnusedLocals": false,
- "noUnusedParameters": false,
- "noPropertyAccessFromIndexSignature": false,
- "types": [
- "bun-types"
- ],
- "baseUrl": "./"
- }
-}
\ No newline at end of file