Skip to content

Commit

Permalink
Merge pull request #341 from vevcom/feat/committee-page
Browse files Browse the repository at this point in the history
Feat/committee page
  • Loading branch information
JohanHjelsethStorstad authored Oct 12, 2024
2 parents bc64f60 + faa4b2e commit 0dea340
Show file tree
Hide file tree
Showing 30 changed files with 724 additions and 82 deletions.
33 changes: 30 additions & 3 deletions src/actions/groups/committees/read.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
'use server'
import { createActionError } from '@/actions/error'
import { getUser } from '@/auth/getUser'
import { readCommittee, readCommittees } from '@/services/groups/committees/read'
import {
readCommittee,
readCommitteeArticle,
readCommitteeParagraph,
readCommittees
} from '@/services/groups/committees/read'
import { safeServerCall } from '@/actions/safeServerCall'
import type { ExpandedCommittee } from '@/services/groups/committees/Types'
import type { ExpandedArticle } from '@/services/cms/articles/Types'
import type { ExpandedCommittee, ExpandedCommitteeWithCover } from '@/services/groups/committees/Types'
import type { ActionReturn } from '@/actions/Types'
import type { CmsParagraph } from '@prisma/client'

/**
* Reads all committees
Expand All @@ -23,7 +30,7 @@ export async function readCommitteeAction(
data: {
shortName: string
},
): Promise<ActionReturn<ExpandedCommittee>> {
): Promise<ActionReturn<ExpandedCommitteeWithCover>> {
const { authorized, status } = await getUser({
requiredPermissions: [['COMMITTEE_READ']]
})
Expand All @@ -32,3 +39,23 @@ export async function readCommitteeAction(

return await safeServerCall(() => readCommittee(data))
}

export async function readCommitteeArticleAction(shortName: string): Promise<ActionReturn<ExpandedArticle>> {
const { authorized, status } = await getUser({
requiredPermissions: [['COMMITTEE_READ']]
})

if (!authorized) return createActionError(status)

return await safeServerCall(() => readCommitteeArticle(shortName))
}

export async function readCommitteeParagraphAction(shortName: string): Promise<ActionReturn<CmsParagraph>> {
const { authorized, status } = await getUser({
requiredPermissions: [['COMMITTEE_READ']]
})

if (!authorized) return createActionError(status)

return await safeServerCall(() => readCommitteeParagraph(shortName))
}
18 changes: 15 additions & 3 deletions src/app/_components/BackdropImage/BackdropImage.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
translate: 40% 0;
right: 0;
bottom: 0;
z-index: 1;
z-index: -1;
width: 400px;
height: 400px;
opacity: 0.5;
opacity: 0.0;
display: flex;
align-items: flex-end;
animation: fadein 1s ease-in forwards;
animation-delay: 1s;

* {
width: 100% !important;
}
Expand All @@ -25,6 +28,15 @@


.content {
z-index: 2;
z-index: 1;
}
}

@keyframes fadein {
0% {
opacity: 0;
}
100% {
opacity: 0.5;
}
}
5 changes: 5 additions & 0 deletions src/app/_components/Cms/Article/Article.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ $padding: ohma.$minimalPagePadding;
margin-bottom: 1em;
}
}
&.noMargin {
> * {
margin: 0;
}
}

//This makes sure the the confirmation for deletion does not lay underneath section
@for $i from 1 through 15 {
Expand Down
22 changes: 13 additions & 9 deletions src/app/_components/Cms/Article/Article.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,23 @@ import type { ExpandedArticle } from '@/cms/articles/Types'

export type PropTypes = {
article: ExpandedArticle,
coverImageClass?: string
coverImageClass?: string,
hideCoverImage?: boolean
noMargin?: boolean
}

export default function Article({ article, coverImageClass }: PropTypes) {
export default function Article({ article, coverImageClass, hideCoverImage = false, noMargin = false }: PropTypes) {
return (
<span className={styles.Article}>
<span className={`${coverImageClass} ${styles.coverImage}`}>
<CmsImage width={500} cmsImage={article.coverImage} />
<SlideInOnView direction="bottom">
<ChangeName article={article} />
</SlideInOnView>
</span>
<article>
{hideCoverImage ? <></> : (
<span className={`${coverImageClass} ${styles.coverImage}`}>
<CmsImage width={500} cmsImage={article.coverImage} />
<SlideInOnView direction="bottom">
<ChangeName article={article} />
</SlideInOnView>
</span>
)}
<article className={noMargin ? styles.noMargin : undefined}>
{
article.articleSections.length ? (
article.articleSections.sort((a, b) => (a.order - b.order)).map((section, i) => (
Expand Down
120 changes: 120 additions & 0 deletions src/app/_components/CommitteeCard/CommitteeCard.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
@use "@/styles/ohma";

$padding: 1.5em;
$imageHeight: 175px;
$contentHeight: 50px;
$height: $imageHeight + $contentHeight;

$background: lighten(ohma.$colors-secondary, 15%);
$textBoxTransparency: 60%;
$textColor: ohma.$colors-gray-900;
$textUnderlineColor: ohma.$colors-secondary;
$textBoxBackgroundColor: ohma.$colors-white;

.CommitteeCard {
width: 100%;
aspect-ratio: 1/1;
border-radius: 50%;
padding: 0px;
position: relative;
color: inherit;
text-decoration: none;
display: block;
background-color: $background;
isolation: isolate;
overflow: hidden;
box-shadow: ohma.$colors-gray-800 0 0 10px;
@include ohma.screenMobile {
width: 100%;
}

&:hover {
@include ohma.screenMobile {
scale: 1;
}
scale: 1.1;
transition-duration: 0.3s;

> .image {
@include ohma.screenMobile {
scale: 1;
}
scale: 1.1;
transition: scale 0.3s;
}

> .content {
@include ohma.screenMobile {
background-color: rgba($textBoxBackgroundColor, 60%);
box-shadow: ohma.$colors-secondary 0 0 40px;
padding-top: $padding
}
background-color: rgba($textBoxBackgroundColor, 0%);
box-shadow: ohma.$colors-secondary 0 0 0px;
padding-top: 10px;

> h2 {
@include ohma.screenMobile {
opacity: 100%;
}
opacity: 0%;
}
}
}

> .image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
transition: scale 0.3s;

> * {
width: 100% !important;
height: 100%;
object-fit: cover;

img {
width: 100% !important;
height: 100%;
object-fit: cover;
}
}

&::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: radial-gradient(ellipse at center top, transparent 40%, $background 70%, $background 100%);
scale: 1.5 1;
z-index: 0;
}
}

> .content {
z-index: 2;
position: absolute;
border-radius: calc(ohma.$cardRounding - $padding);
background-color: rgba($textBoxBackgroundColor, $textBoxTransparency);
width: 100%;
padding: $padding;
bottom: 5%;
height: $contentHeight;
box-shadow: ohma.$colors-secondary 0 0 40px;
color: $textColor;
transition: 0.3s;
overflow: hidden;

> h2 {
opacity: 100%;
text-align: center;
text-decoration-color: $textUnderlineColor;
margin-bottom: ohma.$gap;
}
}
}
30 changes: 30 additions & 0 deletions src/app/_components/CommitteeCard/CommitteeCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import styles from './CommitteeCard.module.scss'
import Image from '@/components/Image/Image'
import Link from 'next/link'
import type { Image as ImageT } from '@prisma/client'
import type { ReactNode } from 'react'

type PropTypes = {
image: ImageT | null,
title: string,
children?: ReactNode,
href: string
}

export default function CommitteeCard({ image, title, children, href }: PropTypes) {
return (
<Link href={href} className={styles.CommitteeCard}>
<div className={styles.image}>
{
image && (
<Image width={240} image={image} />
)
}
</div>
<div className={styles.content}>
<h2>{title}</h2>
{children}
</div>
</Link>
)
}
97 changes: 97 additions & 0 deletions src/app/_components/CommitteeImage/CommitteeImage.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
@use "@/styles/ohma";

$background: lighten(ohma.$colors-secondary, 15%);

.CommitteeImage {
position: relative;
width: 100vw;
height: 300px;
overflow: hidden;
box-shadow: ohma.$colors-secondary 0 0 75px;
margin-bottom: 3rem;
@include ohma.screenMobile {
height: 150px;
animation: none;
}

.image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 275px;
object-fit: cover;
z-index: 1;
transform: scale(0.9);
transform-origin: top left;
animation: loading 1s ease-in-out forwards;
animation-delay: 1s;
pointer-events: none;

@include ohma.screenMobile {
transform: scale(0.4);
animation: none;
animation: loadingMobile 1s ease-in-out forwards;
animation-delay: 1s;
}
}

.images {
position: relative;
width: auto;
height: auto;
}

.committeeImage {
position: absolute;
top: 0;
left: 0;
z-index: 0;
> * {
width: 100vw !important;
img {
width: 100vw !important;
height: 300px;
object-fit: cover;
object-position: center;
background-size: cover;
}
}

@include ohma.screenMobile {
height: 150px;
animation: none;
}
}

.content {
position: relative;
z-index: 2;
margin: 0 auto;
max-width: 800px;
}
}

.image-container {
width: 100vw;
max-width: 100%;
height: 100%;
}

@keyframes loading {
0% {
transform: scale(0.9);
}
100% {
transform: scale(1.0);
}
}

@keyframes loadingMobile {
0% {
transform: scale(0.4);
}
100% {
transform: scale(0.5);
}
}
Loading

0 comments on commit 0dea340

Please sign in to comment.