add frontend
This commit is contained in:
63
frontend/static/js/index.js
Normal file
63
frontend/static/js/index.js
Normal file
@ -0,0 +1,63 @@
|
||||
import Dashboard from "./views/Dashboard.js";
|
||||
import Posts from "./views/Posts.js";
|
||||
import PostView from "./views/PostView.js";
|
||||
import Settings from "./views/Settings.js";
|
||||
|
||||
const pathToRegex = path => new RegExp("^" + path.replace(/\//g, "\\/").replace(/:\w+/g, "(.+)") + "$");
|
||||
|
||||
const getParams = match => {
|
||||
const values = match.result.slice(1);
|
||||
const keys = Array.from(match.route.path.matchAll(/:(\w+)/g)).map(result => result[1]);
|
||||
|
||||
return Object.fromEntries(keys.map((key, i) => {
|
||||
return [key, values[i]];
|
||||
}));
|
||||
};
|
||||
|
||||
const navigateTo = url => {
|
||||
history.pushState(null, null, url);
|
||||
router();
|
||||
};
|
||||
|
||||
const router = async () => {
|
||||
const routes = [
|
||||
{ path: "/", view: Dashboard },
|
||||
{ path: "/posts", view: Posts },
|
||||
{ path: "/posts/:id", view: PostView },
|
||||
{ path: "/settings", view: Settings }
|
||||
];
|
||||
|
||||
// Test each route for potential match
|
||||
const potentialMatches = routes.map(route => {
|
||||
return {
|
||||
route: route,
|
||||
result: location.pathname.match(pathToRegex(route.path))
|
||||
};
|
||||
});
|
||||
|
||||
let match = potentialMatches.find(potentialMatch => potentialMatch.result !== null);
|
||||
|
||||
if (!match) {
|
||||
match = {
|
||||
route: routes[0],
|
||||
result: [location.pathname]
|
||||
};
|
||||
}
|
||||
|
||||
const view = new match.route.view(getParams(match));
|
||||
|
||||
document.querySelector("#app").innerHTML = await view.getHtml();
|
||||
};
|
||||
|
||||
window.addEventListener("popstate", router);
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
document.body.addEventListener("click", e => {
|
||||
if (e.target.matches("[data-link]")) {
|
||||
e.preventDefault();
|
||||
navigateTo(e.target.href);
|
||||
}
|
||||
});
|
||||
|
||||
router();
|
||||
});
|
13
frontend/static/js/views/AbstractView.js
Normal file
13
frontend/static/js/views/AbstractView.js
Normal file
@ -0,0 +1,13 @@
|
||||
export default class {
|
||||
constructor(params) {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
setTitle(title) {
|
||||
document.title = title;
|
||||
}
|
||||
|
||||
async getHtml() {
|
||||
return "";
|
||||
}
|
||||
}
|
20
frontend/static/js/views/Dashboard.js
Normal file
20
frontend/static/js/views/Dashboard.js
Normal file
@ -0,0 +1,20 @@
|
||||
import AbstractView from "./AbstractView.js";
|
||||
|
||||
export default class extends AbstractView {
|
||||
constructor(params) {
|
||||
super(params);
|
||||
this.setTitle("Dashboard");
|
||||
}
|
||||
|
||||
async getHtml() {
|
||||
return `
|
||||
<h1>Welcome back, Dom</h1>
|
||||
<p>
|
||||
Fugiat voluptate et nisi Lorem cillum anim sit do eiusmod occaecat irure do. Reprehenderit anim fugiat sint exercitation consequat. Sit anim laborum sit amet Lorem adipisicing ullamco duis. Anim in do magna ea pariatur et.
|
||||
</p>
|
||||
<p>
|
||||
<a href="/posts" data-link>View recent posts</a>.
|
||||
</p>
|
||||
`;
|
||||
}
|
||||
}
|
16
frontend/static/js/views/PostView.js
Normal file
16
frontend/static/js/views/PostView.js
Normal file
@ -0,0 +1,16 @@
|
||||
import AbstractView from "./AbstractView.js";
|
||||
|
||||
export default class extends AbstractView {
|
||||
constructor(params) {
|
||||
super(params);
|
||||
this.postId = params.id;
|
||||
this.setTitle("Viewing Post");
|
||||
}
|
||||
|
||||
async getHtml() {
|
||||
return `
|
||||
<h1>Post</h1>
|
||||
<p>You are viewing post #${this.postId}.</p>
|
||||
`;
|
||||
}
|
||||
}
|
15
frontend/static/js/views/Posts.js
Normal file
15
frontend/static/js/views/Posts.js
Normal file
@ -0,0 +1,15 @@
|
||||
import AbstractView from "./AbstractView.js";
|
||||
|
||||
export default class extends AbstractView {
|
||||
constructor(params) {
|
||||
super(params);
|
||||
this.setTitle("Posts");
|
||||
}
|
||||
|
||||
async getHtml() {
|
||||
return `
|
||||
<h1>Posts</h1>
|
||||
<p>You are viewing the posts!</p>
|
||||
`;
|
||||
}
|
||||
}
|
15
frontend/static/js/views/Settings.js
Normal file
15
frontend/static/js/views/Settings.js
Normal file
@ -0,0 +1,15 @@
|
||||
import AbstractView from "./AbstractView.js";
|
||||
|
||||
export default class extends AbstractView {
|
||||
constructor(params) {
|
||||
super(params);
|
||||
this.setTitle("Settings");
|
||||
}
|
||||
|
||||
async getHtml() {
|
||||
return `
|
||||
<h1>Settings</h1>
|
||||
<p>Manage your privacy and configuration.</p>
|
||||
`;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user