Merge branch 'julius-dev' of Software_Engineering_I/greenvironment-server into max-dev
commit
3fab56f340
@ -1,248 +0,0 @@
|
|||||||
import {Runtime} from "inspector";
|
|
||||||
import {Pool} from "pg";
|
|
||||||
import globals from "./globals";
|
|
||||||
import {QueryHelper} from "./QueryHelper";
|
|
||||||
|
|
||||||
const config = globals.config;
|
|
||||||
const tableCreationFile = __dirname + "/../sql/create-tables.sql";
|
|
||||||
const dbClient: Pool = new Pool({
|
|
||||||
database: config.database.database,
|
|
||||||
host: config.database.host,
|
|
||||||
password: config.database.password,
|
|
||||||
port: config.database.port,
|
|
||||||
user: config.database.user,
|
|
||||||
});
|
|
||||||
const queryHelper = new QueryHelper(dbClient, tableCreationFile);
|
|
||||||
|
|
||||||
export class DTO {
|
|
||||||
private queryHelper: QueryHelper;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.queryHelper = queryHelper;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes everything that needs to be initialized asynchronous.
|
|
||||||
*/
|
|
||||||
public async init() {
|
|
||||||
await this.queryHelper.createTables();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the user by id
|
|
||||||
* @param userId
|
|
||||||
*/
|
|
||||||
public getUser(userId: number) {
|
|
||||||
return new User(userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the user by handle.
|
|
||||||
* @param userHandle
|
|
||||||
*/
|
|
||||||
public async getUserByHandle(userHandle: string) {
|
|
||||||
const result = await this.queryHelper.first({
|
|
||||||
text: "SELECT * FROM users WHERE users.handle = $1",
|
|
||||||
values: [userHandle],
|
|
||||||
});
|
|
||||||
return new User(result.id, result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class User {
|
|
||||||
public readonly id: number;
|
|
||||||
private $name: string;
|
|
||||||
private $handle: string;
|
|
||||||
private $email: string;
|
|
||||||
private $greenpoints: number;
|
|
||||||
private $joinedAt: string;
|
|
||||||
private dataLoaded: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor of the user
|
|
||||||
* @param id
|
|
||||||
* @param row
|
|
||||||
*/
|
|
||||||
constructor(id: number, private row?: any) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the user
|
|
||||||
*/
|
|
||||||
public async name(): Promise<string> {
|
|
||||||
if (!this.dataLoaded) {
|
|
||||||
await this.loadData();
|
|
||||||
}
|
|
||||||
return this.$name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the username of the user
|
|
||||||
* @param name
|
|
||||||
*/
|
|
||||||
public async setName(name: string): Promise<string> {
|
|
||||||
const result = await queryHelper.first({
|
|
||||||
text: "UPDATE TABLE users SET name = $1 WHERE id = $2",
|
|
||||||
values: [name, this.id],
|
|
||||||
});
|
|
||||||
return result.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The unique handle of the user.
|
|
||||||
*/
|
|
||||||
public async handle(): Promise<string> {
|
|
||||||
if (!this.dataLoaded) {
|
|
||||||
await this.loadData();
|
|
||||||
}
|
|
||||||
return this.$handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the handle of the user
|
|
||||||
*/
|
|
||||||
public async setHandle(handle: string): Promise<string> {
|
|
||||||
const result = await queryHelper.first({
|
|
||||||
text: "UPDATE TABLE users SET handle = $1 WHERE id = $2",
|
|
||||||
values: [handle, this.id],
|
|
||||||
});
|
|
||||||
return result.handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The email of the user
|
|
||||||
*/
|
|
||||||
public async email(): Promise<string> {
|
|
||||||
if (!this.dataLoaded) {
|
|
||||||
await this.loadData();
|
|
||||||
}
|
|
||||||
return this.$email;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the email of the user
|
|
||||||
* @param email
|
|
||||||
*/
|
|
||||||
public async setEmail(email: string): Promise<string> {
|
|
||||||
const result = await queryHelper.first({
|
|
||||||
text: "UPDATE TABLE users SET email = $1 WHERE users.id = $2 RETURNING email",
|
|
||||||
values: [email, this.id],
|
|
||||||
});
|
|
||||||
return result.email;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The number of greenpoints of the user
|
|
||||||
*/
|
|
||||||
public async greenpoints(): Promise<number> {
|
|
||||||
if (!this.dataLoaded) {
|
|
||||||
await this.loadData();
|
|
||||||
}
|
|
||||||
return this.$greenpoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the greenpoints of a user.
|
|
||||||
* @param points
|
|
||||||
*/
|
|
||||||
public async setGreenpoints(points: number): Promise<number> {
|
|
||||||
const result = await queryHelper.first({
|
|
||||||
text: "UPDATE users SET greenpoints = $1 WHERE id = $2 RETURNING greenpoints",
|
|
||||||
values: [points, this.id],
|
|
||||||
});
|
|
||||||
return result.greenpoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The date the user joined the platform
|
|
||||||
*/
|
|
||||||
public async joinedAt(): Promise<Date> {
|
|
||||||
if (!this.dataLoaded) {
|
|
||||||
await this.loadData();
|
|
||||||
}
|
|
||||||
return new Date(this.$joinedAt);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetches the data for the user.
|
|
||||||
*/
|
|
||||||
private async loadData(): Promise<void> {
|
|
||||||
let result: any;
|
|
||||||
if (this.row) {
|
|
||||||
result = this.row;
|
|
||||||
} else {
|
|
||||||
result = await queryHelper.first({
|
|
||||||
text: "SELECT * FROM users WHERE user.id = $1",
|
|
||||||
values: [this.id],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (result) {
|
|
||||||
this.$name = result.name;
|
|
||||||
this.$handle = result.handle;
|
|
||||||
this.$email = result.email;
|
|
||||||
this.$greenpoints = result.greenpoints;
|
|
||||||
this.$joinedAt = result.joined_at;
|
|
||||||
this.dataLoaded = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Post {
|
|
||||||
public readonly id: number;
|
|
||||||
private $upvotes: number;
|
|
||||||
private $downvotes: number;
|
|
||||||
private $createdAt: string;
|
|
||||||
private $content: string;
|
|
||||||
private $author: number;
|
|
||||||
private $type: string;
|
|
||||||
private dataLoaded: boolean = false;
|
|
||||||
|
|
||||||
constructor(id: number, private row?: any) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the upvotes of a post.
|
|
||||||
*/
|
|
||||||
public async upvotes() {
|
|
||||||
if (!this.dataLoaded) {
|
|
||||||
await this.loadData();
|
|
||||||
}
|
|
||||||
return this.$upvotes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the downvotes of the post
|
|
||||||
*/
|
|
||||||
public async downvotes() {
|
|
||||||
if (!this.dataLoaded) {
|
|
||||||
await this.loadData();
|
|
||||||
}
|
|
||||||
return this.$downvotes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the data from the database if needed.
|
|
||||||
*/
|
|
||||||
private async loadData(): Promise<void> {
|
|
||||||
let result: any;
|
|
||||||
if (this.row) {
|
|
||||||
result = this.row;
|
|
||||||
} else {
|
|
||||||
result = await queryHelper.first({
|
|
||||||
text: "SELECT * FROM posts WHERE posts.id = $1",
|
|
||||||
values: [this.id],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (result) {
|
|
||||||
this.$author = result.author;
|
|
||||||
this.$content = result.content;
|
|
||||||
this.$downvotes = result.downvotes;
|
|
||||||
this.$upvotes = result.upvotes;
|
|
||||||
this.$createdAt = result.created_at;
|
|
||||||
this.$type = result.type;
|
|
||||||
this.dataLoaded = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* @author Trivernis
|
||||||
|
* @remarks
|
||||||
|
*
|
||||||
|
* Taken from {@link https://github.com/Trivernis/whooshy}
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {Router} from "express";
|
||||||
|
import {Namespace, Server} from "socket.io";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract Route class to be implemented by each route.
|
||||||
|
* This class contains the socket-io Server, router and resolver
|
||||||
|
* for each route.
|
||||||
|
*/
|
||||||
|
abstract class Route {
|
||||||
|
|
||||||
|
public router?: Router;
|
||||||
|
protected io?: Server;
|
||||||
|
protected ions?: Namespace;
|
||||||
|
|
||||||
|
public abstract async init(...params: any): Promise<any>;
|
||||||
|
public abstract async destroy(...params: any): Promise<any>;
|
||||||
|
public abstract async resolver(request: any, response: any): Promise<object>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Route;
|
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* abstact DataObject class
|
||||||
|
*/
|
||||||
|
export abstract class DataObject {
|
||||||
|
protected dataLoaded: boolean = false;
|
||||||
|
|
||||||
|
constructor(public id: number, protected row?: any) {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract loadData(): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads data from the database if data has not been loaded
|
||||||
|
*/
|
||||||
|
protected loadDataIfNotExists() {
|
||||||
|
if (this.dataLoaded) {
|
||||||
|
this.loadData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
import {DataObject} from "./DataObject";
|
||||||
|
import {queryHelper} from "./index";
|
||||||
|
import dataaccess from "./index";
|
||||||
|
import {User} from "./User";
|
||||||
|
|
||||||
|
export class Post extends DataObject {
|
||||||
|
public readonly id: number;
|
||||||
|
private $upvotes: number;
|
||||||
|
private $downvotes: number;
|
||||||
|
private $createdAt: string;
|
||||||
|
private $content: string;
|
||||||
|
private $author: number;
|
||||||
|
private $type: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the upvotes of a post.
|
||||||
|
*/
|
||||||
|
public async upvotes(): Promise<number> {
|
||||||
|
this.loadDataIfNotExists();
|
||||||
|
return this.$upvotes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the downvotes of the post
|
||||||
|
*/
|
||||||
|
public async downvotes(): Promise<number> {
|
||||||
|
this.loadDataIfNotExists();
|
||||||
|
return this.$downvotes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The content of the post (markdown)
|
||||||
|
*/
|
||||||
|
public async content(): Promise<string> {
|
||||||
|
this.loadDataIfNotExists();
|
||||||
|
return this.$content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The date the post was created at.
|
||||||
|
*/
|
||||||
|
public async createdAt(): Promise<string> {
|
||||||
|
this.loadDataIfNotExists();
|
||||||
|
return this.$createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The autor of the post.
|
||||||
|
*/
|
||||||
|
public async author(): Promise<User> {
|
||||||
|
this.loadDataIfNotExists();
|
||||||
|
return new User(this.$author);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the post.
|
||||||
|
*/
|
||||||
|
public async delete(): Promise<void> {
|
||||||
|
const query = await queryHelper.first({
|
||||||
|
text: "DELETE FROM posts WHERE id = $1",
|
||||||
|
values: [this.id],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of vote the user performed on the post.
|
||||||
|
*/
|
||||||
|
public async userVote(userId: number): Promise<dataaccess.VoteType> {
|
||||||
|
const result = await queryHelper.first({
|
||||||
|
text: "SELECT vote_type FROM votes WHERE user_id = $1 AND item_id = $2",
|
||||||
|
values: [userId, this.id],
|
||||||
|
});
|
||||||
|
if (result) {
|
||||||
|
return result.vote_type;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the data from the database if needed.
|
||||||
|
*/
|
||||||
|
protected async loadData(): Promise<void> {
|
||||||
|
let result: any;
|
||||||
|
if (this.row) {
|
||||||
|
result = this.row;
|
||||||
|
} else {
|
||||||
|
result = await queryHelper.first({
|
||||||
|
text: "SELECT * FROM posts WHERE posts.id = $1",
|
||||||
|
values: [this.id],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (result) {
|
||||||
|
this.$author = result.author;
|
||||||
|
this.$content = result.content;
|
||||||
|
this.$downvotes = result.downvotes;
|
||||||
|
this.$upvotes = result.upvotes;
|
||||||
|
this.$createdAt = result.created_at;
|
||||||
|
this.$type = result.type;
|
||||||
|
this.dataLoaded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,137 @@
|
|||||||
|
import {DataObject} from "./DataObject";
|
||||||
|
import {queryHelper} from "./index";
|
||||||
|
import {Post} from "./Post";
|
||||||
|
|
||||||
|
export class User extends DataObject {
|
||||||
|
private $name: string;
|
||||||
|
private $handle: string;
|
||||||
|
private $email: string;
|
||||||
|
private $greenpoints: number;
|
||||||
|
private $joinedAt: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the user
|
||||||
|
*/
|
||||||
|
public async name(): Promise<string> {
|
||||||
|
this.loadDataIfNotExists();
|
||||||
|
return this.$name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the username of the user
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
public async setName(name: string): Promise<string> {
|
||||||
|
const result = await queryHelper.first({
|
||||||
|
text: "UPDATE TABLE users SET name = $1 WHERE id = $2",
|
||||||
|
values: [name, this.id],
|
||||||
|
});
|
||||||
|
return result.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The unique handle of the user.
|
||||||
|
*/
|
||||||
|
public async handle(): Promise<string> {
|
||||||
|
this.loadDataIfNotExists();
|
||||||
|
return this.$handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the handle of the user
|
||||||
|
*/
|
||||||
|
public async setHandle(handle: string): Promise<string> {
|
||||||
|
const result = await queryHelper.first({
|
||||||
|
text: "UPDATE TABLE users SET handle = $1 WHERE id = $2",
|
||||||
|
values: [handle, this.id],
|
||||||
|
});
|
||||||
|
return result.handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The email of the user
|
||||||
|
*/
|
||||||
|
public async email(): Promise<string> {
|
||||||
|
this.loadDataIfNotExists();
|
||||||
|
return this.$email;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the email of the user
|
||||||
|
* @param email
|
||||||
|
*/
|
||||||
|
public async setEmail(email: string): Promise<string> {
|
||||||
|
const result = await queryHelper.first({
|
||||||
|
text: "UPDATE TABLE users SET email = $1 WHERE users.id = $2 RETURNING email",
|
||||||
|
values: [email, this.id],
|
||||||
|
});
|
||||||
|
return result.email;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of greenpoints of the user
|
||||||
|
*/
|
||||||
|
public async greenpoints(): Promise<number> {
|
||||||
|
this.loadDataIfNotExists();
|
||||||
|
return this.$greenpoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the greenpoints of a user.
|
||||||
|
* @param points
|
||||||
|
*/
|
||||||
|
public async setGreenpoints(points: number): Promise<number> {
|
||||||
|
const result = await queryHelper.first({
|
||||||
|
text: "UPDATE users SET greenpoints = $1 WHERE id = $2 RETURNING greenpoints",
|
||||||
|
values: [points, this.id],
|
||||||
|
});
|
||||||
|
return result.greenpoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The date the user joined the platform
|
||||||
|
*/
|
||||||
|
public async joinedAt(): Promise<Date> {
|
||||||
|
this.loadDataIfNotExists();
|
||||||
|
return new Date(this.$joinedAt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all posts for a user.
|
||||||
|
*/
|
||||||
|
public async posts(): Promise<Post[]> {
|
||||||
|
const result = await queryHelper.all({
|
||||||
|
text: "SELECT * FROM posts WHERE author = $1",
|
||||||
|
values: [this.id],
|
||||||
|
});
|
||||||
|
const posts = [];
|
||||||
|
|
||||||
|
for (const row of result) {
|
||||||
|
posts.push(new Post(row.id, row));
|
||||||
|
}
|
||||||
|
return posts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches the data for the user.
|
||||||
|
*/
|
||||||
|
protected async loadData(): Promise<void> {
|
||||||
|
let result: any;
|
||||||
|
if (this.row) {
|
||||||
|
result = this.row;
|
||||||
|
} else {
|
||||||
|
result = await queryHelper.first({
|
||||||
|
text: "SELECT * FROM users WHERE user.id = $1",
|
||||||
|
values: [this.id],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (result) {
|
||||||
|
this.$name = result.name;
|
||||||
|
this.$handle = result.handle;
|
||||||
|
this.$email = result.email;
|
||||||
|
this.$greenpoints = result.greenpoints;
|
||||||
|
this.$joinedAt = result.joined_at;
|
||||||
|
this.dataLoaded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
import {Pool} from "pg";
|
||||||
|
import globals from "../globals";
|
||||||
|
import {QueryHelper} from "../QueryHelper";
|
||||||
|
import {User} from "./User";
|
||||||
|
|
||||||
|
const config = globals.config;
|
||||||
|
const tableCreationFile = __dirname + "/../../sql/create-tables.sql";
|
||||||
|
const tableUpdateFile = __dirname + "/../../sql/update-tables.sql";
|
||||||
|
|
||||||
|
const dbClient: Pool = new Pool({
|
||||||
|
database: config.database.database,
|
||||||
|
host: config.database.host,
|
||||||
|
password: config.database.password,
|
||||||
|
port: config.database.port,
|
||||||
|
user: config.database.user,
|
||||||
|
});
|
||||||
|
export const queryHelper = new QueryHelper(dbClient, tableCreationFile, tableUpdateFile);
|
||||||
|
|
||||||
|
namespace dataaccess {
|
||||||
|
/**
|
||||||
|
* Initializes everything that needs to be initialized asynchronous.
|
||||||
|
*/
|
||||||
|
export async function init() {
|
||||||
|
await queryHelper.updateTableDefinitions();
|
||||||
|
await queryHelper.createTables();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the user by id
|
||||||
|
* @param userId
|
||||||
|
*/
|
||||||
|
export function getUser(userId: number) {
|
||||||
|
return new User(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the user by handle.
|
||||||
|
* @param userHandle
|
||||||
|
*/
|
||||||
|
export async function getUserByHandle(userHandle: string) {
|
||||||
|
const result = await this.queryHelper.first({
|
||||||
|
text: "SELECT * FROM users WHERE users.handle = $1",
|
||||||
|
values: [userHandle],
|
||||||
|
});
|
||||||
|
return new User(result.id, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum representing the types of votes that can be performed on a post.
|
||||||
|
*/
|
||||||
|
export enum VoteType {
|
||||||
|
UPVOTE = "UPVOTE",
|
||||||
|
DOWNVOTE = "DOWNVOTE",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum representing the types of request that can be created.
|
||||||
|
*/
|
||||||
|
export enum RequestType {
|
||||||
|
FRIENDREQUEST = "FRIENDREQUEST",
|
||||||
|
GROUPINVITE = "GROUPINVITE",
|
||||||
|
EVENTINVITE = "EVENTINVITE",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default dataaccess;
|
@ -0,0 +1,5 @@
|
|||||||
|
@mixin gridPosition($rowStart, $rowEnd, $columnStart, $columnEnd)
|
||||||
|
grid-row-start: $rowStart
|
||||||
|
grid-row-end: $rowEnd
|
||||||
|
grid-column-start: $columnStart
|
||||||
|
grid-column-end: $columnEnd
|
@ -0,0 +1,82 @@
|
|||||||
|
@import "vars"
|
||||||
|
@import "mixins"
|
||||||
|
|
||||||
|
body
|
||||||
|
font-family: Arial, serif
|
||||||
|
|
||||||
|
button
|
||||||
|
border: 2px solid $cPrimary
|
||||||
|
margin-top: 0.125em
|
||||||
|
padding: 0.125em
|
||||||
|
background-color: $cPrimary
|
||||||
|
color: $cPrimarySurface
|
||||||
|
font-weight: bold
|
||||||
|
transition-duration: 0.25s
|
||||||
|
|
||||||
|
button:hover
|
||||||
|
background-color: lighten($cPrimary, 10%)
|
||||||
|
cursor: pointer
|
||||||
|
|
||||||
|
button:active
|
||||||
|
background-color: darken($cPrimary, 5%)
|
||||||
|
box-shadow: inset 0.25em 0.25em 0.1em rgba(0, 0, 0, 0.25)
|
||||||
|
|
||||||
|
.stylebar
|
||||||
|
@include gridPosition(1, 2, 1, 4)
|
||||||
|
display: grid
|
||||||
|
grid-template: 100% /25% 50% 25%
|
||||||
|
background-color: $cPrimary
|
||||||
|
color: $cPrimarySurface
|
||||||
|
|
||||||
|
h1
|
||||||
|
@include gridPosition(1, 2, 1, 2)
|
||||||
|
text-align: center
|
||||||
|
margin: auto
|
||||||
|
|
||||||
|
#content
|
||||||
|
grid-template: 7.5% 92.5% / 25% 50% 25%
|
||||||
|
display: grid
|
||||||
|
width: 100%
|
||||||
|
height: 100%
|
||||||
|
|
||||||
|
#friendscontainer
|
||||||
|
@include gridPosition(2, 3, 1, 2)
|
||||||
|
background-color: $cPrimaryBackground
|
||||||
|
|
||||||
|
#feedcontainer
|
||||||
|
@include gridPosition(2, 3, 2, 3)
|
||||||
|
background-color: $cSecondaryBackground
|
||||||
|
.postinput
|
||||||
|
margin: 0.5em
|
||||||
|
input
|
||||||
|
width: 100%
|
||||||
|
border-radius: 0.25em
|
||||||
|
border: 1px solid $cPrimary
|
||||||
|
padding: 0.125em
|
||||||
|
height: 2em
|
||||||
|
button.submitbutton
|
||||||
|
border-radius: 0.25em
|
||||||
|
height: 2em
|
||||||
|
|
||||||
|
.feeditem
|
||||||
|
background-color: $cPrimaryBackground
|
||||||
|
min-height: 2em
|
||||||
|
margin: 0.5em
|
||||||
|
padding: 0.25em
|
||||||
|
border-radius: 0.25em
|
||||||
|
.itemhead
|
||||||
|
align-items: flex-start
|
||||||
|
|
||||||
|
.title, .handle, .date
|
||||||
|
margin: 0.125em
|
||||||
|
.title
|
||||||
|
font-weight: bold
|
||||||
|
|
||||||
|
.handle, .date
|
||||||
|
color: $cInactiveText
|
||||||
|
.handle a
|
||||||
|
text-decoration: none
|
||||||
|
color: $cInactiveText
|
||||||
|
font-style: normal
|
||||||
|
.handle a:hover
|
||||||
|
text-decoration: underline
|
@ -0,0 +1,5 @@
|
|||||||
|
$cPrimaryBackground: #fff
|
||||||
|
$cSecondaryBackground: #ddd
|
||||||
|
$cInactiveText: #555
|
||||||
|
$cPrimary: #0d6b14
|
||||||
|
$cPrimarySurface: #fff
|
@ -1,10 +1,55 @@
|
|||||||
import {Router} from "express";
|
import {Router} from "express";
|
||||||
|
import {Server} from "socket.io";
|
||||||
|
import Route from "../lib/Route";
|
||||||
|
|
||||||
const router = Router();
|
/**
|
||||||
|
* Class for the home route.
|
||||||
|
*/
|
||||||
|
class HomeRoute extends Route {
|
||||||
|
/**
|
||||||
|
* Constructor, creates new router.
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.router = Router();
|
||||||
|
this.configure();
|
||||||
|
}
|
||||||
|
|
||||||
/* GET home page. */
|
/**
|
||||||
router.get("/", (req, res) => {
|
* Asynchronous init for socket.io.
|
||||||
|
* @param io - the io instance
|
||||||
|
*/
|
||||||
|
public async init(io: Server) {
|
||||||
|
this.io = io;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the instance by dereferencing the router and resolver.
|
||||||
|
*/
|
||||||
|
public async destroy(): Promise<void> {
|
||||||
|
this.router = null;
|
||||||
|
this.resolver = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the resolvers for the graphql api.
|
||||||
|
* @param req - the request object
|
||||||
|
* @param res - the response object
|
||||||
|
*/
|
||||||
|
public async resolver(req: any, res: any): Promise<object> {
|
||||||
|
return {
|
||||||
|
// TODO: Define grapql resolvers
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the route.
|
||||||
|
*/
|
||||||
|
private configure() {
|
||||||
|
this.router.get("/", (req, res) => {
|
||||||
res.render("home");
|
res.render("home");
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default router;
|
export default HomeRoute;
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
ALTER TABLE IF EXISTS votes
|
||||||
|
ADD COLUMN IF NOT EXISTS vote_type varchar(8) DEFAULT 'upvote',
|
||||||
|
ALTER COLUMN vote_type SET DEFAULT 'upvote';
|
@ -1,5 +0,0 @@
|
|||||||
html
|
|
||||||
head
|
|
||||||
title Greenvironment Network
|
|
||||||
body
|
|
||||||
h1 Greenvironment
|
|
@ -0,0 +1,13 @@
|
|||||||
|
div#feedcontainer
|
||||||
|
div.postinput
|
||||||
|
input(type=text placeholder='Post something')
|
||||||
|
button.submitbutton Submit
|
||||||
|
div.feeditem
|
||||||
|
div.itemhead
|
||||||
|
span.title Testuser
|
||||||
|
span.handle
|
||||||
|
a(href='#') @testuser
|
||||||
|
span.date 23.09.19 10:07
|
||||||
|
p.text
|
||||||
|
| Example Test text.
|
||||||
|
| This is a test
|
@ -0,0 +1 @@
|
|||||||
|
div#friendscontainer
|
@ -0,0 +1,9 @@
|
|||||||
|
html
|
||||||
|
head
|
||||||
|
title Greenvironment Network
|
||||||
|
include ../includes/head
|
||||||
|
body
|
||||||
|
div#content
|
||||||
|
include stylebar
|
||||||
|
include feed
|
||||||
|
include friends
|
@ -0,0 +1,2 @@
|
|||||||
|
div.stylebar
|
||||||
|
h1 Greenvironment
|
@ -0,0 +1 @@
|
|||||||
|
link(rel='stylesheet' href='stylesheets/style.css')
|
Loading…
Reference in New Issue