diff --git a/package.json b/package.json index f21abd9..b438f10 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,8 @@ "axios": "^1.1.3", "babel-loader": "8.2.5", "color": "4.2.0", + "dayjs": "^1.11.7", + "nanoid": "^4.0.1", "react": "18.2.0", "react-router-dom": "6.8.1", "react-scripts": "5.0.1", @@ -61,13 +63,10 @@ "devDependencies": { "@babel/core": "^7.19.3", "@babel/plugin-proposal-export-default-from": "^7.16.7", + "@babel/plugin-syntax-typescript": "7.18.6", "@babel/plugin-transform-runtime": "^7.19.6", "@babel/plugin-transform-typescript": "^7.16.8", - "@babel/plugin-syntax-typescript": "7.18.6", "@reduxjs/toolkit": "^1.8.6", - "@types/jest": "29.2.0", - "@types/node": "18.8.5", - "@types/react": "18.0.21", "@shopify/eslint-plugin": "42.0.1", "@storybook/addon-actions": "^6.4.18", "@storybook/addon-essentials": "^6.4.18", @@ -80,8 +79,11 @@ "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^14.4.3", - "@types/react-dom": "^18.0.6", "@types/color": "^3.0.3", + "@types/jest": "29.2.0", + "@types/node": "18.8.5", + "@types/react": "18.0.21", + "@types/react-dom": "^18.0.6", "@types/react-test-renderer": "^17.0.1", "@types/styled-components": "5.1.26", "@typescript-eslint/eslint-plugin": "^5.0.0", diff --git a/src/App.test.tsx b/src/App.test.tsx index 410dbe8..23a4ea3 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -11,6 +11,10 @@ const AppComponent = ( ); +jest.mock('nanoid', () => { + return { nanoid: () => '' }; +}); + const mockedUsedNavigate = jest.fn(); jest.mock('react-router-dom', () => ({ diff --git a/src/App.tsx b/src/App.tsx index d09927a..126fe5c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,7 +5,8 @@ import { Route, Routes, useNavigate } from 'react-router-dom'; import { StyledColumn, StyledContainer, StyledContent, StyledHeader, StyledOverlay } from './AppStyles'; import data from './data/index.json'; import { Button, Portefolio } from './components'; -import { ProjectsUI, ForumUI, ForumBody } from './pages'; +import { ProjectsUI, ForumOutlet, Threads } from './pages'; +import { ForumContextWrapper } from './pages/forum/context/forumContext'; export const App: React.FC = () => { const navigate = useNavigate(); @@ -54,8 +55,15 @@ export const App: React.FC = () => { } /> - }> - } /> + }> + + + + } + /> login wip} /> register wip} /> diff --git a/src/pages/forum/components/index.tsx b/src/pages/forum/components/index.tsx index cf1f0c6..e56d7d0 100644 --- a/src/pages/forum/components/index.tsx +++ b/src/pages/forum/components/index.tsx @@ -1,2 +1,3 @@ export * from './banner'; export * from './header'; +export * from './thread'; diff --git a/src/pages/forum/components/thread/index.tsx b/src/pages/forum/components/thread/index.tsx index fbbf566..d02f044 100644 --- a/src/pages/forum/components/thread/index.tsx +++ b/src/pages/forum/components/thread/index.tsx @@ -1,8 +1,12 @@ +import dayjs from 'dayjs'; import React from 'react'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { StyledContainer, StyledEnd, StyledMiddle, StyledStart } from './styles'; import { ThreadProps } from './types'; +dayjs.extend(relativeTime); + export const Thread: React.FC = ({ avatar, title, subtitle, sideSection }: ThreadProps) => { return ( @@ -14,7 +18,7 @@ export const Thread: React.FC = ({ avatar, title, subtitle, sideSec
{sideSection.replies}
{sideSection.views}
-
{new Date(sideSection.postTimeTracker).toLocaleDateString()}
+
{dayjs(sideSection.postTimeTracker).fromNow()}
); diff --git a/src/pages/forum/components/thread/styles.tsx b/src/pages/forum/components/thread/styles.tsx index 506bb02..6c1482f 100644 --- a/src/pages/forum/components/thread/styles.tsx +++ b/src/pages/forum/components/thread/styles.tsx @@ -1,7 +1,27 @@ import styled from 'styled-components'; -export const StyledContainer = styled.div``; +export const StyledContainer = styled.div` + display: flex; + gap: 32px; + padding: 16px; + flex: 1; + box-sizing: border-box; + background-color: #f7f7f7; + border: 1px solid #dddddd; + justify-content: space-between; + min-height: 100px; +`; -export const StyledStart = styled.div``; -export const StyledMiddle = styled.div``; -export const StyledEnd = styled.div``; +export const StyledStart = styled.div` + flex-direction: column; +`; + +export const StyledMiddle = styled.div` + display: flex; + flex-direction: column; + gap: 16px; +`; + +export const StyledEnd = styled.div` + flex-direction: column; +`; diff --git a/src/pages/forum/context/forumContext.tsx b/src/pages/forum/context/forumContext.tsx index 57faa6c..30a17c9 100644 --- a/src/pages/forum/context/forumContext.tsx +++ b/src/pages/forum/context/forumContext.tsx @@ -15,13 +15,12 @@ export const ForumContextWrapper: React.FC = ({ childr const value = useMemo( () => ({ - children, isLoggedIn, threads, setIsLoggedIn, setThreads }), - [children, isLoggedIn, threads, setThreads, setIsLoggedIn] + [isLoggedIn, threads, setThreads, setIsLoggedIn] ); return {children}; diff --git a/src/pages/forum/index.tsx b/src/pages/forum/index.tsx index f75aa48..cf12dc3 100644 --- a/src/pages/forum/index.tsx +++ b/src/pages/forum/index.tsx @@ -1,2 +1,2 @@ -export * from './pages'; -export { ForumBody } from './layout'; +export * from './pages/Outlet'; +export { Threads } from './pages/Threads'; diff --git a/src/pages/forum/layout/View/ViewRouter/index.tsx b/src/pages/forum/layout/Container/ViewRouter/index.tsx similarity index 100% rename from src/pages/forum/layout/View/ViewRouter/index.tsx rename to src/pages/forum/layout/Container/ViewRouter/index.tsx diff --git a/src/pages/forum/layout/View/index.tsx b/src/pages/forum/layout/Container/index.tsx similarity index 89% rename from src/pages/forum/layout/View/index.tsx rename to src/pages/forum/layout/Container/index.tsx index 92b2f4f..84a96cb 100644 --- a/src/pages/forum/layout/View/index.tsx +++ b/src/pages/forum/layout/Container/index.tsx @@ -4,7 +4,7 @@ import { Header } from '../../components'; import { StyledLayoutWrapper, StyledBody } from './styles'; -export const Layout = () => { +export const Container = () => { return (
diff --git a/src/pages/forum/layout/View/styles.tsx b/src/pages/forum/layout/Container/styles.tsx similarity index 100% rename from src/pages/forum/layout/View/styles.tsx rename to src/pages/forum/layout/Container/styles.tsx diff --git a/src/pages/forum/layout/ForumBody/index.tsx b/src/pages/forum/layout/ForumBody/index.tsx deleted file mode 100644 index 9786415..0000000 --- a/src/pages/forum/layout/ForumBody/index.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import React, { useContext } from 'react'; - -import { ForumContext, ForumContextWrapper } from '../../context/forumContext'; - -import { StyledContainer } from './styles'; - -export const ForumBody = () => { - const { threads } = useContext(ForumContext); - - return ( - - Forum Body - - ); -}; diff --git a/src/pages/forum/layout/ForumBody/styles.tsx b/src/pages/forum/layout/ForumBody/styles.tsx deleted file mode 100644 index b5b717f..0000000 --- a/src/pages/forum/layout/ForumBody/styles.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import styled from 'styled-components'; - -export const StyledContainer = styled.div` - display: flex; - flex: 1; - padding: 1rem; - overflow-y: auto; -`; diff --git a/src/pages/forum/layout/ThreadsView/index.tsx b/src/pages/forum/layout/ThreadsView/index.tsx new file mode 100644 index 0000000..8b2bf81 --- /dev/null +++ b/src/pages/forum/layout/ThreadsView/index.tsx @@ -0,0 +1,30 @@ +import { nanoid } from 'nanoid'; +import React, { useContext } from 'react'; + +import { Thread } from '../../components'; +import { ForumContext } from '../../context/forumContext'; + +import { StyledContainer, StyledSideSection, StyledThreadContainer } from './styles'; + +export const ThreadsView = () => { + const { threads } = useContext(ForumContext); + + return ( + + + {threads?.map((thread) => ( + + ))} + + +
sample
+
+
+ ); +}; diff --git a/src/pages/forum/layout/ThreadsView/styles.tsx b/src/pages/forum/layout/ThreadsView/styles.tsx new file mode 100644 index 0000000..5dc0ed5 --- /dev/null +++ b/src/pages/forum/layout/ThreadsView/styles.tsx @@ -0,0 +1,26 @@ +import styled from 'styled-components'; + +export const StyledContainer = styled.div` + display: flex; + flex: 1; + padding: 1rem 10rem; + overflow-y: auto; + gap: 16px; +`; + +export const StyledThreadContainer = styled.div` + display: flex; + flex-direction: column; + flex: 1; + gap: 16px; +`; + +export const StyledSideSection = styled.div` + display: flex; + flex-direction: column; + min-width: 300px; + padding: 16px; + gap: 16px; + background-color: #f7f7f7; + border: 1px solid #dddddd; +`; diff --git a/src/pages/forum/layout/index.tsx b/src/pages/forum/layout/index.tsx index a822bcd..3c8fc1c 100644 --- a/src/pages/forum/layout/index.tsx +++ b/src/pages/forum/layout/index.tsx @@ -1 +1,2 @@ -export * from './ForumBody'; +export * from './ThreadsView'; +export { Container } from './Container'; diff --git a/src/pages/forum/pages/Outlet/index.tsx b/src/pages/forum/pages/Outlet/index.tsx new file mode 100644 index 0000000..8d86c52 --- /dev/null +++ b/src/pages/forum/pages/Outlet/index.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +import { Container } from '../../layout'; + +export const ForumOutlet = () => { + return ; +}; diff --git a/src/pages/forum/pages/Threads/index.tsx b/src/pages/forum/pages/Threads/index.tsx new file mode 100644 index 0000000..1d75e5c --- /dev/null +++ b/src/pages/forum/pages/Threads/index.tsx @@ -0,0 +1,16 @@ +import React, { useContext, useEffect } from 'react'; + +import { ForumContext, ForumContextWrapper } from '../../context/forumContext'; +import { ThreadsView } from '../../layout'; +import { mockedThreads } from '../../shared/mockData'; + +export const Threads = () => { + const { setThreads } = useContext(ForumContext); + + useEffect(() => { + setThreads(mockedThreads); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return ; +}; diff --git a/src/pages/forum/pages/index.tsx b/src/pages/forum/pages/index.tsx deleted file mode 100644 index a20a9b8..0000000 --- a/src/pages/forum/pages/index.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import React from 'react'; - -import { Layout } from '../layout/View'; - -export const ForumUI = () => { - return ; -}; diff --git a/src/pages/forum/shared/mockData.ts b/src/pages/forum/shared/mockData.ts new file mode 100644 index 0000000..a790d0d --- /dev/null +++ b/src/pages/forum/shared/mockData.ts @@ -0,0 +1,124 @@ +import { IThread } from '../context/contextType'; + +export const mockedThreads: IThread[] = [ + { + avatar: 'avatar url', + title: 'title of the thread', + subtitle: 'Subtitle of the thread', + sideSection: { + postTimeTracker: new Date(1231231313545), + replies: Math.floor(Math.random() * 10000) + 1, + views: Math.floor(Math.random() * 10000) + 1 + } + }, + { + avatar: 'avatar url', + title: 'title of the thread', + subtitle: 'Subtitle of the thread', + sideSection: { + postTimeTracker: new Date(1674153241555), + replies: Math.floor(Math.random() * 10000) + 1, + views: Math.floor(Math.random() * 10000) + 1 + } + }, + { + avatar: 'avatar url', + title: 'title of the thread', + subtitle: 'Subtitle of the thread', + sideSection: { + postTimeTracker: new Date(1676153241555), + replies: Math.floor(Math.random() * 10000) + 1, + views: Math.floor(Math.random() * 10000) + 1 + } + }, + { + avatar: 'avatar url', + title: 'title of the thread', + subtitle: 'Subtitle of the thread', + sideSection: { + postTimeTracker: new Date(1676153241555), + replies: Math.floor(Math.random() * 10000) + 1, + views: Math.floor(Math.random() * 10000) + 1 + } + }, + { + avatar: 'avatar url', + title: 'title of the thread', + subtitle: 'Subtitle of the thread', + sideSection: { + postTimeTracker: new Date(1674153241555), + replies: Math.floor(Math.random() * 10000) + 1, + views: Math.floor(Math.random() * 10000) + 1 + } + }, + { + avatar: 'avatar url', + title: 'title of the thread', + subtitle: 'Subtitle of the thread', + sideSection: { + postTimeTracker: new Date(1674153241555), + replies: Math.floor(Math.random() * 10000) + 1, + views: Math.floor(Math.random() * 10000) + 1 + } + }, + { + avatar: 'avatar url', + title: 'title of the thread', + subtitle: 'Subtitle of the thread', + sideSection: { + postTimeTracker: new Date(1231231313545), + replies: Math.floor(Math.random() * 10000) + 1, + views: Math.floor(Math.random() * 10000) + 1 + } + }, + { + avatar: 'avatar url', + title: 'title of the thread', + subtitle: 'Subtitle of the thread', + sideSection: { + postTimeTracker: new Date(1674153241555), + replies: Math.floor(Math.random() * 10000) + 1, + views: Math.floor(Math.random() * 10000) + 1 + } + }, + { + avatar: 'avatar url', + title: 'title of the thread', + subtitle: 'Subtitle of the thread', + sideSection: { + postTimeTracker: new Date(1676153241555), + replies: Math.floor(Math.random() * 10000) + 1, + views: Math.floor(Math.random() * 10000) + 1 + } + }, + { + avatar: 'avatar url', + title: 'title of the thread', + subtitle: 'Subtitle of the thread', + sideSection: { + postTimeTracker: new Date(1676153241555), + replies: Math.floor(Math.random() * 10000) + 1, + views: Math.floor(Math.random() * 10000) + 1 + } + }, + { + avatar: 'avatar url', + title: 'title of the thread', + subtitle: 'Subtitle of the thread', + sideSection: { + postTimeTracker: new Date(1674153241555), + replies: Math.floor(Math.random() * 10000) + 1, + views: Math.floor(Math.random() * 10000) + 1 + } + }, + { + avatar: 'avatar url', + title: 'title of the thread', + subtitle: 'Subtitle of the thread', + sideSection: { + postTimeTracker: new Date(1674153241555), + replies: Math.floor(Math.random() * 10000) + 1, + views: Math.floor(Math.random() * 10000) + 1 + } + } +]; diff --git a/src/pages/index.ts b/src/pages/index.ts index 7dc8166..f717b87 100644 --- a/src/pages/index.ts +++ b/src/pages/index.ts @@ -1,2 +1,2 @@ export { ProjectsUI } from './projects'; -export { ForumUI, ForumBody } from './forum'; +export { ForumOutlet, Threads } from './forum'; diff --git a/yarn.lock b/yarn.lock index 5dc0883..f489776 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6481,6 +6481,11 @@ data-urls@^3.0.2: whatwg-mimetype "^3.0.0" whatwg-url "^11.0.0" +dayjs@^1.11.7: + version "1.11.7" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.7.tgz#4b296922642f70999544d1144a2c25730fce63e2" + integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ== + debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -11319,6 +11324,11 @@ nanoid@^3.3.1, nanoid@^3.3.4: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== +nanoid@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-4.0.1.tgz#398d7ccfdbf9faf2231b2ca7e8fff5dbca6a509b" + integrity sha512-udKGtCCUafD3nQtJg9wBhRP3KMbPglUsgV5JVsXhvyBs/oefqb4sqMEhKBBgqZncYowu58p1prsZQBYvAj/Gww== + nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"