From 15ff02ccef8b18cac7b5a47ee71534d11a2f95bf Mon Sep 17 00:00:00 2001
From: Ricardo Costa
Date: Tue, 25 Jun 2024 16:04:41 +0100
Subject: [PATCH] Refactoring & Bug Fixes
---
code/client/src/App.tsx | 8 ++---
code/client/src/contexts/auth/AuthContext.tsx | 3 ++
.../contexts/workspace/WorkspaceContext.tsx | 2 +-
.../src/services/commits/commitsService.ts | 6 ++--
.../src/ui/components/header/Header.scss | 9 ++++-
.../src/ui/components/header/Header.tsx | 19 ++++++++---
.../ui/components/popup-menu/PopupMenu.tsx | 26 ++++++++------
.../src/ui/components/sidebar/Sidebar.tsx | 22 +++++++-----
.../workspace-tree/TreeResourceView.tsx | 6 ++--
.../commit-history/CommitHistory.tsx | 34 +++++++++++--------
.../floating-buttons/FloatingButtons.tsx | 4 ++-
code/client/src/ui/pages/home/Home.tsx | 28 +++++++--------
.../Landing.scss => login/Login.scss} | 2 +-
.../{landing/Landing.tsx => login/Login.tsx} | 17 +++++-----
code/client/src/ui/pages/search/Search.tsx | 18 ++++++----
.../http/handlers/commitsHandlers.ts | 6 ++--
.../http/handlers/workspacesHandlers.ts | 10 +++---
.../ws/events/workspace/onJoinWorkspace.ts | 4 +--
code/server/src/services/DocumentsService.ts | 4 +--
19 files changed, 135 insertions(+), 93 deletions(-)
rename code/client/src/ui/pages/{landing/Landing.scss => login/Login.scss} (98%)
rename code/client/src/ui/pages/{landing/Landing.tsx => login/Login.tsx} (74%)
diff --git a/code/client/src/App.tsx b/code/client/src/App.tsx
index bf7a72ed..9e165527 100644
--- a/code/client/src/App.tsx
+++ b/code/client/src/App.tsx
@@ -3,7 +3,6 @@ import Document from '@ui/pages/document/Document';
import Header from '@ui/components/header/Header';
import Workspace from '@ui/pages/workspace/Workspace';
import NotFound from '@ui/pages/notfound/NotFound';
-import './App.scss';
import { ErrorProvider } from '@/contexts/error/ErrorContext';
import Sidebar from '@ui/components/sidebar/Sidebar';
import { WorkspaceProvider } from '@/contexts/workspace/WorkspaceContext';
@@ -12,10 +11,11 @@ import { CommunicationProvider } from '@/contexts/communication/CommunicationCon
import Home from '@ui/pages/home/Home';
import AuthProvider from '@/contexts/auth/AuthContext';
import Profile from '@ui/pages/profile/Profile';
-import Landing from '@ui/pages/landing/Landing';
+import Login from '@ui/pages/login/Login';
import Search from '@ui/pages/search/Search';
import CommitHistory from '@ui/pages/document/components/commit-history/CommitHistory';
import Commit from '@ui/pages/document/components/commit/Commit';
+import './App.scss';
function App() {
return (
@@ -27,9 +27,9 @@ function App() {
- } />
+ } />
diff --git a/code/client/src/contexts/auth/AuthContext.tsx b/code/client/src/contexts/auth/AuthContext.tsx
index 8df89094..6cff5b3e 100644
--- a/code/client/src/contexts/auth/AuthContext.tsx
+++ b/code/client/src/contexts/auth/AuthContext.tsx
@@ -7,6 +7,7 @@ import { useNavigate } from 'react-router-dom';
export type AuthContextType = {
currentUser: User | null;
+ isLoggedIn: boolean;
loginWithGoogle: () => Promise;
loginWithGithub: () => Promise;
logout: () => Promise;
@@ -15,6 +16,7 @@ export type AuthContextType = {
export const AuthContext = createContext({
currentUser: null,
+ isLoggedIn: false,
loginWithGoogle: async () => {},
loginWithGithub: async () => {},
logout: async () => {},
@@ -69,6 +71,7 @@ export function AuthProvider({ children }: AuthProviderProps) {
({});
diff --git a/code/client/src/services/commits/commitsService.ts b/code/client/src/services/commits/commitsService.ts
index 2b54a3d0..82afc478 100644
--- a/code/client/src/services/commits/commitsService.ts
+++ b/code/client/src/services/commits/commitsService.ts
@@ -11,8 +11,8 @@ function commitsService(http: HttpCommunication, errorHandler: ErrorHandler, wid
return errorHandler(async () => await http.post(`/workspaces/${wid}/${id}/rollback`, { commitId }));
}
- async function fork(commitId: string) {
- return errorHandler(async () => await http.post(`/workspaces/${wid}/${id}/fork`, { commitId }));
+ async function clone(commitId: string) {
+ return errorHandler(async () => await http.post(`/workspaces/${wid}/${id}/clone`, { commitId }));
}
async function getCommits(): Promise {
@@ -26,7 +26,7 @@ function commitsService(http: HttpCommunication, errorHandler: ErrorHandler, wid
return {
commit,
rollback,
- fork,
+ clone,
getCommits,
getCommit,
};
diff --git a/code/client/src/ui/components/header/Header.scss b/code/client/src/ui/components/header/Header.scss
index 4633bba4..60083cee 100644
--- a/code/client/src/ui/components/header/Header.scss
+++ b/code/client/src/ui/components/header/Header.scss
@@ -25,9 +25,16 @@
align-items: center;
margin-right: 1rem;
gap: 2vh;
+ padding-left: 10vh;
+ padding-right: 2vh;
button {
- padding: 1vh;
+ padding: 1.5vh;
+ gap: 1vh;
+
+ svg {
+ font-size: larger;
+ }
}
}
diff --git a/code/client/src/ui/components/header/Header.tsx b/code/client/src/ui/components/header/Header.tsx
index dea92284..84e0ec88 100644
--- a/code/client/src/ui/components/header/Header.tsx
+++ b/code/client/src/ui/components/header/Header.tsx
@@ -2,6 +2,7 @@ import { useAuth } from '@/contexts/auth/useAuth';
import { Link, useLocation, useNavigate } from 'react-router-dom';
import { ChangeEvent, FormEvent, useState } from 'react';
import './Header.scss';
+import { MdLogin, MdLogout } from 'react-icons/md';
function Header() {
const { currentUser, logout } = useAuth();
@@ -20,9 +21,9 @@ function Header() {
return (
diff --git a/code/client/src/ui/components/popup-menu/PopupMenu.tsx b/code/client/src/ui/components/popup-menu/PopupMenu.tsx
index aa002a1c..d682b1fa 100644
--- a/code/client/src/ui/components/popup-menu/PopupMenu.tsx
+++ b/code/client/src/ui/components/popup-menu/PopupMenu.tsx
@@ -1,6 +1,7 @@
-import React, { ReactNode, useEffect, useState } from 'react';
+import React, { ReactNode, useCallback, useEffect, useState } from 'react';
import { Menu, PopoverPosition } from '@mui/material';
import './PopupMenu.scss';
+import useWorkspace from '@/contexts/workspace/useWorkspace';
type PopupMenuProps = {
item: ReactNode;
@@ -11,15 +12,20 @@ type PopupMenuProps = {
function PopupMenu({ item, trigger, children }: PopupMenuProps) {
const [anchorEl, setAnchorEl] = useState(null);
const [contextMenuPosition, setContextMenuPosition] = useState(null);
+ const { isMember } = useWorkspace();
- const onOpen = (event: MouseEvent | React.MouseEvent) => {
- event.preventDefault();
- setContextMenuPosition({
- left: event.clientX - 2,
- top: event.clientY - 4,
- });
- setAnchorEl(event.currentTarget as HTMLElement);
- };
+ const onOpen = useCallback(
+ (event: MouseEvent | React.MouseEvent) => {
+ event.preventDefault();
+ if (!isMember) return;
+ setContextMenuPosition({
+ left: event.clientX - 2,
+ top: event.clientY - 4,
+ });
+ setAnchorEl(event.currentTarget as HTMLElement);
+ },
+ [isMember]
+ );
const onClose = () => {
setAnchorEl(null);
@@ -34,7 +40,7 @@ function PopupMenu({ item, trigger, children }: PopupMenuProps) {
return () => {
triggerElement.removeEventListener('click', onOpen);
};
- }, [trigger]);
+ }, [onOpen, trigger]);
return (
{} : onOpen} onClick={onClose}>
diff --git a/code/client/src/ui/components/sidebar/Sidebar.tsx b/code/client/src/ui/components/sidebar/Sidebar.tsx
index 20491d45..a9d69543 100644
--- a/code/client/src/ui/components/sidebar/Sidebar.tsx
+++ b/code/client/src/ui/components/sidebar/Sidebar.tsx
@@ -9,11 +9,13 @@ import { TiHome } from 'react-icons/ti';
import { GoPlus } from 'react-icons/go';
import { ResourceType } from '@notespace/shared/src/workspace/types/resource';
import CreateResourceMenu from '@ui/components/sidebar/components/CreateResourceMenu';
+import { useAuth } from '@/contexts/auth/useAuth';
import './Sidebar.scss';
function Sidebar() {
const { width, isOpen, isLocked, isLoaded, handlers } = useSidebarState();
- const { workspace, resources, operations } = useWorkspace();
+ const { workspace, resources, operations, isMember } = useWorkspace();
+ const { isLoggedIn } = useAuth();
if (!isLoaded) return null;
return (
@@ -35,10 +37,12 @@ function Sidebar() {
Home
-
-
- Workspaces
-
+ {isLoggedIn && (
+
+
+ Workspaces
+
+ )}
Recent
@@ -58,9 +62,11 @@ function Sidebar() {
onCreateNew={(type: ResourceType) => operations.createResource('Untitled', type, workspace.id)}
trigger="sidebar-create-resource"
/>
-
+ {isMember && (
+
+ )}
>
diff --git a/code/client/src/ui/components/sidebar/components/workspace-tree/TreeResourceView.tsx b/code/client/src/ui/components/sidebar/components/workspace-tree/TreeResourceView.tsx
index 22c44fa2..3df0951f 100644
--- a/code/client/src/ui/components/sidebar/components/workspace-tree/TreeResourceView.tsx
+++ b/code/client/src/ui/components/sidebar/components/workspace-tree/TreeResourceView.tsx
@@ -8,6 +8,7 @@ import CreateResourceMenu from '@ui/components/sidebar/components/CreateResource
import { GoPlus } from 'react-icons/go';
import ResourceContextMenu from '@ui/pages/workspace/components/ResourceContextMenu';
import useEditing from '@ui/hooks/useEditing';
+import useWorkspace from '@/contexts/workspace/useWorkspace';
type TreeResourceViewProps = {
workspace: string;
@@ -34,6 +35,7 @@ function TreeResourceView({
onDrag,
onDrop,
}: TreeResourceViewProps) {
+ const { isMember } = useWorkspace();
const [isOpen, setIsOpen] = useState(true);
const { component, isEditing, setIsEditing } = useEditing(resource.name || 'Untitled', (name: string) =>
onRenameResource!(resource.id, name)
@@ -45,7 +47,7 @@ function TreeResourceView({
const props: React.HTMLProps = {
id: resource.id,
- draggable: true,
+ draggable: isMember,
onDragOver: (e: React.DragEvent) => e.preventDefault(),
onDragStart: onDrag,
onDrop: onDrop,
@@ -92,7 +94,7 @@ function TreeResourceView({
)}
- {!isEditing && (
+ {!isEditing && isMember && (
diff --git a/code/client/src/ui/pages/document/components/commit-history/CommitHistory.tsx b/code/client/src/ui/pages/document/components/commit-history/CommitHistory.tsx
index 23fc03cf..ce044687 100644
--- a/code/client/src/ui/pages/document/components/commit-history/CommitHistory.tsx
+++ b/code/client/src/ui/pages/document/components/commit-history/CommitHistory.tsx
@@ -1,4 +1,3 @@
-import './CommitHistory.scss';
import useCommitsService from '@services/commits/useCommitsService';
import { Link, useNavigate, useParams } from 'react-router-dom';
import useResourcesService from '@services/resource/useResourcesService';
@@ -7,8 +6,10 @@ import useLoading from '@ui/hooks/useLoading';
import { DocumentResource } from '@notespace/shared/src/workspace/types/resource';
import { Commit } from '@notespace/shared/src/document/types/commits';
import { formatTimePassed } from '@/utils/utils';
-import { FaCodeFork } from 'react-icons/fa6';
+import { FaClone } from 'react-icons/fa6';
import { FaUndo } from 'react-icons/fa';
+import useWorkspace from '@/contexts/workspace/useWorkspace';
+import './CommitHistory.scss';
function CommitHistory() {
const [document, setDocument] = useState();
@@ -16,7 +17,8 @@ function CommitHistory() {
const { loading, spinner, startLoading, stopLoading } = useLoading();
const { wid, id } = useParams();
const { getResource } = useResourcesService();
- const { getCommits, fork, rollback } = useCommitsService();
+ const { getCommits, clone, rollback } = useCommitsService();
+ const { isMember } = useWorkspace();
const navigate = useNavigate();
async function onRollback(commitId: string) {
@@ -24,8 +26,8 @@ function CommitHistory() {
navigate(`/workspaces/${wid}/${id}`);
}
- async function onFork(commitId: string) {
- await fork(commitId);
+ async function onClone(commitId: string) {
+ await clone(commitId);
navigate(`/workspaces/${wid}`);
}
@@ -59,16 +61,18 @@ function CommitHistory() {
{commit.author.name} committed{' '}
{formatTimePassed(new Date(commit.timestamp).toLocaleString())}
-
-
-
-
+ {isMember && (
+
+
+
+
+ )}
))
) : (
diff --git a/code/client/src/ui/pages/document/components/floating-buttons/FloatingButtons.tsx b/code/client/src/ui/pages/document/components/floating-buttons/FloatingButtons.tsx
index c60170d3..5ea470c6 100644
--- a/code/client/src/ui/pages/document/components/floating-buttons/FloatingButtons.tsx
+++ b/code/client/src/ui/pages/document/components/floating-buttons/FloatingButtons.tsx
@@ -3,14 +3,16 @@ import CommitDialog from '@ui/pages/document/components/floating-buttons/CommitD
import useCommitsService from '@services/commits/useCommitsService';
import { useNavigate, useParams } from 'react-router-dom';
import { MdHistory } from 'react-icons/md';
+import useWorkspace from '@/contexts/workspace/useWorkspace';
function FloatingButtons() {
const { wid, id } = useParams();
const { commit } = useCommitsService();
+ const { isMember } = useWorkspace();
const navigate = useNavigate();
return (
-
+ {isMember &&
}
diff --git a/code/client/src/ui/pages/home/Home.tsx b/code/client/src/ui/pages/home/Home.tsx
index 723192e2..9b0de680 100644
--- a/code/client/src/ui/pages/home/Home.tsx
+++ b/code/client/src/ui/pages/home/Home.tsx
@@ -23,21 +23,19 @@ function Home() {
return (
Home
-
Welcome to NoteSpace
-
Go to Workspaces
-
-
-
-
Public Workspaces
- {loading
- ? spinner
- : workspaces.map(workspace => (
-
-
- {workspace.name}
-
-
- ))}
+ {loading ? (
+ spinner
+ ) : workspaces.length > 0 ? (
+ workspaces.map(workspace => (
+
+
+ {workspace.name}
+
+
+ ))
+ ) : (
+
No workspaces yet
+ )}
);
}
diff --git a/code/client/src/ui/pages/landing/Landing.scss b/code/client/src/ui/pages/login/Login.scss
similarity index 98%
rename from code/client/src/ui/pages/landing/Landing.scss
rename to code/client/src/ui/pages/login/Login.scss
index 5c88741f..8c143d7f 100644
--- a/code/client/src/ui/pages/landing/Landing.scss
+++ b/code/client/src/ui/pages/login/Login.scss
@@ -1,4 +1,4 @@
-.landing {
+.login {
display: flex;
flex-direction: column;
justify-content: center;
diff --git a/code/client/src/ui/pages/landing/Landing.tsx b/code/client/src/ui/pages/login/Login.tsx
similarity index 74%
rename from code/client/src/ui/pages/landing/Landing.tsx
rename to code/client/src/ui/pages/login/Login.tsx
index 76c5d191..d5928a8f 100644
--- a/code/client/src/ui/pages/landing/Landing.tsx
+++ b/code/client/src/ui/pages/login/Login.tsx
@@ -3,20 +3,20 @@ import { useNavigate } from 'react-router-dom';
import { useEffect } from 'react';
import googleIcon from '@assets/images/google-icon.png';
import { FaGithub } from 'react-icons/fa6';
-import './Landing.scss';
+import './Login.scss';
-function Landing() {
- const { currentUser, loginWithGoogle, loginWithGithub } = useAuth();
+function Login() {
+ const { isLoggedIn, loginWithGoogle, loginWithGithub } = useAuth();
const navigate = useNavigate();
useEffect(() => {
- if (currentUser) {
- navigate('/home');
+ if (isLoggedIn) {
+ navigate('/');
}
- }, [currentUser, navigate]);
+ }, [isLoggedIn, navigate]);
return (
-
+
Welcome to NoteSpace
@@ -30,10 +30,9 @@ function Landing() {
-
Please choose a provider to continue
);
}
-export default Landing;
+export default Login;
diff --git a/code/client/src/ui/pages/search/Search.tsx b/code/client/src/ui/pages/search/Search.tsx
index b8008a7a..89fa3d2b 100644
--- a/code/client/src/ui/pages/search/Search.tsx
+++ b/code/client/src/ui/pages/search/Search.tsx
@@ -25,13 +25,17 @@ function Search() {
return (
Search results for "{query}"
- {results.map(workspace => (
-
-
- {workspace.name}
-
-
- ))}
+ {results.length > 0 ? (
+ results.map(workspace => (
+
+
+ {workspace.name}
+
+
+ ))
+ ) : (
+
No results found
+ )}