Skip to content

Commit

Permalink
Merge pull request #11 from LinumLabs/feature/dm/FAIR-102-main-page
Browse files Browse the repository at this point in the history
Add PodSideBar
  • Loading branch information
MostertCoder authored Feb 7, 2022
2 parents a167f46 + b72fa2a commit e8ab526
Show file tree
Hide file tree
Showing 18 changed files with 341 additions and 5 deletions.
66 changes: 66 additions & 0 deletions src/api/pod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import axios from '@api/customAxios';
export interface GetPodResponse {
pod_name: string[];
shared_pod_name: string[];
}

export interface PodFilesResponse {
files: string[];
dirs: string;
}
export async function getPods(): Promise<GetPodResponse> {
return (await axios.get('pod/ls')).data;
}

export async function openPod(
pod_name: string,
password: string
): Promise<void> {
return await axios.post('pod/open', {
pod_name,
password,
});
}
export async function createPod(pod_name: string, password: string) {
return await axios.post('pod/new', {
pod_name,
password,
});
}
export async function receivePod(podReference: string) {
return await axios.get(
`pod/receive?sharing_ref=${podReference}&ref=${podReference}`
);
}

export async function getFilesAndDirectories(
pod_name: string,
directory: string
): Promise<PodFilesResponse> {
let data = { dir_path: '', pod_name: pod_name };

if (directory === 'root') {
data = {
dir_path: '/',
pod_name: pod_name,
};
} else {
data = {
dir_path: '/' + directory,
pod_name: pod_name,
};
}
const response = (
await axios({
baseURL: process.env.NEXT_PUBLIC_FAIROSHOST,
method: 'GET',
url: 'dir/ls',
params: data,
headers: {
'Content-Type': 'application/json',
},
withCredentials: true,
})
).data;
return response;
}
29 changes: 29 additions & 0 deletions src/components/Layouts/MainLayout/MainLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { FC, ReactChild } from 'react';

import { MainNavigationBar, PodSideBar } from '@components/NavigationBars';

interface MainLayoutProps {
children: ReactChild | ReactChild[];
}

const MainLayout: FC<MainLayoutProps> = ({ children }) => {
return (
<div className="w-screen h-screen bg-white overflow-hidden">
<div className="fixed top-0 left-0 w-full h-16">
<MainNavigationBar />
</div>

<div className="flex justify-items-stretch items-stretch w-full h-full mt-16 overflow-hidden">
<div className="w-68 h-full">
<PodSideBar />
</div>

<div className="w-full pt-10 overflow-scroll no-scroll-bar">
{children}
</div>
</div>
</div>
);
};

export default MainLayout;
3 changes: 2 additions & 1 deletion src/components/Layouts/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import AuthenticationLayout from '@components/Layouts/AuthenticationLayout/AuthenticationLayout';
import MainLayout from '@components/Layouts/MainLayout/MainLayout';

export { AuthenticationLayout };
export { AuthenticationLayout, MainLayout };
36 changes: 36 additions & 0 deletions src/components/NavigationBars/PodSideBar/PodItem/PodItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { FC } from 'react';

import ArrowRight from '@media/UI/arrow-right.svg';

interface PodItemProps {
podName: string;
isActivePod: boolean;
onClick: () => void;
}

const PodItem: FC<PodItemProps> = ({ podName, isActivePod, onClick }) => {
return (
<div
onClick={onClick}
className={`${
isActivePod
? 'bg-white border-r-3 border-color-accents-purple-heavy shadow-active-pod-item'
: 'shadow-sm'
} flex justify-between items-center w-full py-5 px-4 cursor-pointer`}
>
<span
className={`text-main-purple ${
isActivePod ? 'font-semibold' : 'font-normal'
}`}
>
{podName}
</span>

<span>
<ArrowRight className="inline-block ml-2" />
</span>
</div>
);
};

export default PodItem;
65 changes: 65 additions & 0 deletions src/components/NavigationBars/PodSideBar/PodSideBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/* eslint-disable react-hooks/exhaustive-deps */

import { FC, useContext, useEffect } from 'react';

import PodContext from '@context/PodContext';
import UserContext from '@context/UserContext';

import { getPods, openPod } from '@api/pod';

import PodItem from '@components/NavigationBars/PodSideBar/PodItem/PodItem';

import sortAlphabetically from 'src/utils/sortAlphabetically';

const DriveSideBar: FC = () => {
const { pods, setPods, activePod, setActivePod, openPods, setOpenPods } =
useContext(PodContext);
const { password } = useContext(UserContext);

useEffect(() => {
if (!pods) {
handleFetchPods();
}
}, []);

const handleFetchPods = () => {
getPods()
.then((response) => {
setPods(response);
})
.catch(() => console.log('Error: Pods could not be fetched!'));
};

const handleOpenPod = (podName: string) => {
if (!openPods.includes(podName)) {
openPod(podName, password)
.then(() => {
setOpenPods([...openPods, podName]);
})
.catch(() => console.log('Error: Pod could not be opened!'));
}

setActivePod(podName);
};

return (
<div className="w-56 h-full px-5 bg-white shadow-xl overflow-scroll no-scroll-bar">
<h2 className="my-6 font-semibold text-2xl text-main-purple">
Your Pods
</h2>

<div className="mt-5 mb-16 text-center shadow-pod-item">
{sortAlphabetically(pods?.pod_name).map((pod: string) => (
<PodItem
key={pod}
podName={pod}
isActivePod={pod === activePod}
onClick={() => handleOpenPod(pod)}
/>
))}
</div>
</div>
);
};

export default DriveSideBar;
3 changes: 2 additions & 1 deletion src/components/NavigationBars/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import MainNavigationBar from '@components/NavigationBars/MainNavigationBar/MainNavigationBar';
import PodSideBar from '@components/NavigationBars/PodSideBar/PodSideBar';

export { MainNavigationBar };
export { MainNavigationBar, PodSideBar };
70 changes: 70 additions & 0 deletions src/context/PodContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable @typescript-eslint/no-empty-function */
import { GetPodResponse } from '@api/pod';
import { FC, ReactNode, createContext, useState } from 'react';

interface PodContext {
pods: GetPodResponse;
setPods: (pods: GetPodResponse) => void;
activePod: string;
setActivePod: (pod: string) => void;
openPods: string[];
setOpenPods: (openPods: string[]) => void;
directoryName: string;
setDirectoryName: (directoryName: string) => void;
clearPodContext: () => void;
}

interface PodContextProps {
children: ReactNode;
}

const podContextDefaultValues: PodContext = {
pods: { pod_name: [], shared_pod_name: [] },
setPods: (pods: GetPodResponse) => {},
activePod: '',
setActivePod: (pod: string) => {},
openPods: [],
setOpenPods: (openPods: string[]) => {},
directoryName: '',
setDirectoryName: (directoryName: string) => {},
clearPodContext: () => {},
};

const PodContext = createContext<PodContext>(podContextDefaultValues);

const PodProvider: FC<PodContextProps> = ({ children }) => {
const [pods, setPods] = useState(null);
const [activePod, setActivePod] = useState('');
const [openPods, setOpenPods] = useState([]);
const [directoryName, setDirectoryName] = useState('');

const clearPodContext = () => {
setPods(null);
setActivePod('');
setOpenPods([]);
setDirectoryName('');
};

return (
<PodContext.Provider
value={{
pods,
setPods,
activePod,
setActivePod,
openPods,
setOpenPods,
directoryName,
setDirectoryName,
clearPodContext,
}}
>
{children}
</PodContext.Provider>
);
};

export default PodContext;

export { PodProvider };
3 changes: 3 additions & 0 deletions src/media/UI/arrow-right-active.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/media/UI/arrow-right.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 6 additions & 3 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import { AppProps } from 'next/app';

import { UserProvider } from '@context/UserContext';
import { PodProvider } from '@context/PodContext';
import { SearchProvider } from '@context/SearchContext';

import '@styles/globals.scss';

function MyApp({ Component, pageProps }: AppProps) {
return (
<UserProvider>
<SearchProvider>
<Component {...pageProps} />
</SearchProvider>
<PodProvider>
<SearchProvider>
<Component {...pageProps} />
</SearchProvider>
</PodProvider>
</UserProvider>
);
}
Expand Down
10 changes: 10 additions & 0 deletions src/pages/gallery/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* eslint-disable react-hooks/exhaustive-deps */
import { FC } from 'react';

import { MainLayout } from '@components/Layouts';

const Gallery: FC = () => {
return <MainLayout>Coming Soon</MainLayout>;
};

export default Gallery;
7 changes: 7 additions & 0 deletions src/utils/formatDate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import moment from 'moment';

export default function formatDate(date: string, withTime?: boolean) {
return withTime
? moment.unix(parseInt(date)).format('DD/MM/YYYY HH:mm:ss')
: moment.unix(parseInt(date)).format('DD/MM/YYYY');
}
5 changes: 5 additions & 0 deletions src/utils/formatDirectory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import formatURL from '@utils/formatURL';

export default function writePath(directory: string): string {
return directory === 'root' ? '/' : '/' + formatURL(directory) + '/';
}
3 changes: 3 additions & 0 deletions src/utils/formatURL.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function formatURL(path: string): string {
return path.replace(/&/g, '/');
}
7 changes: 7 additions & 0 deletions src/utils/generateMnemonic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { ethers } from 'ethers';

export default async function generateMnemonic(): Promise<ethers.utils.Mnemonic> {
const mnemonic = await ethers.Wallet.createRandom().mnemonic;

return mnemonic;
}
10 changes: 10 additions & 0 deletions src/utils/shortenString.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default function shortenString(
title: string,
maxLength: number
): string {
if (title.length > maxLength) {
return `${title.slice(0, 10)}...${title.slice(title.length - 10)}`;
} else {
return title;
}
}
14 changes: 14 additions & 0 deletions src/utils/sortAlphabetically.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default function sortAlphabetically(list: string[]): string[] {
if (!list || list.length === 0) {
return [];
}

list.sort((a: string, b: string) => {
if (a < b) return -1;
if (a > b) return 1;

return 0;
});

return list;
}
3 changes: 3 additions & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ module.exports = {
'dark-purple': ' 0px 0px 15px 0px #7D6BECC4',
'dark-active': '0px 4px 4px 0px #362F68',
'light-active': '0px 0px 5px 0px #5C568540',
'pod-item': '0px 0px 18px rgba(92, 86, 133, 0.18)',
'active-pod-item':
'0px 0px 30px rgba(92, 86, 133, 0.3), inset -4px 0px 0px #434D7E',
},
backgroundImage: {
'auth-light': "url('/media/authentication/authentication-light.svg')",
Expand Down

0 comments on commit e8ab526

Please sign in to comment.