diff --git a/frontend/components/News/articleSet.tsx b/frontend/components/News/articleSet.tsx index c4db5fe57..ef669882b 100644 --- a/frontend/components/News/articleSet.tsx +++ b/frontend/components/News/articleSet.tsx @@ -11,6 +11,7 @@ type NewsPageProps = { loading?: boolean; setLoading?: (loading: boolean) => void; small?: boolean + nollning?: boolean }; export default function ArticleSet({ @@ -20,11 +21,14 @@ export default function ArticleSet({ loading, setLoading, small, + nollning = false, }: NewsPageProps) { const { error, data, refetch, } = useNewsPageQuery({ - variables: { page_number: pageIndex, per_page: articlesPerPage, tagIds }, + variables: { + page_number: pageIndex, per_page: articlesPerPage, tagIds, nollning, + }, onCompleted: () => { if (setLoading) setLoading(false); }, diff --git a/frontend/components/Nolla/Article.tsx b/frontend/components/Nolla/Article.tsx new file mode 100644 index 000000000..f68c80c6b --- /dev/null +++ b/frontend/components/Nolla/Article.tsx @@ -0,0 +1,133 @@ +import EditOutlinedIcon from '@mui/icons-material/EditOutlined'; +import { + Avatar, + Box, + Button, + IconButton, + Paper, + Stack, + Typography, + useMediaQuery, +} from '@mui/material'; +import { DateTime } from 'luxon'; +import { useTranslation } from 'next-i18next'; +import { useRef, useState } from 'react'; +import Markdown from '~/components/Markdown'; +import { + authorIsUser, + getAuthor, + getSignature, +} from '~/functions/authorFunctions'; +import { timeAgo } from '~/functions/datetimeFunctions'; +import selectTranslation from '~/functions/selectTranslation'; +import { + ArticleQuery, + ArticleRequestStatus, + Author, +} from '~/generated/graphql'; +import { hasAccess, useApiAccess } from '~/providers/ApiAccessProvider'; +import { useUser } from '~/providers/UserProvider'; +import routes from '~/routes'; +import Link from '../Link'; +import articleStyles from '~/components/News/articleStyles'; + +type ArticleProps = { + article: ArticleQuery['article']; +}; + +const getNollaNewsAuthor = (i18n: any, author: Partial) => { + if (author.__typename === 'Member') { + return getSignature(author); + } + const { name, nameEn } = author.position; + return selectTranslation(i18n, name, nameEn); +}; + +export default function Article({ article }: ArticleProps) { + const classes = articleStyles(); + const { t, i18n } = useTranslation('common'); + const date = DateTime.fromISO( + article.status === ArticleRequestStatus.Approved + ? article.publishedDatetime + : article.createdDatetime, + ).setLocale(i18n.language); + const apiContext = useApiAccess(); + const { user } = useUser(); + const [expanded, setExpanded] = useState(false); + const markdownRef = useRef(null); + + const markdown = selectTranslation(i18n, article.body, article.bodyEn); + const isScreenLarge = useMediaQuery((theme: any) => + theme.breakpoints.up('md')); + + const topPart = ( + + {/* Avatar and name */} + + + + {getNollaNewsAuthor(i18n, article.author)} + {timeAgo(date)} + + + + {/* Edit button */} + {(hasAccess(apiContext, 'news:article:update') + || authorIsUser(article.author, user)) && ( + + + + + + )} + + ); + + return ( + + + + {topPart} + + + {/* Body */} + + + + + + {/* Read more button */} + + + + ); +} diff --git a/frontend/pages/nolla/news.tsx b/frontend/pages/nolla/news.tsx new file mode 100644 index 000000000..6ec8dd23e --- /dev/null +++ b/frontend/pages/nolla/news.tsx @@ -0,0 +1,78 @@ +import AddIcon from '@mui/icons-material/Add'; +import { + Alert, Box, Button, Pagination, Typography, +} from '@mui/material'; +import { useTranslation } from 'next-i18next'; +import { useRouter } from 'next/router'; +import { useEffect } from 'react'; +import Article from '~/components/Nolla/Article'; +import NollaLayout from '~/components/Nolla/layout'; +import theme from '~/components/Nolla/theme'; +import genGetProps from '~/functions/genGetServerSideProps'; +import { useNewsPageQuery } from '~/generated/graphql'; +import { hasAccess, useApiAccess } from '~/providers/ApiAccessProvider'; +import routes from '~/routes'; + +const ARTICLES_PER_PAGE = 10; + +export default function News() { + const apiContext = useApiAccess(); + const router = useRouter(); + const { t } = useTranslation('common'); + const currentPage = parseInt(router.query.page as string, 10) || 1; + const { data } = useNewsPageQuery({ + variables: { + page_number: currentPage, + per_page: ARTICLES_PER_PAGE, + nollning: true, + }, + }); + const totalPages = data?.news?.pageInfo?.totalPages || 1; + const articles = data?.news?.articles || []; + + // restrict access during development + useEffect(() => { + if (!apiContext.apisLoading && !apiContext.hasAccess('nolla:news')) { + router.push(routes.root); + } + }, [apiContext, router]); + + return ( + + + This page is under construction! + + + {hasAccess(apiContext, 'news:article:create') && ( + + )} + + {articles.map((article) => + (article ? ( +
+ ) : ( +
{t('news:articleError.missing')}
+ )))} + + router.push(`?page=${page}`)} + /> + + ); +} + +export const getServerSideProps = genGetProps(['nolla', 'news']); + +News.getLayout = function getLayout({ children }) { + return {children}; +}; + +News.theme = theme; diff --git a/frontend/public/images/nolla/nollning_logo_small.png b/frontend/public/images/nolla/nollning_logo_small.png new file mode 100644 index 000000000..b6ffb2efe Binary files /dev/null and b/frontend/public/images/nolla/nollning_logo_small.png differ diff --git a/frontend/public/locales/en/common.json b/frontend/public/locales/en/common.json index 71d0966c1..180e3feca 100644 --- a/frontend/public/locales/en/common.json +++ b/frontend/public/locales/en/common.json @@ -23,6 +23,7 @@ "next": "Next", "back": "Back", "read_more": "Read more", + "minimize": "Minimize", "sign in": "Sign in", "sign out": "Sign out", "register": "Register", diff --git a/frontend/public/locales/sv/common.json b/frontend/public/locales/sv/common.json index 0b1dc246e..833f0552c 100644 --- a/frontend/public/locales/sv/common.json +++ b/frontend/public/locales/sv/common.json @@ -23,6 +23,7 @@ "next": "Nästa", "back": "Tillbaka", "read_more": "Läs mer", + "minimize": "Minimera", "sign in": "Logga in", "sign out": "Logga ut", "register": "Registrera dig",