Compare commits
10 Commits
76f638d818
...
041772e67a
Author | SHA1 | Date | |
---|---|---|---|
![]() |
041772e67a | ||
![]() |
362c411751 | ||
![]() |
0727d5f71a | ||
![]() |
ea3167981c | ||
![]() |
4667dfee78 | ||
![]() |
93241aae82 | ||
![]() |
f3df4b9913 | ||
![]() |
b64e7d8b71 | ||
![]() |
113b9f87f6 | ||
![]() |
0a8e3fc32a |
5
Readme.md
Normal file
5
Readme.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
## Build
|
||||||
|
```
|
||||||
|
bun run build.ts
|
||||||
|
bun run build_app
|
||||||
|
```
|
8
build.ts
8
build.ts
@ -1,7 +1,4 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function build() {
|
async function build() {
|
||||||
const minify = {
|
const minify = {
|
||||||
whitespace: true,
|
whitespace: true,
|
||||||
@ -10,15 +7,12 @@ async function build() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const sa = await Bun.build({
|
const sa = await Bun.build({
|
||||||
entrypoints: ["./frontend/cash/cash", "./frontend/list/list"],
|
entrypoints: ["./frontend/list/list"],
|
||||||
outdir: "./public/assets/build/",
|
outdir: "./public/assets/build/",
|
||||||
minify,
|
minify,
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log(sa);
|
console.log(sa);
|
||||||
|
|
||||||
const { stdout } = Bun.spawnSync({ cmd: ["bun", "build", "./app.ts", "--outfile=bundle.js", "--target=bun", "--minify"] });
|
|
||||||
console.log(stdout.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
build();
|
build();
|
||||||
|
@ -1,97 +0,0 @@
|
|||||||
import { type Request, type Response } from "express";
|
|
||||||
|
|
||||||
import cashTransactionModel from '../models/cashTransactionModel';
|
|
||||||
|
|
||||||
const types = ['ZAVRNITEV POS NAKUP', 'POS NAKUP', 'BA DVIG', 'priliv', 'SDD', 'SPLET/TEL NAKUP', 'PREDAVTORIZACIJE'];
|
|
||||||
|
|
||||||
// TODO hendel this PREDAVTORIZACIJA
|
|
||||||
|
|
||||||
export default {
|
|
||||||
|
|
||||||
list: async function (req: Request, res: Response) {
|
|
||||||
try {
|
|
||||||
var transactions;
|
|
||||||
const date = req.body.date;
|
|
||||||
|
|
||||||
if (date) {
|
|
||||||
const splitDate = date.split('-');
|
|
||||||
var year = splitDate[0];
|
|
||||||
var month = splitDate[1];
|
|
||||||
year = parseInt(year);
|
|
||||||
month = parseInt(month);
|
|
||||||
transactions = await cashTransactionModel.findWithPar(year, month);
|
|
||||||
} else {
|
|
||||||
transactions = await cashTransactionModel.find();
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = { transactions: transactions, types: types };
|
|
||||||
|
|
||||||
return res.json(data);
|
|
||||||
} catch (err) {
|
|
||||||
return res.status(500).json({
|
|
||||||
message: 'Error when getting transactions.',
|
|
||||||
error: err
|
|
||||||
});
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
create: async function (req: Request, res: Response) {
|
|
||||||
const rawString = req.body.messageBody;
|
|
||||||
|
|
||||||
if (rawString == "") return res.status(400).json({ message: "empty string" });
|
|
||||||
|
|
||||||
const transaction = {
|
|
||||||
rawMessage: rawString,
|
|
||||||
day: 0,
|
|
||||||
month: 0,
|
|
||||||
year: 0,
|
|
||||||
amount: 0,
|
|
||||||
type: -1,
|
|
||||||
company: "",
|
|
||||||
};
|
|
||||||
|
|
||||||
const datePattern = /(0[1-9]|[12][0-9]|3[01])\.(0[1-9]|1[0-2])\.(19|20)\d{2}/;
|
|
||||||
const amountPattern = /\d{1,3}(?:[.]\d{3})*(?:[.,]\d{2})(?=\sEUR)/;
|
|
||||||
const companyPattern1 = /(?<=(UR,|\sod)\s).*?(?=\s(na\s|za\s|Inf))/;
|
|
||||||
|
|
||||||
for (var i = 0; i < types.length; i++) {
|
|
||||||
if (rawString.includes(types[i])) {
|
|
||||||
transaction.type = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transaction.type != -1) {
|
|
||||||
const amountMatch = rawString.match(amountPattern);
|
|
||||||
if (amountMatch) {
|
|
||||||
const amount = amountMatch[0].replace('.', '').replace(',', '.');
|
|
||||||
transaction.amount = parseFloat(amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
const companyMatch1 = rawString.match(companyPattern1);
|
|
||||||
if (companyMatch1) transaction.company = companyMatch1[0];
|
|
||||||
|
|
||||||
const dateMatch = rawString.match(datePattern);
|
|
||||||
if (dateMatch) {
|
|
||||||
const date = dateMatch[0].split('.');
|
|
||||||
transaction.day = date[0];
|
|
||||||
transaction.month = date[1];
|
|
||||||
transaction.year = date[2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const trans = await cashTransactionModel.save(transaction.rawMessage, transaction.day, transaction.month, transaction.year, transaction.amount, transaction.type, transaction.company);
|
|
||||||
if (trans) {
|
|
||||||
return res.status(201).json(trans);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return res.status(400).json({ message: "something went wrong" });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
delete: async function (req: Request, res: Response) {
|
|
||||||
cashTransactionModel.findOneAndDelete(-1)
|
|
||||||
.then(data => {
|
|
||||||
res.status(201).json({ message: "OK" });
|
|
||||||
});
|
|
||||||
},
|
|
||||||
};
|
|
@ -1,116 +0,0 @@
|
|||||||
import Chart from 'chart.js/auto'
|
|
||||||
import * as elements from "../elementcreate";
|
|
||||||
|
|
||||||
interface Transaction {
|
|
||||||
day: number;
|
|
||||||
month: number;
|
|
||||||
year: number;
|
|
||||||
amount: number;
|
|
||||||
type: number;
|
|
||||||
company: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
var types: Array<string> = [];
|
|
||||||
|
|
||||||
async function submitMedia(event: SubmitEvent) {
|
|
||||||
event.preventDefault();
|
|
||||||
const pass = document.getElementById("pass") as HTMLInputElement | null;
|
|
||||||
const date = document.getElementById("date") as HTMLInputElement | null;
|
|
||||||
if (!pass || !date) return;
|
|
||||||
|
|
||||||
if (pass.value == "") return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = await fetch('/api/cash/list', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ pass: pass.value, date: date.value }),
|
|
||||||
})
|
|
||||||
|
|
||||||
const data: { types: string[]; transactions: Array<Transaction>; } = await result.json();
|
|
||||||
types = data.types;
|
|
||||||
|
|
||||||
renderData(data.transactions);
|
|
||||||
renderChart(data.transactions);
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
pass.value = "";
|
|
||||||
};
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', async () => {
|
|
||||||
document.getElementById("myform")?.addEventListener("submit", submitMedia);
|
|
||||||
});
|
|
||||||
|
|
||||||
function renderChart(transactions: Array<Transaction>) {
|
|
||||||
|
|
||||||
const cash = [];
|
|
||||||
|
|
||||||
for (let index = 0; index < 7; index++) {
|
|
||||||
cash.push(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let index = 0; index < transactions.length; index++) {
|
|
||||||
const element = transactions[index];
|
|
||||||
|
|
||||||
const type = element.type;
|
|
||||||
const amount = element.amount;
|
|
||||||
if (type == -1) continue;
|
|
||||||
cash[type] += amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
var data = {
|
|
||||||
labels: types,
|
|
||||||
datasets: [{
|
|
||||||
label: '',
|
|
||||||
data: cash
|
|
||||||
}]
|
|
||||||
};
|
|
||||||
|
|
||||||
var ctx = document.getElementById('acquisitions') as HTMLCanvasElement | null;
|
|
||||||
if (ctx == null) return;
|
|
||||||
new Chart(
|
|
||||||
ctx,
|
|
||||||
{
|
|
||||||
type: 'pie',
|
|
||||||
data: data,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
function getTypeName(type: number) {
|
|
||||||
if (type == -1) return "UNKNOWN";
|
|
||||||
return types[type];
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderData(transactions: Array<Transaction>) {
|
|
||||||
var tbody = document.getElementById("tbody");
|
|
||||||
if (tbody == null) return;
|
|
||||||
tbody.innerHTML = "";
|
|
||||||
|
|
||||||
transactions
|
|
||||||
.sort((a, b) => a.day - b.day)
|
|
||||||
.sort((a, b) => a.month - b.month)
|
|
||||||
.sort((a, b) => a.year - b.year);
|
|
||||||
|
|
||||||
for (let index = 0; index < transactions.length; index++) {
|
|
||||||
const element = transactions[index];
|
|
||||||
|
|
||||||
var row =
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{index}</th>
|
|
||||||
<td>{element.day}</td>
|
|
||||||
<td>{element.month}</td>
|
|
||||||
<td>{element.year}</td>
|
|
||||||
<td>{element.amount}</td>
|
|
||||||
<td>{getTypeName(element.type)}</td>
|
|
||||||
<td>{element.company}</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
tbody.appendChild(row);
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,5 +1,5 @@
|
|||||||
import type { Attributes } from "../elementcreate";
|
import type { Attributes } from "frontend/elementcreate";
|
||||||
import * as elements from "../elementcreate";
|
import * as elements from "frontend/elementcreate";
|
||||||
|
|
||||||
function MediaElement(attributes: Attributes, contents: string[]) {
|
function MediaElement(attributes: Attributes, contents: string[]) {
|
||||||
const ret = <div class="col media-element" id={attributes['id']}>
|
const ret = <div class="col media-element" id={attributes['id']}>
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
import { MediaElement, MyHeader, MediaContainer } from "./elements";
|
import { MediaElement, MyHeader, MediaContainer } from "frontend/list/elements";
|
||||||
import { splitByTitle, splitByYear } from "./functions";
|
import { splitByTitle, splitByYear } from "frontend/list/functions";
|
||||||
|
|
||||||
import * as elements from "../elementcreate";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import * as elements from "frontend/elementcreate";
|
||||||
|
|
||||||
var sortType = 0;
|
var sortType = 0;
|
||||||
var listType = 0;
|
var listType = 0;
|
||||||
@ -36,6 +33,16 @@ function getLink(): string {
|
|||||||
return "/api/media/movies";
|
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) {
|
function submitMedia(event: SubmitEvent) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
@ -62,21 +69,7 @@ function submitMedia(event: SubmitEvent) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const movie: Movie = await response.json();
|
await reload();
|
||||||
var letter = movie.title[0].toUpperCase();
|
|
||||||
if (!isNaN(parseInt(letter))) letter = "#";
|
|
||||||
|
|
||||||
const mediaElement = <MediaElement webImg={movie.webImg} title={movie.title} released={movie.released} id={movie.code} fun={removeMedia} imageError={onImgError} />;
|
|
||||||
|
|
||||||
const container = document.getElementById(letter);
|
|
||||||
if (!container) {
|
|
||||||
root?.appendChild(<MyHeader title={letter} />);
|
|
||||||
root?.appendChild(<MediaContainer id={letter}>{mediaElement}</MediaContainer>);
|
|
||||||
return
|
|
||||||
};
|
|
||||||
container.appendChild(mediaElement);
|
|
||||||
|
|
||||||
movieElements.push(mediaElement);
|
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
@ -122,9 +115,6 @@ function loadState() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number} type
|
|
||||||
*/
|
|
||||||
function changeType(type: number) {
|
function changeType(type: number) {
|
||||||
listType = type;
|
listType = type;
|
||||||
loadPage();
|
loadPage();
|
||||||
@ -143,9 +133,6 @@ function changeType(type: number) {
|
|||||||
history.replaceState({}, '', window.location.pathname + '?' + searchParams.toString());
|
history.replaceState({}, '', window.location.pathname + '?' + searchParams.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number} type
|
|
||||||
*/
|
|
||||||
function changeSort(type: number) {
|
function changeSort(type: number) {
|
||||||
sortType = type;
|
sortType = type;
|
||||||
loadPage();
|
loadPage();
|
||||||
@ -216,13 +203,7 @@ async function loadPage() {
|
|||||||
listButtons.forEach(button => button?.classList.remove("active"));
|
listButtons.forEach(button => button?.classList.remove("active"));
|
||||||
listButtons[listType]?.classList.add("active");
|
listButtons[listType]?.classList.add("active");
|
||||||
|
|
||||||
try {
|
await reload();
|
||||||
const response = await fetch(getLink());
|
|
||||||
const movies = await response.json();
|
|
||||||
renderMedias(movies);
|
|
||||||
} catch (err) {
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -270,6 +251,7 @@ function renderMedias(unsorted_movies: Array<Movie>) {
|
|||||||
if (!root) return;
|
if (!root) return;
|
||||||
|
|
||||||
root.innerHTML = "";
|
root.innerHTML = "";
|
||||||
|
movieElements = [];
|
||||||
|
|
||||||
const splitMovies = splitBySort(unsorted_movies);
|
const splitMovies = splitBySort(unsorted_movies);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { type NextFunction, type Request, type Response } from "express";
|
import { type NextFunction, type Request, type Response } from "express";
|
||||||
import userModel, { values } from '../models/userModel';
|
import userModel, { values } from 'models/userModel';
|
||||||
|
|
||||||
async function checkAuthenticated(req: Request, res: Response, next: NextFunction) {
|
async function checkAuthenticated(req: Request, res: Response, next: NextFunction) {
|
||||||
const pass = req.body.pass;
|
const pass = req.body.pass;
|
||||||
|
@ -1,69 +0,0 @@
|
|||||||
import { type ResultSetHeader, type RowDataPacket, type QueryOptions } from "mysql2"
|
|
||||||
import pool from '../miscellaneous/db'
|
|
||||||
|
|
||||||
interface CashTransaction extends RowDataPacket {
|
|
||||||
id?: number;
|
|
||||||
rawMessage?: string;
|
|
||||||
day?: number;
|
|
||||||
month?: number;
|
|
||||||
year?: number;
|
|
||||||
amount?: number;
|
|
||||||
type?: number;
|
|
||||||
company?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function save(rawMessage: string, day: number, month: number, year: number, amount: number, type: number, company: string): Promise<number> {
|
|
||||||
try {
|
|
||||||
const options: QueryOptions = {
|
|
||||||
sql: "INSERT INTO bankCardTransaction (raw, day, month, year, amount, type, company) VALUES (?,?,?,?,?,?,?)",
|
|
||||||
values: [rawMessage, day, month, year, amount, type, company]
|
|
||||||
};
|
|
||||||
const [result, fields] = await pool.query<ResultSetHeader>(options);
|
|
||||||
return result.affectedRows;
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function find(): Promise<CashTransaction[]> {
|
|
||||||
try {
|
|
||||||
const [rows, fields] = await pool.query<CashTransaction[]>("SELECT * FROM bankCardTransaction;");
|
|
||||||
return rows;
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
async function findWithPar(month: number, year: number): Promise<CashTransaction[]> {
|
|
||||||
try {
|
|
||||||
const [rows, fields] = await pool.query<CashTransaction[]>("SELECT * FROM bankCardTransaction;");
|
|
||||||
return rows;
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
async function findOneAndDelete(type: number): Promise<number> {
|
|
||||||
try {
|
|
||||||
const [result, fields] = await pool.query<ResultSetHeader>("DELETE FROM bankCardTransaction WHERE type = ?;", [type]);
|
|
||||||
return result.affectedRows;
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default {
|
|
||||||
find,
|
|
||||||
findWithPar,
|
|
||||||
save,
|
|
||||||
findOneAndDelete
|
|
||||||
};
|
|
@ -1,5 +1,5 @@
|
|||||||
import { type ResultSetHeader, type RowDataPacket, type QueryOptions } from "mysql2"
|
import { type ResultSetHeader, type RowDataPacket, type QueryOptions } from "mysql2"
|
||||||
import pool from '../miscellaneous/db'
|
import pool from 'miscellaneous/db'
|
||||||
|
|
||||||
|
|
||||||
interface Media extends RowDataPacket {
|
interface Media extends RowDataPacket {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { type ResultSetHeader, type RowDataPacket } from "mysql2"
|
import { type ResultSetHeader, type RowDataPacket } from "mysql2"
|
||||||
import pool from '../miscellaneous/db'
|
import pool from 'miscellaneous/db'
|
||||||
|
|
||||||
interface UserD extends RowDataPacket {
|
interface UserD extends RowDataPacket {
|
||||||
name?: string;
|
name?: string;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "bun ./app.ts",
|
"start": "bun ./app.ts",
|
||||||
"build": "bun build ./app.ts --outfile=bundle.js --target=bun"
|
"build_app": "bun build ./app.ts --outfile=bundle.js --target=bun"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/express": "^4.17.21",
|
"@types/express": "^4.17.21",
|
||||||
|
Binary file not shown.
@ -7,19 +7,23 @@
|
|||||||
"living_location": "Ljubljana, Slovenia",
|
"living_location": "Ljubljana, Slovenia",
|
||||||
"web_link": "https://petrovv.com",
|
"web_link": "https://petrovv.com",
|
||||||
"git_link": "https://git.petrovv.com",
|
"git_link": "https://git.petrovv.com",
|
||||||
"email": "nikolape7@gmail.com",
|
"email": "nikola@petrovv.com",
|
||||||
|
"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": [
|
"project": [
|
||||||
{
|
{
|
||||||
"img": "/images/projects/Advent_Of_Code_Logo.jpg",
|
"img": "/images/projects/Advent_Of_Code_Logo.jpg",
|
||||||
"title": "Advent of code",
|
"title": "Advent of code",
|
||||||
"des": "My solutions for AOC",
|
"des": "My solutions for AOC",
|
||||||
"link": "https://gitlab.com/homep/advent_of_code"
|
"link": "https://git.petrovv.com/home/advent_of_code"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"img": "/images/projects/password_manager.jpeg",
|
"img": "/images/projects/password_manager.jpeg",
|
||||||
"title": "Password manager",
|
"title": "Password manager",
|
||||||
"des": "CLI app",
|
"des": "CLI app",
|
||||||
"link": "https://gitlab.com/homep/password_manager"
|
"link": "https://git.petrovv.com/home/password_manager"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"img": "/images/projects/list.jpeg",
|
"img": "/images/projects/list.jpeg",
|
||||||
@ -31,40 +35,46 @@
|
|||||||
"img": "/images/logo.png",
|
"img": "/images/logo.png",
|
||||||
"title": "Server",
|
"title": "Server",
|
||||||
"des": "Everything running on my server",
|
"des": "Everything running on my server",
|
||||||
"link": "https://gitlab.com/homep/server"
|
"link": "https://git.petrovv.com/home/server"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"img": "/images/projects/projektna_naloga.jpeg",
|
"img": "/images/projects/projektna_naloga.jpeg",
|
||||||
"title": "Highway Tracker",
|
"title": "Highway Tracker",
|
||||||
"des": "School project",
|
"des": "School project",
|
||||||
"link": "https://gitlab.com/school221/projektna_naloga"
|
"link": "https://git.petrovv.com/school/projektna_naloga"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"img": "/images/projects/media_player.jpeg",
|
"img": "/images/projects/media_player.jpeg",
|
||||||
"title": "Media player",
|
"title": "Media player",
|
||||||
"des": "WPF",
|
"des": "WPF",
|
||||||
"link": "https://gitlab.com/school221/semester_3/uporabniski_vmesniki"
|
"link": "https://git.petrovv.com/school/semester_3/uporabniski_vmesniki"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"img": "/images/projects/bitshift.jpeg",
|
"img": "/images/projects/bitshift.jpeg",
|
||||||
"title": "BitShifters",
|
"title": "BitShifters",
|
||||||
"des": "unity",
|
"des": "unity",
|
||||||
"link": "https://gitlab.com/school221/semester_4/razvoj_programskih_sistemov/bitshifters"
|
"link": "https://git.petrovv.com/school/semester_4/razvoj_programskih_sistemov/bitshifters"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"img": "/images/projects/tetris.jpeg",
|
"img": "/images/projects/tetris.jpeg",
|
||||||
"title": "Tetris",
|
"title": "Tetris",
|
||||||
"des": "WPF",
|
"des": "WPF",
|
||||||
"link": "https://gitlab.com/school221/semester_4/razvoj_programskih_sistemov/tetrisrps"
|
"link": "https://git.petrovv.com/school/semester_4/razvoj_programskih_sistemov/tetrisrps"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"img": "/images/projects/games.jpeg",
|
"img": "/images/projects/games.jpeg",
|
||||||
"title": "Games",
|
"title": "Games",
|
||||||
"des": "java",
|
"des": "java",
|
||||||
"link": "https://gitlab.com/school221/semester_5/uvod_v_razvoj_racunalniskih_iger"
|
"link": "https://git.petrovv.com/school/semester_5/uvod_v_razvoj_racunalniskih_iger"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"experience": [
|
"experience": [
|
||||||
|
{
|
||||||
|
"title": "Backend/Frontend",
|
||||||
|
"company": "RRC d.o.o",
|
||||||
|
"time": "01/09/2024 - CURRENT",
|
||||||
|
"des": "Backend in java with frontend in ext JS and jQuery"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"title": "Developer",
|
"title": "Developer",
|
||||||
"company": "RRC d.o.o",
|
"company": "RRC d.o.o",
|
@ -1,12 +1,10 @@
|
|||||||
import express, { type Request, type Response } from "express";
|
import express, { type Request, type Response } from "express";
|
||||||
import checkAuthenticated from '../../miscellaneous/checkAuthenticated';
|
import checkAuthenticated from 'miscellaneous/checkAuthenticated';
|
||||||
import mediaRouter from './mediaRouter';
|
import mediaRouter from 'routes/api/mediaRouter';
|
||||||
import cashTransactionRouter from './cashTransactionRouter';
|
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
router.use('/media', mediaRouter);
|
router.use('/media', mediaRouter);
|
||||||
router.use('/cash', checkAuthenticated, cashTransactionRouter);
|
|
||||||
|
|
||||||
router.get('/', function (req: Request, res: Response) {
|
router.get('/', function (req: Request, res: Response) {
|
||||||
res.status(200).json({ message: 'API is working' });
|
res.status(200).json({ message: 'API is working' });
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
import express from "express";
|
|
||||||
import cashTransaction from '../../controllers/cashTransactionController';
|
|
||||||
|
|
||||||
const router = express.Router();
|
|
||||||
|
|
||||||
router.post('/list', cashTransaction.list);
|
|
||||||
|
|
||||||
router.post('/', cashTransaction.create);
|
|
||||||
|
|
||||||
router.delete('/', cashTransaction.delete);
|
|
||||||
|
|
||||||
export default router;
|
|
@ -1,14 +1,11 @@
|
|||||||
import express, { type Request, type Response } from "express";
|
import express, { type Request, type Response } from "express";
|
||||||
import userData from './userKnowledge.json';
|
import userData from 'public/userKnowledge.json';
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
/* GET home page. */
|
/* GET home page. */
|
||||||
router.get('/', function (req: Request, res: Response) {
|
router.get('/', function (req: Request, res: Response) {
|
||||||
const project = userData.project;
|
res.render('main/2_0', { userData });
|
||||||
const experience = userData.experience;
|
|
||||||
const education = userData.education;
|
|
||||||
res.render('main/2_0', { project, experience, education });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/cv', function (req: Request, res: Response) {
|
router.get('/cv', function (req: Request, res: Response) {
|
||||||
@ -19,18 +16,10 @@ router.get('/old', function (req: Request, res: Response) {
|
|||||||
res.render('main/1_0');
|
res.render('main/1_0');
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/mail', function (req: Request, res: Response) {
|
|
||||||
res.redirect('https://privateemail.com/');
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get('/list', function (req: Request, res: Response) {
|
router.get('/list', function (req: Request, res: Response) {
|
||||||
res.render('list');
|
res.render('list');
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/cash', function (req: Request, res: Response) {
|
|
||||||
res.render('cash');
|
|
||||||
});
|
|
||||||
|
|
||||||
//import userRouter from './user';
|
//import userRouter from './user';
|
||||||
//router.use('/user', userRouter);
|
//router.use('/user', userRouter);
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import express, { type Request, type Response } from "express";
|
import express, { type Request, type Response } from "express";
|
||||||
import userController from '../controllers/userController';
|
import userController from 'controllers/userController';
|
||||||
import checkAuthenticated from '../miscellaneous/checkAuthenticated';
|
import checkAuthenticated from 'miscellaneous/checkAuthenticated';
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
DBIP=
|
DBIP=''
|
||||||
DBPort=
|
DBPort=
|
||||||
DBUser=
|
DBUser=''
|
||||||
DBPassword=
|
DBPassword=''
|
||||||
DBDatabase=
|
DBDatabase=''
|
@ -28,6 +28,7 @@
|
|||||||
"noPropertyAccessFromIndexSignature": false,
|
"noPropertyAccessFromIndexSignature": false,
|
||||||
"types": [
|
"types": [
|
||||||
"bun-types"
|
"bun-types"
|
||||||
]
|
],
|
||||||
|
"baseUrl": "./"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,68 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en" data-bs-theme="dark">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<link rel="shortcut icon" href="images/logo.ico" type="image/x-icon">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"
|
|
||||||
integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"
|
|
||||||
integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL"
|
|
||||||
crossorigin="anonymous"></script>
|
|
||||||
|
|
||||||
<title>Cash</title>
|
|
||||||
<script type="module" src="/assets/build/cash/cash.js"></script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<header>
|
|
||||||
<nav class="navbar navbar-expand-md navbar-dark bg-dark">
|
|
||||||
<div class="container-fluid">
|
|
||||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
|
|
||||||
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
|
||||||
<span class="navbar-toggler-icon"></span>
|
|
||||||
</button>
|
|
||||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
|
||||||
<form class="d-flex" action="" id="myform">
|
|
||||||
<input class="form-control me-2" type="date" name="date" id="date" placeholder="date">
|
|
||||||
<input class="form-control me-2" type="password" name="password" id="pass" placeholder="password">
|
|
||||||
<input class="btn btn-outline-success" type="submit" value="Submit">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<main class="bg-body-tertiary pt-5 pb-5">
|
|
||||||
<div class="container position-relative">
|
|
||||||
<table class="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">#</th>
|
|
||||||
<th scope="col">Day</th>
|
|
||||||
<th scope="col">Month</th>
|
|
||||||
<th scope="col">Year</th>
|
|
||||||
<th scope="col">Amount</th>
|
|
||||||
<th scope="col">Type</th>
|
|
||||||
<th scope="col">Company</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id="tbody">
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<div class="row">
|
|
||||||
<div class="w-50 mx-auto"><canvas id="acquisitions"></canvas></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -17,6 +17,8 @@
|
|||||||
<script defer nomodule src="https://unpkg.com/ionicons@5.5.2/dist/ionicons/ionicons.js"></script>
|
<script defer nomodule src="https://unpkg.com/ionicons@5.5.2/dist/ionicons/ionicons.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
{{#with userData}}
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
<aside class="sidebar" data-sidebar>
|
<aside class="sidebar" data-sidebar>
|
||||||
@ -26,9 +28,9 @@
|
|||||||
</figure>
|
</figure>
|
||||||
|
|
||||||
<div class="info-content">
|
<div class="info-content">
|
||||||
<h1 class="name" title="Nikola Petrov">Nikola Petrov</h1>
|
<h1 class="name" title="Nikola Petrov">{{first_name}} {{last_name}}</h1>
|
||||||
|
|
||||||
<p class="title">RIT Student</p>
|
<p class="title">{{occupation}}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="info_more-btn" data-sidebar-btn>
|
<button class="info_more-btn" data-sidebar-btn>
|
||||||
@ -54,7 +56,7 @@
|
|||||||
<div class="contact-info">
|
<div class="contact-info">
|
||||||
<p class="contact-title">Email</p>
|
<p class="contact-title">Email</p>
|
||||||
|
|
||||||
<a href="mailto:nikola@petrov.nexus" class="contact-link">nikolape7@gmail.com</a>
|
<a href="mailto:{{email}}" class="contact-link">{{email}}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@ -68,7 +70,7 @@
|
|||||||
<div class="contact-info">
|
<div class="contact-info">
|
||||||
<p class="contact-title">Phone</p>
|
<p class="contact-title">Phone</p>
|
||||||
|
|
||||||
<a href="tel:0038670749506" class="contact-link">070749506</a>
|
<a href="tel:{{phone_number}}" class="contact-link">{{phone_number}}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@ -82,7 +84,7 @@
|
|||||||
<div class="contact-info">
|
<div class="contact-info">
|
||||||
<p class="contact-title">Birthday</p>
|
<p class="contact-title">Birthday</p>
|
||||||
|
|
||||||
<time datetime="2000-11-01">November, 2000</time>
|
<time datetime="2000-11-01">{{birth}}</time>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@ -108,7 +110,7 @@
|
|||||||
<ul class="social-list">
|
<ul class="social-list">
|
||||||
|
|
||||||
<li class="social-item">
|
<li class="social-item">
|
||||||
<a href="https://gitlab.com/nikolape7" title="GitLab" class="social-link">
|
<a href="{{git_link}}" title="GitLab" class="social-link">
|
||||||
<ion-icon name="logo-gitlab"></ion-icon>
|
<ion-icon name="logo-gitlab"></ion-icon>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@ -178,18 +180,12 @@
|
|||||||
|
|
||||||
<section class="about-text">
|
<section class="about-text">
|
||||||
<p>
|
<p>
|
||||||
I am currently an RIT student at FERI in Maribor and come from the beautiful city of Ljubljana.
|
{{#each about_me}}
|
||||||
What really excites me is the opportunity to build systems that have a direct and positive impact on
|
{{this}}
|
||||||
people's
|
{{#unless @last}}
|
||||||
lives.
|
</br>
|
||||||
I find great satisfaction in using my skills to create practical solutions that address real-world
|
{{/unless}}
|
||||||
challenges.
|
{{/each}}
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
I am excited by the potential of my work and the opportunities that lie ahead.
|
|
||||||
With my dedication and expertise, I am determined to contribute to the development of solutions that enhance
|
|
||||||
the people's experiences and make a positive difference in the world.
|
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@ -368,4 +364,6 @@
|
|||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
{{/with}}
|
||||||
|
|
||||||
</html>
|
</html>
|
Loading…
x
Reference in New Issue
Block a user