From d528e5a019aa4a1d1c32717d97ab077add900961 Mon Sep 17 00:00:00 2001 From: Hege Aalvik <48259307+hegeaal@users.noreply.github.com> Date: Fri, 6 Oct 2023 08:43:42 +0200 Subject: [PATCH] feat: add data to requests page (#1786) --- src/api/community-api/search.ts | 4 ++ src/components/with-community/index.tsx | 10 +++- .../with-community/redux/action-types.ts | 4 ++ .../with-community/redux/actions.ts | 36 +++++++++++- .../with-community/redux/reducer.ts | 11 +++- src/components/with-community/redux/saga.ts | 29 ++++++++-- src/pages/requests/index.tsx | 55 +++++++++++++++---- src/pages/requests/styled.ts | 45 ++++++++++++++- src/types/domain.d.ts | 21 +++++++ 9 files changed, 194 insertions(+), 21 deletions(-) diff --git a/src/api/community-api/search.ts b/src/api/community-api/search.ts index b85e5555d..c2117309c 100644 --- a/src/api/community-api/search.ts +++ b/src/api/community-api/search.ts @@ -24,6 +24,10 @@ export const getRecentPosts = (term: CommunityTerm) => .get(`${FDK_COMMUNITY_BASE_URI}/api/recent/posts/${term}`) .then(({ data }) => data); +export const getRequests = () => + axios + .get(`${FDK_COMMUNITY_BASE_URI}/api/category/6`) + .then(({ data }) => data); export const extractTopicsFromSearch = ( searchResponse: any ): CommunityTopic[] => { diff --git a/src/components/with-community/index.tsx b/src/components/with-community/index.tsx index 34fcc616d..1f60cb002 100644 --- a/src/components/with-community/index.tsx +++ b/src/components/with-community/index.tsx @@ -4,13 +4,18 @@ import { connect } from 'react-redux'; import * as actions from './redux/actions'; -import type { CommunityPost, CommunityTopic } from '../../types'; +import type { + CommunityPost, + CommunityRequestCategory, + CommunityTopic +} from '../../types'; export interface Props { topics: CommunityTopic[]; multiplePages: boolean; posts: CommunityPost[]; communityActions: typeof actions; + requests: CommunityRequestCategory; } const withCommunity = (Component: ComponentType) => { @@ -19,7 +24,8 @@ const withCommunity = (Component: ComponentType) => { const mapStateToProps = (state: any) => ({ topics: state.CommunityReducer.get('topics').toJS(), multiplePages: state.CommunityReducer.get('multiplePages'), - posts: state.CommunityReducer.get('posts').toJS() + posts: state.CommunityReducer.get('posts').toJS(), + requests: state.CommunityReducer.get('requests').toJS() }); const mapDispatchToProps = (dispatch: Dispatch) => ({ diff --git a/src/components/with-community/redux/action-types.ts b/src/components/with-community/redux/action-types.ts index 37ceb6928..f711add72 100644 --- a/src/components/with-community/redux/action-types.ts +++ b/src/components/with-community/redux/action-types.ts @@ -8,3 +8,7 @@ export const GET_RECENT_POSTS_FAILED = 'GET_RECENT_POSTS_FAILED' as const; export const RESET_TOPICS = 'RESET_TOPICS' as const; export const RESET_POSTS = 'RESET_POSTS' as const; + +export const GET_REQUESTS = 'GET_REQUESTS' as const; +export const GET_REQUESTS_SUCCEEDED = 'GET_REQUESTS_SUCCEEDED' as const; +export const GET_REQUESTS_FAILED = 'GET_REQUESTS_FAILED' as const; diff --git a/src/components/with-community/redux/actions.ts b/src/components/with-community/redux/actions.ts index b073e6e39..f3af3ae1b 100644 --- a/src/components/with-community/redux/actions.ts +++ b/src/components/with-community/redux/actions.ts @@ -6,10 +6,17 @@ import { GET_RECENT_POSTS_SUCCEEDED, GET_RECENT_POSTS_FAILED, RESET_TOPICS, - RESET_POSTS + RESET_POSTS, + GET_REQUESTS, + GET_REQUESTS_FAILED, + GET_REQUESTS_SUCCEEDED } from './action-types'; -import type { CommunityPost, CommunityTopic } from '../../../types'; +import type { + CommunityPost, + CommunityRequestCategory, + CommunityTopic +} from '../../../types'; import { CommunityTerm } from '../../../types/enums'; export function searchTopicsRequested(queryTerm: string) { @@ -69,6 +76,31 @@ export function getRecentPostsFailed(message: string) { } }; } +export function getCommunityRequests() { + return { + type: GET_REQUESTS + }; +} + +export function getCommunityRequestsSucceeded( + requests: CommunityRequestCategory +) { + return { + type: GET_REQUESTS_SUCCEEDED, + payload: { + requests + } + }; +} + +export function getCommunityRequestsFailed(message: string) { + return { + type: GET_REQUESTS_FAILED, + payload: { + message + } + }; +} export function resetTopics() { return { diff --git a/src/components/with-community/redux/reducer.ts b/src/components/with-community/redux/reducer.ts index 920f1a10a..1d6e29a62 100644 --- a/src/components/with-community/redux/reducer.ts +++ b/src/components/with-community/redux/reducer.ts @@ -9,7 +9,9 @@ import { GET_RECENT_POSTS_SUCCEEDED, GET_RECENT_POSTS_FAILED, RESET_TOPICS, - RESET_POSTS + RESET_POSTS, + GET_REQUESTS, + GET_REQUESTS_SUCCEEDED } from './action-types'; import type { Actions } from '../../../types'; @@ -17,7 +19,8 @@ import type { Actions } from '../../../types'; const initialState = fromJS({ topics: [], multiplePages: false, - posts: [] + posts: [], + requests: {} }); export default function reducer( @@ -41,6 +44,10 @@ export default function reducer( case GET_RECENT_POSTS_FAILED: case RESET_POSTS: return state.set('posts', fromJS([])); + case GET_REQUESTS: + return state.set('requests', fromJS([])); + case GET_REQUESTS_SUCCEEDED: + return state.set('requests', fromJS(action.payload.requests)); default: return state; } diff --git a/src/components/with-community/redux/saga.ts b/src/components/with-community/redux/saga.ts index 06df1a02d..0c6e19db3 100644 --- a/src/components/with-community/redux/saga.ts +++ b/src/components/with-community/redux/saga.ts @@ -2,7 +2,8 @@ import { all, call, put, takeLatest } from 'redux-saga/effects'; import { SEARCH_TOPICS_REQUESTED, - GET_RECENT_POSTS_REQUESTED + GET_RECENT_POSTS_REQUESTED, + GET_REQUESTS } from './action-types'; import * as actions from './actions'; @@ -11,10 +12,15 @@ import { getRecentPosts, getTopicById, pruneNodebbTemplateTags, - searchCommunity + searchCommunity, + getRequests } from '../../../api/community-api/search'; -import type { CommunityPost, CommunityTopic } from '../../../types'; +import type { + CommunityPost, + CommunityRequestCategory, + CommunityTopic +} from '../../../types'; function* searchTopicsRequested({ payload: { queryTerm } @@ -60,9 +66,24 @@ function* recentPostsRequested({ } } +function* getCommunityRequests() { + try { + const requests: CommunityRequestCategory = yield call(getRequests); + + if (requests !== null && requests !== undefined) { + yield put(actions.getCommunityRequestsSucceeded(requests)); + } else { + yield put(actions.getCommunityRequestsFailed('')); + } + } catch (e: any) { + yield put(actions.getCommunityRequestsFailed(e.message)); + } +} + export default function* saga() { yield all([ takeLatest(SEARCH_TOPICS_REQUESTED, searchTopicsRequested), - takeLatest(GET_RECENT_POSTS_REQUESTED, recentPostsRequested) + takeLatest(GET_RECENT_POSTS_REQUESTED, recentPostsRequested), + takeLatest(GET_REQUESTS, getCommunityRequests) ]); } diff --git a/src/pages/requests/index.tsx b/src/pages/requests/index.tsx index 28e30d5c1..3663d0689 100644 --- a/src/pages/requests/index.tsx +++ b/src/pages/requests/index.tsx @@ -1,10 +1,45 @@ -import React from 'react'; -import Banner from '../../components/banner'; -import localization from '../../lib/localization'; - -const RequestsPage = () => ( -
- -
-); -export default RequestsPage; +import React, { FC, useEffect } from 'react'; +import withCommunity, { + Props as CommunityProps +} from '../../components/with-community'; +import { compose } from 'redux'; +import withErrorBoundary from '../../components/with-error-boundary'; +import ErrorPage from '../error-page'; +import SC from './styled'; +import { formatDate } from '../../lib/date-utils'; + +interface Props extends CommunityProps {} + +const RequestsPage: FC = ({ + requests, + communityActions: { getCommunityRequests } +}) => { + useEffect(() => { + getCommunityRequests(); + }, []); + + return ( +
+ + Etterspørsler fra Datalandsbyen + Dato + Antall stemmer + Antall visninger + + {requests?.topics && + requests.topics.map(topic => ( + + {topic.title} + + {formatDate(new Date(topic.timestampISO))} + + {topic.upvotes} + {topic.viewcount} + + ))} +
+ ); +}; + +const enhance = compose(withCommunity, withErrorBoundary(ErrorPage)); +export default enhance(RequestsPage); diff --git a/src/pages/requests/styled.ts b/src/pages/requests/styled.ts index ff8b4c563..625ee773b 100755 --- a/src/pages/requests/styled.ts +++ b/src/pages/requests/styled.ts @@ -1 +1,44 @@ -export default {}; +import styled from 'styled-components'; + +const RequestRow = styled.div` + display: flex; + background-color: white; + width: 100%; + height: 90px; + margin-bottom: 10px; + border-radius: 8px; + border: solid 1px #d5d7d9; + padding-left: 37px; + padding-right: 37px; + align-items: center; + font-size: 18px; +`; + +const RequestsTitleRow = styled.div` + background-color: #d2eafd; + height: 57px; + border-radius: 8px; + display: flex; + align-items: center; + padding-left: 37px; + padding-right: 37px; + font-weight: bold; +`; + +const RequestTitle = styled.div` + width: 50%; + font-weight: bold; +`; + +const RequestInfo = styled.div` + width: 16%; + display: flex; + justify-content: center; +`; + +export default { + RequestRow, + RequestsTitleRow, + RequestTitle, + RequestInfo +}; diff --git a/src/types/domain.d.ts b/src/types/domain.d.ts index 818ec234e..ea0f257b1 100644 --- a/src/types/domain.d.ts +++ b/src/types/domain.d.ts @@ -1019,6 +1019,27 @@ export interface CommunityPost { multiplePages: boolean; } +export interface CommunityRequestCategory { + description: string; + name: string; + post_count: number; + topics: CommunityRequest[]; +} + +export interface CommunityRequest { + cid: number; + timestamp: number; + lastposttime: number; + lastposttimeISO: Date; + timestampISO: Date; + postcount: number; + title: string; + viewcount: number; + postercount: number; + downvotes: number; + upvotes: number; +} + export interface CommunityTeaser { pid: number; uid: number;