Skip to content

Commit

Permalink
Merge pull request #337 from vevcom/feat/event-tags
Browse files Browse the repository at this point in the history
Feat/event tags
  • Loading branch information
JohanHjelsethStorstad authored Oct 12, 2024
2 parents 0dea340 + 639092b commit 7f7159b
Show file tree
Hide file tree
Showing 57 changed files with 1,230 additions and 221 deletions.
58 changes: 58 additions & 0 deletions src/actions/Action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { createZodActionError } from './error'
import { safeServerCall } from './safeServerCall'
import { Session } from '@/auth/Session'
import type { SessionMaybeUser } from '@/auth/Session'
import type { ServiceMethod } from '@/services/ServiceTypes'

export function Action<
TypeType,
DetailedType,
Params,
Return,
WantsToOpenTransaction extends boolean,
NoAuther extends boolean
>(serviceMethod: ServiceMethod<
true,
TypeType,
DetailedType,
Params,
Return,
WantsToOpenTransaction,
NoAuther
>) {
return async (params: Params, rawData: FormData) => {
const session = await Session.fromNextAuth()
const parse = serviceMethod.typeValidate(rawData)
if (!parse.success) return createZodActionError(parse)
const data = parse.data
const config: { session: SessionMaybeUser, params: Params, data: DetailedType } = { session, params, data }
return {
...(await safeServerCall(() => serviceMethod.client('NEW').execute(config, { withAuth: true }))),
session: session.toJsObject()
}
}
}

export function ActionNoData<
Params,
Return,
WantsToOpenTransaction extends boolean,
NoAuther extends boolean
>(serviceMethod: ServiceMethod<
false,
never,
never,
Params,
Return,
WantsToOpenTransaction,
NoAuther
>) {
return async (params: Params) => {
const session = await Session.fromNextAuth()
const config: { session: SessionMaybeUser, params: Params, data: unknown } = { session, params, data: {} }
return {
...(await safeServerCall(() => serviceMethod.client('NEW').execute(config, { withAuth: true }))),
session: session.toJsObject()
}
}
}
2 changes: 2 additions & 0 deletions src/actions/events/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import { safeServerCall } from '@/actions/safeServerCall'
import { Session } from '@/auth/Session'

export async function createEventAction(rawData: FormData) {
console.log('createEventAction')
const parse = Events.create.typeValidate(rawData)
if (!parse.success) return createZodActionError(parse)
const data = parse.data
console.log('createEventAction', data)

const session = await Session.fromNextAuth()

Expand Down
17 changes: 3 additions & 14 deletions src/actions/events/read.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
'use server'
import { ActionNoData } from '@/actions/Action'
import { safeServerCall } from '@/actions/safeServerCall'
import { Session } from '@/auth/Session'
import { Events } from '@/services/events'
import type { ReadPageInput } from '@/services/paging/Types'
import type { EventArchiveCursor, EventArchiveDetails } from '@/services/events/Types'

export async function readCurrentEvents() {
const session = await Session.fromNextAuth()
return await safeServerCall(() => Events.readCurrent.client('NEW').execute({
params: { tags: null, visibilityFilter: {} }, session,
}))
}
export const readCurrentEventsAction = ActionNoData(Events.readCurrent)

export async function readEvent(params: {order: number, name: string}) {
const session = await Session.fromNextAuth()
return await safeServerCall(() => Events.read.client('NEW').execute({ params, session }))
}

export async function readArchivedEventsPage<const PageSize extends number>(
paging: ReadPageInput<PageSize, EventArchiveCursor, EventArchiveDetails>
) {
const session = await Session.fromNextAuth()
return await safeServerCall(() => Events.readArchivedPage.client('NEW').execute({ session, params: { paging } }))
}
export const readArchivedEventsPage = ActionNoData(Events.readArchivedPage)
5 changes: 5 additions & 0 deletions src/actions/events/tags/create.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use server'
import { EventTags } from '@/services/events/tags'
import { Action } from '@/actions/Action'

export const createEventTagAction = Action(EventTags.create)
5 changes: 5 additions & 0 deletions src/actions/events/tags/destroy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use server'
import { ActionNoData } from '@/actions/Action'
import { EventTags } from '@/services/events/tags'

export const destroyEventTagAction = ActionNoData(EventTags.destroy)
6 changes: 6 additions & 0 deletions src/actions/events/tags/read.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use server'
import { ActionNoData } from '@/actions/Action'
import { EventTags } from '@/services/events/tags'

export const readEventTagsAction = ActionNoData(EventTags.readAll)
export const readEventTagAction = ActionNoData(EventTags.read)
5 changes: 5 additions & 0 deletions src/actions/events/tags/update.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use server'
import { Action } from '@/actions/Action'
import { EventTags } from '@/services/events/tags'

export const updateEventTagAction = Action(EventTags.update)
17 changes: 14 additions & 3 deletions src/app/_components/Event/EventCard.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,19 @@ $imgHeight: $height / 2.5;
background-color: lighten(ohma.$colors-secondary, 40%);
border-radius: ohma.$cardRounding;
padding: 3em;
h2 {
font-size: ohma.$fonts-xl;
margin: 0.5em 0;
.topInfo {
display: flex;
align-items: center;
gap: 0 1em;
h2 {
font-size: ohma.$fonts-xl;
margin: 0.5em 0;
}
ul {
display: flex;
gap: 0 .3em;
list-style-type: none;
}
}

}
16 changes: 13 additions & 3 deletions src/app/_components/Event/EventCard.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import styles from './EventCard.module.scss'
import SmallEventTag from './SmallEventTag'
import Image from '@/components/Image/Image'
import React from 'react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faCalendar, faUsers } from '@fortawesome/free-solid-svg-icons'
import Link from 'next/link'
import type { EventFilteredWithImage } from '@/services/events/Types'
import type { EventExpanded } from '@/services/events/Types'

type PropTypes = {
event: EventFilteredWithImage
event: EventExpanded
}

export default function EventCard({ event }: PropTypes) {
Expand All @@ -25,7 +26,16 @@ export default function EventCard({ event }: PropTypes) {
/> : <FontAwesomeIcon icon={faCalendar} />
}
</div>
<h2>{event.name}</h2>
<div className={styles.topInfo}>
<h2>{event.name}</h2>
<ul className={styles.tags}>
{event.tags.map(tag => (
<li key={tag.id}>
<SmallEventTag eventTag={tag} />
</li>
))}
</ul>
</div>
<ul>
<li>
<FontAwesomeIcon icon={faCalendar} />
Expand Down
44 changes: 44 additions & 0 deletions src/app/_components/Event/EventTag.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
@use '@/styles/ohma';

.EventTag {
width: 100px;
height: 50px;
padding: .5em;
border-radius: 50px;
position: relative;
display: flex;
align-items: center;
.description {
padding: 1em;
border-radius: 1em;
background-color: ohma.$colors-gray-400;
color: ohma.$colors-black;
position: absolute;
bottom: 0;
left: 50%;
transform: translate(-50%, calc(100% + 10px));
display: none;
&::before {
content: '';
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%, -100%);
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 10px solid ohma.$colors-gray-400;
border-top: 0;
}
}
.name {
width: 100%;
text-align: center;
overflow: hidden;
}
&:hover {
cursor: pointer;
.description {
display: block;
}
}
}
22 changes: 22 additions & 0 deletions src/app/_components/Event/EventTag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import styles from './EventTag.module.scss'
import type { EventTag } from '@prisma/client'

type PropTypes = {
eventTag: EventTag
}

export default function EventTag({ eventTag }: PropTypes) {
// if background color is too dark color of text should be white
const textColor = (eventTag.colorR * 0.299 + eventTag.colorG * 0.587 + eventTag.colorB * 0.114) > 100 ? 'black' : 'white'
return (
<div className={styles.EventTag} style={{
color: textColor,
backgroundColor: `rgb(${eventTag.colorR}, ${eventTag.colorG}, ${eventTag.colorB})`
}}>
<p className={styles.name}>{eventTag.name}</p>
<p className={styles.description}>
{eventTag.description}
</p>
</div>
)
}
60 changes: 60 additions & 0 deletions src/app/_components/Event/EventTagsAdmin.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
@use '@/styles/ohma';

.EventTagsAdmin {
max-height: 80svh;
.create {
display: flex;
align-items: center;
form {
display: flex;
flex-direction: row wrap;
@include ohma.screenLg {
align-items: center;
justify-content: center;
gap: 1em;
}
@include ohma.screenMobile {
flex-direction: column;
}
}
}
ul {
margin-top: 1em;
display: flex;
flex-flow: row wrap;
gap: 2em;
overflow-y: auto;
overflow-x: visible;
list-style-type: none;
isolation: isolate;
padding-bottom: 5em;
a {
text-decoration: none;
&.selected {
position: relative;
&:hover {
&::after {
content: '';
font-size: 4em;
color: ohma.$colors-black;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
}
}
}
li {
display: flex;
align-items: center;
z-index: 1;
}
li:hover {
z-index: 2;
}
}
.update {
border-bottom: 3px solid ohma.$colors-gray-800;
}
}
Loading

0 comments on commit 7f7159b

Please sign in to comment.