Reformat files and run lint

Co-authored-by: Ezequiel Bellver <ebellver@itba.edu.ar>
Co-authored-by: Juan Barmasch <jbarmasch@itba.edu.ar>
This commit is contained in:
Santiago Lo Coco 2022-12-20 08:35:02 -03:00
parent afa3dd8ed8
commit 2c0c5b49bf
41 changed files with 6463 additions and 857 deletions

View File

@ -80,7 +80,7 @@ sh run.sh -a
Por último, debe levantar el frontend (usará el puerto 3000) mediante: Por último, debe levantar el frontend (usará el puerto 3000) mediante:
``` ```
h run.sh -f sh run.sh -f
``` ```
## Documentación de la API ## Documentación de la API

View File

@ -3,7 +3,7 @@ import json
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from bsition.api.models.document import Document, DocumentUpdate, Access from bsition.api.models.document import Access, Document, DocumentUpdate
from bsition.api.utils.security import get_current_user from bsition.api.utils.security import get_current_user
from bsition.backend.elastic import search as elastic from bsition.backend.elastic import search as elastic
from bsition.backend.mongo import documents as mongo from bsition.backend.mongo import documents as mongo
@ -14,13 +14,17 @@ router = APIRouter()
@router.post("") @router.post("")
def create(aux: Document, user: tuple = Depends(get_current_user)): def create(aux: Document, user: tuple = Depends(get_current_user)):
doc_id = mongo.create_document({ doc_id = mongo.create_document(
{
"name": aux.name, "name": aux.name,
"owner": user[0], "owner": user[0],
"data": aux.data if aux.data is not None else "" "data": aux.data if aux.data is not None else "",
}) }
)
postgres.give_access_doc(user[0], doc_id, 1) postgres.give_access_doc(user[0], doc_id, 1)
return JSONResponse(content={"detail": "Document created", "id": doc_id}, status_code=201) return JSONResponse(
content={"detail": "Document created", "id": doc_id}, status_code=201
)
@router.get("") @router.get("")
@ -63,7 +67,9 @@ def give_access(id: str, access_type: Access, user: tuple = Depends(get_current_
@router.put("/{id}/access") @router.put("/{id}/access")
def update_access(id: str, access_type: Access, user: tuple = Depends(get_current_user)): def update_access(
id: str, access_type: Access, user: tuple = Depends(get_current_user)
):
postgres.give_access_doc(user[0], id, access_type.access_type) postgres.give_access_doc(user[0], id, access_type.access_type)
return JSONResponse(content={"detail": "Access updated"}, status_code=202) return JSONResponse(content={"detail": "Access updated"}, status_code=202)

View File

@ -5,8 +5,8 @@ from bsition.api.models.document import Access
from bsition.api.models.table import Filter, Sort, Table from bsition.api.models.table import Filter, Sort, Table
from bsition.api.utils.security import get_current_user from bsition.api.utils.security import get_current_user
from bsition.backend.mongo import tables as mongo from bsition.backend.mongo import tables as mongo
from bsition.backend.postgres import tables as postgres_t
from bsition.backend.postgres import relations as postgres_r from bsition.backend.postgres import relations as postgres_r
from bsition.backend.postgres import tables as postgres_t
router = APIRouter() router = APIRouter()
@ -74,7 +74,9 @@ def give_access(id: str, access_type: Access, user: tuple = Depends(get_current_
@router.put("/{id}/access") @router.put("/{id}/access")
def update_access(id: str, access_type: Access, user: tuple = Depends(get_current_user)): def update_access(
id: str, access_type: Access, user: tuple = Depends(get_current_user)
):
postgres_r.give_access_table(user[0], id, access_type.access_type) postgres_r.give_access_table(user[0], id, access_type.access_type)
return JSONResponse(content={"detail": "Access updated"}, status_code=202) return JSONResponse(content={"detail": "Access updated"}, status_code=202)

View File

@ -7,7 +7,7 @@ from bsition.api.utils.jwt import write_token
from bsition.api.utils.password import verify_password from bsition.api.utils.password import verify_password
from bsition.api.utils.security import get_current_user, oauth2_scheme from bsition.api.utils.security import get_current_user, oauth2_scheme
from bsition.backend.postgres.users import get_user_by_username from bsition.backend.postgres.users import get_user_by_username
from bsition.backend.redis.tokens import add_token, remove_token, clean_tokens from bsition.backend.redis.tokens import add_token, clean_tokens, remove_token
router = APIRouter() router = APIRouter()
@ -34,6 +34,8 @@ def login(form: OAuth2PasswordRequestForm = Depends()):
@router.delete("/token") @router.delete("/token")
def logout(token: str = Depends(oauth2_scheme), user: tuple = Depends(get_current_user)): def logout(
token: str = Depends(oauth2_scheme), user: tuple = Depends(get_current_user)
):
remove_token(user[1], token) remove_token(user[1], token)
return JSONResponse(content={"detail": "Token deleted."}, status_code=202) return JSONResponse(content={"detail": "Token deleted."}, status_code=202)

View File

@ -15,9 +15,7 @@ def search(index, query, user_id):
"must": [ "must": [
{"query_string": {"query": query, "default_field": "data"}}, {"query_string": {"query": query, "default_field": "data"}},
], ],
"filter": [ "filter": [{"terms": {"_id": acc_doc}}],
{"terms": {"_id": acc_doc}}
]
} }
}, },
highlight={"fields": {"data": {}}}, highlight={"fields": {"data": {}}},
@ -29,11 +27,11 @@ def search(index, query, user_id):
# str(hit["highlight"]) + " ---- " + "%(name)s: %(data)s" % hit["_source"] # str(hit["highlight"]) + " ---- " + "%(name)s: %(data)s" % hit["_source"]
# str(hit["highlight"]) + " ---- " + "%(name)s: %(data)s" % hit["_source"] # str(hit["highlight"]) + " ---- " + "%(name)s: %(data)s" % hit["_source"]
{ {
"id": hit['_id'], "id": hit["_id"],
"name": hit['_source']["name"], "name": hit["_source"]["name"],
"highlight": str(hit["highlight"]["data"]) "highlight": str(hit["highlight"]["data"]),
} }
) )
print(hit['_id'], hit['_source']) print(hit["_id"], hit["_source"])
return hits return hits

View File

@ -1,8 +1,8 @@
from bson import ObjectId from bson import ObjectId
from bsition.backend.elastic import utils as elastic from bsition.backend.elastic import utils as elastic
from bsition.backend.postgres import relations as postgres
from bsition.backend.mongo.utils import get_database from bsition.backend.mongo.utils import get_database
from bsition.backend.postgres import relations as postgres
def get_documents(user_id): def get_documents(user_id):
@ -22,7 +22,7 @@ def get_documents(user_id):
"access": 1, "access": 1,
"owner": 1, "owner": 1,
} }
} },
] ]
return list(docs_coll.aggregate(pipeline)) return list(docs_coll.aggregate(pipeline))

View File

@ -118,9 +118,7 @@ def is_public(doc_id):
conn = get_connection() conn = get_connection()
cur = conn.cursor() cur = conn.cursor()
cur.execute( cur.execute(
sql.SQL( sql.SQL("SELECT doc_id FROM public_docs WHERE doc_id = {doc_id}").format(
"SELECT doc_id FROM public_docs WHERE doc_id = {doc_id}"
).format(
doc_id=sql.Literal(doc_id), doc_id=sql.Literal(doc_id),
) )
) )

View File

@ -21,8 +21,6 @@ def remove_token(username, token):
client.zrem(username, token) client.zrem(username, token)
# Puede correr en un cron o, por ejemplo, cada vez que el usuario hace login (o logout)
def clean_tokens(username): def clean_tokens(username):
client = get_client() client = get_client()
client.zremrangebyscore(username, -inf, int(time.time())) client.zremrangebyscore(username, -inf, int(time.time()))

View File

@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"scripts": { "scripts": {
"lint": "next lint",
"dev": "next dev", "dev": "next dev",
"build": "next build", "build": "next build",
"start": "next start" "start": "next start"
@ -19,6 +20,8 @@
"@types/node": "^17.0.21", "@types/node": "^17.0.21",
"@types/react": "^17.0.39", "@types/react": "^17.0.39",
"autoprefixer": "^10.4.2", "autoprefixer": "^10.4.2",
"eslint": "8.30.0",
"eslint-config-next": "13.0.7",
"postcss": "^8.4.7", "postcss": "^8.4.7",
"postcss-import": "^14.0.2", "postcss-import": "^14.0.2",
"tailwindcss": "^3.0.23", "tailwindcss": "^3.0.23",

View File

@ -1,10 +1,10 @@
import React from "react"; import React from "react";
import Sidebar from "./Sidebar"; import Sidebar from "./Sidebar";
const Layout = ({ children }) => { const Layout = ({children}) => {
return ( return (
<div className="h-screen flex flex-row justify-start"> <div className="h-screen flex flex-row justify-start">
<Sidebar /> <Sidebar/>
<div <div
className="bg-primary flex-1 p-4 text-white justify-center align-center h-full"> className="bg-primary flex-1 p-4 text-white justify-center align-center h-full">
{children} {children}

View File

@ -1,6 +1,6 @@
import classNames from "classnames"; import classNames from "classnames";
import Link from "next/link"; import Link from "next/link";
import { useRouter } from "next/router"; import {useRouter} from "next/router";
import React, {useState, useMemo, useEffect} from "react"; import React, {useState, useMemo, useEffect} from "react";
import { import {
ArticleIcon, ArticleIcon,
@ -16,9 +16,9 @@ const Sidebar = () => {
const [toggleCollapse, setToggleCollapse] = useState(false); const [toggleCollapse, setToggleCollapse] = useState(false);
const [isCollapsible, setIsCollapsible] = useState(false); const [isCollapsible, setIsCollapsible] = useState(false);
const [menuItems, setMenuItems] = useState([ const [menuItems, setMenuItems] = useState([
{ id: 1, label: "Home", icon: HomeIcon, link: "/" }, {id: 1, label: "Home", icon: HomeIcon, link: "/"},
{ id: 2, label: "Search", icon: SearchIcon, link: "/search" }, {id: 2, label: "Search", icon: SearchIcon, link: "/search"},
{ id: 3, label: "Create document", icon: CreateIcon, link: "/create-document" } {id: 3, label: "Create document", icon: CreateIcon, link: "/create-document"}
]); ]);
const [token, setToken] = useState(""); const [token, setToken] = useState("");
@ -37,9 +37,9 @@ const Sidebar = () => {
}) })
let json = await res.json(); let json = await res.json();
let list = [ let list = [
{ id: 1, label: "Home", icon: HomeIcon, link: "/" }, {id: 1, label: "Home", icon: HomeIcon, link: "/"},
{ id: 2, label: "Search", icon: SearchIcon, link: "/search" }, {id: 2, label: "Search", icon: SearchIcon, link: "/search"},
{ id: 3, label: "Create document", icon: CreateIcon, link: "/create-document" } {id: 3, label: "Create document", icon: CreateIcon, link: "/create-document"}
] ]
json.forEach((doc) => { json.forEach((doc) => {
list.push({ list.push({
@ -90,8 +90,7 @@ const Sidebar = () => {
if (!activeMenu || !menu || menu === "undefined") { if (!activeMenu || !menu || menu === "undefined") {
if (!router.query || !router.query.id) { if (!router.query || !router.query.id) {
return classNames("flex items-center cursor-pointer hover:bg-light-lighter rounded w-full overflow-hidden whitespace-nowrap"); return classNames("flex items-center cursor-pointer hover:bg-light-lighter rounded w-full overflow-hidden whitespace-nowrap");
} } else {
else {
return classNames( return classNames(
"flex items-center cursor-pointer hover:bg-light-lighter rounded w-full overflow-hidden whitespace-nowrap", "flex items-center cursor-pointer hover:bg-light-lighter rounded w-full overflow-hidden whitespace-nowrap",
{ {
@ -135,12 +134,12 @@ const Sidebar = () => {
className={wrapperClasses} className={wrapperClasses}
onMouseEnter={onMouseOver} onMouseEnter={onMouseOver}
onMouseLeave={onMouseOver} onMouseLeave={onMouseOver}
style={{ transition: "width 300ms cubic-bezier(0.2, 0, 0, 1) 0s" }} style={{transition: "width 300ms cubic-bezier(0.2, 0, 0, 1) 0s"}}
> >
<div className="flex flex-col"> <div className="flex flex-col">
<div className="flex items-center justify-between relative"> <div className="flex items-center justify-between relative">
<div className="flex items-center pl-1 gap-4"> <div className="flex items-center pl-1 gap-4">
<LogoIcon /> <LogoIcon/>
<span <span
className={classNames("mt-2 text-lg font-medium text-text", { className={classNames("mt-2 text-lg font-medium text-text", {
hidden: toggleCollapse, hidden: toggleCollapse,
@ -154,21 +153,21 @@ const Sidebar = () => {
className={collapseIconClasses} className={collapseIconClasses}
onClick={handleSidebarToggle} onClick={handleSidebarToggle}
> >
<CollapsIcon /> <CollapsIcon/>
</button> </button>
)} )}
</div> </div>
<div className="flex flex-col items-start mt-24"> <div className="flex flex-col items-start mt-24">
{menuItems.map(({ icon: Icon, ...menu }) => { {menuItems.map(({icon: Icon, ...menu}) => {
const classes = getNavItemClasses(menu); const classes = getNavItemClasses(menu);
return ( return (
<div className={classes} key={menu.id}> <div className={classes} key={menu.id}>
<Link href={menu.link}> <Link href={menu.link}>
<a className="flex py-4 px-3 items-center w-full h-full"> <a className="flex py-4 px-3 items-center w-full h-full">
<div style={{ width: "2.5rem" }}> <div style={{width: "2.5rem"}}>
<Icon /> <Icon/>
</div> </div>
{!toggleCollapse && ( {!toggleCollapse && (
<span <span
@ -188,8 +187,8 @@ const Sidebar = () => {
</div> </div>
<div className={`${getNavItemClasses({})} px-3 py-4`}> <div className={`${getNavItemClasses({})} px-3 py-4`}>
<div style={{ width: "2.5rem" }}> <div style={{width: "2.5rem"}}>
<LogoutIcon /> <LogoutIcon/>
</div> </div>
{!toggleCollapse && ( {!toggleCollapse && (
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>

View File

@ -1,6 +1,6 @@
import * as React from "react"; import * as React from "react";
function ArticleIcon({ fill = "#6C7281", ...rest }) { function ArticleIcon({fill = "#6C7281", ...rest}) {
return ( return (
<svg <svg
width={24} width={24}
@ -14,7 +14,7 @@ function ArticleIcon({ fill = "#6C7281", ...rest }) {
d="M19 5v14H5V5h14zm0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z" d="M19 5v14H5V5h14zm0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"
fill={fill} fill={fill}
/> />
<path d="M14 17H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z" fill={fill} /> <path d="M14 17H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z" fill={fill}/>
</svg> </svg>
); );
} }

View File

@ -1,6 +1,6 @@
import * as React from "react"; import * as React from "react";
function CollapsIcon({ fill = "#6C7281", ...rest }) { function CollapsIcon({fill = "#6C7281", ...rest}) {
return ( return (
<svg <svg
width={16} width={16}

View File

@ -1,6 +1,6 @@
import * as React from "react"; import * as React from "react";
function CreateIcon({ fill = "#6C7281", ...rest }) { function CreateIcon({fill = "#6C7281", ...rest}) {
return ( return (
<svg <svg
width={24} width={24}

View File

@ -1,6 +1,6 @@
import * as React from "react"; import * as React from "react";
function DeleteIcon({ fill = "#6C7281", ...rest }) { function DeleteIcon({fill = "#6C7281", ...rest}) {
return ( return (
<svg <svg
width={24} width={24}

View File

@ -1,6 +1,6 @@
import * as React from "react"; import * as React from "react";
function HomeIcon({ fill = "#6C7281", ...rest }) { function HomeIcon({fill = "#6C7281", ...rest}) {
return ( return (
<svg <svg
width={24} width={24}

View File

@ -1,6 +1,6 @@
import * as React from "react"; import * as React from "react";
function LockIcon({ fill = "#6C7281", ...rest }) { function LockIcon({fill = "#6C7281", ...rest}) {
return ( return (
<svg <svg
width={24} width={24}

View File

@ -1,14 +1,14 @@
import * as React from "react"; import * as React from "react";
function Logo({ fill = "#3B81F6", ...rest }) { function Logo({fill = "#3B81F6", ...rest}) {
return ( return (
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" <svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="40.000000pt" height="40.000000pt" viewBox="0 0 500.000000 500.000000" width="40.000000pt" height="40.000000pt" viewBox="0 0 500.000000 500.000000"
preserveAspectRatio="xMidYMid meet"> preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,500.000000) scale(0.100000,-0.100000)" <g transform="translate(0.000000,500.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none"> fill="#000000" stroke="none">
<path d="M3020 4444 c-138 -12 -603 -47 -855 -64 -159 -11 -371 -27 -470 -35 <path d="M3020 4444 c-138 -12 -603 -47 -855 -64 -159 -11 -371 -27 -470 -35
-99 -8 -283 -21 -410 -30 -500 -33 -538 -40 -595 -98 -71 -71 -65 49 -65 -99 -8 -283 -21 -410 -30 -500 -33 -538 -40 -595 -98 -71 -71 -65 49 -65
-1387 l0 -1295 42 -80 c24 -44 85 -134 136 -200 51 -66 182 -235 291 -375 223 -1387 l0 -1295 42 -80 c24 -44 85 -134 136 -200 51 -66 182 -235 291 -375 223
-288 253 -315 357 -330 35 -5 96 -7 134 -4 39 2 295 18 570 34 748 45 1638 98 -288 253 -315 357 -330 35 -5 96 -7 134 -4 39 2 295 18 570 34 748 45 1638 98
@ -24,7 +24,7 @@ c9 -5 24 -28 32 -51 15 -39 16 -158 14 -1233 -3 -1116 -4 -1192 -21 -1222 -23
-820 -50 -853 -50 -900 -5 -17 16 -35 45 -41 65 -6 23 -9 431 -7 1217 3 1181 -820 -50 -853 -50 -900 -5 -17 16 -35 45 -41 65 -6 23 -9 431 -7 1217 3 1181
3 1182 24 1210 11 15 32 33 46 40 13 7 108 17 214 23 104 6 374 22 599 35 226 3 1182 24 1210 11 15 32 33 46 40 13 7 108 17 214 23 104 6 374 22 599 35 226
14 457 27 515 30 58 3 290 17 515 31 757 46 734 45 777 23z"/> 14 457 27 515 30 58 3 290 17 515 31 757 46 734 45 777 23z"/>
<path d="M1950 3121 l0 -140 88 -3 87 -3 3 -766 c2 -759 2 -766 -18 -792 -23 <path d="M1950 3121 l0 -140 88 -3 87 -3 3 -766 c2 -759 2 -766 -18 -792 -23
-30 -74 -47 -137 -47 l-43 0 0 -130 0 -130 503 0 c622 0 729 11 901 94 204 99 -30 -74 -47 -137 -47 l-43 0 0 -130 0 -130 503 0 c622 0 729 11 901 94 204 99
310 264 323 503 15 278 -97 443 -376 550 -22 8 -19 11 42 51 151 98 227 240 310 264 323 503 15 278 -97 443 -376 550 -22 8 -19 11 42 51 151 98 227 240
227 422 -1 270 -146 439 -434 502 -83 18 -139 21 -628 25 l-538 5 0 -141z 227 422 -1 270 -146 439 -434 502 -83 18 -139 21 -628 25 l-538 5 0 -141z
@ -33,8 +33,8 @@ m1030 -185 c63 -24 116 -62 142 -105 20 -31 23 -49 23 -141 0 -98 -2 -109 -30
252 -22z m-7 -861 c165 -35 250 -124 272 -285 8 -56 -10 -161 -35 -211 -28 252 -22z m-7 -861 c165 -35 250 -124 272 -285 8 -56 -10 -161 -35 -211 -28
-54 -102 -114 -173 -140 -56 -20 -85 -23 -289 -27 l-228 -4 0 341 0 341 193 0 -54 -102 -114 -173 -140 -56 -20 -85 -23 -289 -27 l-228 -4 0 341 0 341 193 0
c128 0 215 -5 260 -15z"/> c128 0 215 -5 260 -15z"/>
</g> </g>
</svg> </svg>
); );
} }

View File

@ -1,6 +1,6 @@
import * as React from "react"; import * as React from "react";
function LogoutIcon({ fill = "#6C7281", ...rest }) { function LogoutIcon({fill = "#6C7281", ...rest}) {
return ( return (
<svg <svg
width={16} width={16}
@ -13,7 +13,7 @@ function LogoutIcon({ fill = "#6C7281", ...rest }) {
d="M8 19c4.411 0 8-3.589 8-8 0-3.35-2.072-6.22-5-7.41v2.222A6 6 0 0114 11c0 3.31-2.691 6-6 6s-6-2.69-6-6a5.999 5.999 0 013-5.188V3.59C2.072 4.78 0 7.65 0 11c0 4.411 3.589 8 8 8z" d="M8 19c4.411 0 8-3.589 8-8 0-3.35-2.072-6.22-5-7.41v2.222A6 6 0 0114 11c0 3.31-2.691 6-6 6s-6-2.69-6-6a5.999 5.999 0 013-5.188V3.59C2.072 4.78 0 7.65 0 11c0 4.411 3.589 8 8 8z"
fill={fill} fill={fill}
/> />
<path d="M7 0h2v10H7V0z" fill={fill} /> <path d="M7 0h2v10H7V0z" fill={fill}/>
</svg> </svg>
); );
} }

View File

@ -1,6 +1,6 @@
import * as React from "react"; import * as React from "react";
function ManageIcon({ fill = "#6C7281", ...rest }) { function ManageIcon({fill = "#6C7281", ...rest}) {
return ( return (
<svg <svg
width={24} width={24}

View File

@ -1,6 +1,6 @@
import * as React from "react"; import * as React from "react";
function OptionsIcon({ fill = "#6C7281", ...rest }) { function OptionsIcon({fill = "#6C7281", ...rest}) {
return ( return (
<svg <svg
width={24} width={24}

View File

@ -1,6 +1,6 @@
import * as React from "react"; import * as React from "react";
function PublicIcon({ fill = "#6C7281", ...rest }) { function PublicIcon({fill = "#6C7281", ...rest}) {
return ( return (
<svg <svg
width={24} width={24}

View File

@ -1,6 +1,6 @@
import * as React from "react"; import * as React from "react";
function SearchIcon({ fill = "#6C7281", ...rest }) { function SearchIcon({fill = "#6C7281", ...rest}) {
return ( return (
<svg <svg
width={24} width={24}

View File

@ -1,6 +1,6 @@
import * as React from "react"; import * as React from "react";
function ShareIcon({ fill = "#6C7281", ...rest }) { function ShareIcon({fill = "#6C7281", ...rest}) {
return ( return (
<svg <svg
width={24} width={24}

View File

@ -1,6 +1,6 @@
import * as React from "react"; import * as React from "react";
function UsersIcon({ stroke = "#6C7281", ...rest }) { function UsersIcon({stroke = "#6C7281", ...rest}) {
return ( return (
<svg <svg
width={24} width={24}

View File

@ -1,6 +1,6 @@
import * as React from "react"; import * as React from "react";
function VideosIcon({ fill = "#6C7281", ...rest }) { function VideosIcon({fill = "#6C7281", ...rest}) {
return ( return (
<svg <svg
width={24} width={24}
@ -10,7 +10,7 @@ function VideosIcon({ fill = "#6C7281", ...rest }) {
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
{...rest} {...rest}
> >
<path d="M4 8H2v12a2 2 0 002 2h12v-2H4V8z" fill={fill} /> <path d="M4 8H2v12a2 2 0 002 2h12v-2H4V8z" fill={fill}/>
<path <path
d="M20 2H8a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V4a2 2 0 00-2-2zm-9 12V6l7 4-7 4z" d="M20 2H8a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V4a2 2 0 00-2-2zm-9 12V6l7 4-7 4z"
fill={fill} fill={fill}

View File

@ -1,16 +1,16 @@
export { default as ArticleIcon } from "./ArticleIcon"; export {default as ArticleIcon} from "./ArticleIcon";
export { default as HomeIcon } from "./HomeIcon"; export {default as HomeIcon} from "./HomeIcon";
export { default as UsersIcon } from "./UsersIcon"; export {default as UsersIcon} from "./UsersIcon";
export { default as VideosIcon } from "./VideosIcon"; export {default as VideosIcon} from "./VideosIcon";
export { default as CollapsIcon } from "./CollapsIcon"; export {default as CollapsIcon} from "./CollapsIcon";
export { default as LogoIcon } from "./Logo"; export {default as LogoIcon} from "./Logo";
export { default as LogoutIcon } from "./LogoutIcon"; export {default as LogoutIcon} from "./LogoutIcon";
export { default as SearchIcon } from "./SearchIcon"; export {default as SearchIcon} from "./SearchIcon";
export { default as ShareIcon } from "./ShareIcon"; export {default as ShareIcon} from "./ShareIcon";
export { default as LockIcon } from "./LockIcon"; export {default as LockIcon} from "./LockIcon";
export { default as PublicIcon } from "./PublicIcon"; export {default as PublicIcon} from "./PublicIcon";
export { default as DeleteIcon } from "./DeleteIcon"; export {default as DeleteIcon} from "./DeleteIcon";
export { default as OptionsIcon } from "./OptionsIcon"; export {default as OptionsIcon} from "./OptionsIcon";
export { default as ManageIcon } from "./ManageIcon"; export {default as ManageIcon} from "./ManageIcon";
export { default as CreateIcon } from "./CreateIcon"; export {default as CreateIcon} from "./CreateIcon";

View File

@ -1,4 +1,4 @@
import { Server } from "socket.io"; import {Server} from "socket.io";
import messageHandler from "../../utils/sockets/messageHandler"; import messageHandler from "../../utils/sockets/messageHandler";
export default function SocketHandler(req, res) { export default function SocketHandler(req, res) {

View File

@ -39,13 +39,17 @@ export default function CreateDocument() {
return ( return (
<Layout> <Layout>
<div className="flex items-center justify-center w-full h-full"> <div className="flex items-center justify-center w-full h-full">
<form onSubmit={handleSubmit} className="flex items-center justify-center align-center w-full h-full login-form" style={{flexDirection: "column"}}> <form onSubmit={handleSubmit}
className="flex items-center justify-center align-center w-full h-full login-form"
style={{flexDirection: "column"}}>
<div> <div>
<input type="text" id="name" name="name" required placeholder="name" <input type="text" id="name" name="name" required placeholder="name"
style={{border: "1px solid grey", color: "black", padding: "2px 4px"}}/> style={{border: "1px solid grey", color: "black", padding: "2px 4px"}}/>
</div> </div>
<button type="submit" className="rounded bg-pink-600 rounded" style={{border: "1px solid grey", padding: "4px"}}>Create</button> <button type="submit" className="rounded bg-pink-600 rounded"
style={{border: "1px solid grey", padding: "4px"}}>Create
</button>
</form> </form>
</div> </div>
</Layout> </Layout>

View File

@ -1,6 +1,6 @@
import io from "socket.io-client"; import io from "socket.io-client";
import { useState, useEffect } from "react"; import {useState, useEffect} from "react";
import { useRouter } from "next/router"; import {useRouter} from "next/router";
import Layout from "../../components/Layout"; import Layout from "../../components/Layout";
import { import {
OptionsIcon, OptionsIcon,
@ -101,7 +101,7 @@ export default function Document() {
<OptionsIcon onClick={(e) => { <OptionsIcon onClick={(e) => {
document.getElementById("myDropdown").classList.toggle("show"); document.getElementById("myDropdown").classList.toggle("show");
window.onclick = function(event) { window.onclick = function (event) {
if (!event.target.matches('.dropbtn')) { if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content"); var dropdowns = document.getElementsByClassName("dropdown-content");
var i; var i;
@ -111,14 +111,26 @@ export default function Document() {
openDropdown.classList.remove('show'); openDropdown.classList.remove('show');
} }
} }
}}}} className="dropbtn"></OptionsIcon> }
}
}} className="dropbtn"></OptionsIcon>
<div id="myDropdown" className="dropdown-content"> <div id="myDropdown" className="dropdown-content">
<Link href={access}> <Link href={access}>
<div className="flex flex-row items-center justify-start align-center menu-opt"><ManageIcon/><span>Manage access</span></div> <div className="flex flex-row items-center justify-start align-center menu-opt">
<ManageIcon/><span>Manage access</span></div>
</Link> </Link>
<a href="#"><div className="flex flex-row items-center justify-start align-center menu-opt"><ShareIcon/><span>Share</span></div></a> <a href="#">
<a href="#"><div className="flex flex-row items-center justify-start align-center menu-opt"><LockIcon/><span>Public/private</span></div></a> <div className="flex flex-row items-center justify-start align-center menu-opt"><ShareIcon/><span>Share</span>
<a href="#"><div className="flex flex-row items-center justify-start align-center menu-opt"><DeleteIcon/><span>Delete document</span></div></a> </div>
</a>
<a href="#">
<div className="flex flex-row items-center justify-start align-center menu-opt">
<LockIcon/><span>Public/private</span></div>
</a>
<a href="#">
<div className="flex flex-row items-center justify-start align-center menu-opt">
<DeleteIcon/><span>Delete document</span></div>
</a>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,5 +1,5 @@
import React, { useState, useEffect } from "react"; import React, {useState, useEffect} from "react";
import { useRouter } from "next/router"; import {useRouter} from "next/router";
import Layout from "../../../components/Layout"; import Layout from "../../../components/Layout";
import { import {
OptionsIcon, OptionsIcon,
@ -78,7 +78,7 @@ export default function Document() {
<th>Username</th> <th>Username</th>
<th>Access</th> <th>Access</th>
</tr> </tr>
{users.map(({ icon: Icon, ...user }) => { {users.map(({icon: Icon, ...user}) => {
return ( return (
<> <>
<tr style={{color: "black"}}> <tr style={{color: "black"}}>
@ -100,7 +100,9 @@ export default function Document() {
style={{border: "1px solid grey", color: "black", padding: "2px 4px"}}/> style={{border: "1px solid grey", color: "black", padding: "2px 4px"}}/>
</div> </div>
<button type="submit" className="rounded bg-pink-600 rounded" style={{border: "1px solid grey", padding: "4px"}}>Create</button> <button type="submit" className="rounded bg-pink-600 rounded"
style={{border: "1px solid grey", padding: "4px"}}>Create
</button>
{/*</form>*/} {/*</form>*/}
</div> </div>
</> </>

View File

@ -38,7 +38,9 @@ export default function Login() {
return ( return (
<div className="flex items-center justify-center w-full h-full" style={{marginTop: "30%"}}> <div className="flex items-center justify-center w-full h-full" style={{marginTop: "30%"}}>
<form onSubmit={handleSubmit} className="flex items-center justify-center align-center w-full h-full login-form" style={{flexDirection: "column"}}> <form onSubmit={handleSubmit}
className="flex items-center justify-center align-center w-full h-full login-form"
style={{flexDirection: "column"}}>
<div> <div>
<input type="text" id="username" name="username" required placeholder="username" <input type="text" id="username" name="username" required placeholder="username"
style={{border: "1px solid grey", color: "black", padding: "2px 4px"}}/> style={{border: "1px solid grey", color: "black", padding: "2px 4px"}}/>
@ -48,7 +50,9 @@ export default function Login() {
style={{border: "1px solid grey", color: "black", padding: "2px 4px"}}/> style={{border: "1px solid grey", color: "black", padding: "2px 4px"}}/>
</div> </div>
<button type="submit" className="rounded bg-pink-600 rounded" style={{border: "1px solid grey", padding: "4px"}}>Log in</button> <button type="submit" className="rounded bg-pink-600 rounded"
style={{border: "1px solid grey", padding: "4px"}}>Log in
</button>
</form> </form>
</div> </div>
); );

View File

@ -49,7 +49,7 @@
background-color: white; background-color: white;
min-width: 220px; min-width: 220px;
overflow: auto; overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
right: 0; right: 0;
z-index: 1; z-index: 1;
} }
@ -61,9 +61,13 @@
display: block; display: block;
} }
.dropdown a:hover {background-color: #ddd;} .dropdown a:hover {
background-color: #ddd;
}
.show {display: block;} .show {
display: block;
}
svg { svg {

View File

@ -3,7 +3,7 @@ export default (io, socket) => {
socket.to(room).emit("newIncomingText", text); socket.to(room).emit("newIncomingText", text);
}; };
socket.on('create', function(room) { socket.on('create', function (room) {
socket.join(room); socket.join(room);
}); });

File diff suppressed because it is too large Load Diff

2
run.sh
View File

@ -14,7 +14,7 @@ EOF
} }
RUN= RUN=
while getopts "hadic" OPTION; do while getopts "hadicf" OPTION; do
case $OPTION in case $OPTION in
a) RUN=api ;; a) RUN=api ;;
d) RUN=docker ;; d) RUN=docker ;;