Skip to content

Commit

Permalink
Merge pull request #87 from vevcom/feat/ImageLink
Browse files Browse the repository at this point in the history
Feat/image link
  • Loading branch information
JohanHjelsethStorstad authored Jan 11, 2024
2 parents fb6ad37 + 14b91d1 commit e1c6679
Show file tree
Hide file tree
Showing 69 changed files with 1,281 additions and 504 deletions.
54 changes: 53 additions & 1 deletion src/actions/images/collections/read.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { ActionReturn } from '@/actions/type'
'use server'
import type { ActionReturn, ReadPageInput } from '@/actions/type'
import type { ImageCollection, Image } from '@prisma/client'
import prisma from '@/prisma'
import errorHandeler from '@/prisma/errorHandler'
Expand All @@ -19,3 +20,54 @@ export default async function read(id: number) : Promise<ActionReturn<ImageColle
return errorHandeler(error)
}
}


export type ImageCollectionPageReturn = ImageCollection & {
coverImage: Image | null,
numberOfImages: number,
}
export async function readPage<const PageSize extends number>({ page }: ReadPageInput<PageSize, null>) : Promise<ActionReturn<ImageCollectionPageReturn[]>> {
try {
const { page: pageNumber, pageSize } = page
const collections = await prisma.imageCollection.findMany({
include: {
coverImage: true,
images: {
take: 1
},
_count: {
select: {
images: true
}
}
},
skip: pageNumber * pageSize,
take: pageSize,
})

const lensCamera = await prisma.image.findUnique({
where: {
name: 'lens_camera'
},
})

const chooseCoverImage = (collection : {
coverImage: Image | null,
images: Image[]
}) => {
if (collection.coverImage) return collection.coverImage
if (collection.images[0]) return collection.images[0]
if (lensCamera) return lensCamera
return null
}
const returnData = collections.map(collection => ({
...collection,
coverImage: chooseCoverImage(collection),
numberOfImages: collection._count.images,
}))

return { success: true, data: returnData }
} catch (error) {
return errorHandeler(error)
}
}
33 changes: 33 additions & 0 deletions src/actions/images/links/read.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use server'
import prisma from '@/prisma'
import type { Image, ImageLink } from '@prisma/client'
import type { ActionReturn } from '@/actions/type'
import errorHandeler from '@/prisma/errorHandler'

export default async function read(name: string) : Promise<ActionReturn<ImageLink & {image: Image | null}>> {
//Note this action reates a image link if it does not exist and returns it
try {
const imageLink = await prisma.imageLink.findUnique({
where: {
name,
},
include: {
image: true,
}
})
if (!imageLink) {
const created = {
...await prisma.imageLink.create({
data: {
name,
},
}),
image: null,
}
return { success: true, data: created }
}
return { success: true, data: imageLink }
} catch (error) {
return errorHandeler(error)
}
}
25 changes: 25 additions & 0 deletions src/actions/images/links/update.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use server'
import { ActionReturn } from '@/actions/type'
import { ImageLink } from '@prisma/client'
import prisma from '@/prisma'
import errorHandeler from '@/prisma/errorHandler'

export default async function update(linkId: number, imageId: number) : Promise<ActionReturn<ImageLink>> {
try {
const imageLink = await prisma.imageLink.update({
where: {
id: linkId,
},
data: {
image: {
connect: {
id: imageId,
}
}
}
})
return { success: true, data: imageLink }
} catch (error) {
return errorHandeler(error)
}
}
1 change: 0 additions & 1 deletion src/actions/users/create.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
'use server'

import prisma from '@/prisma'
import { z } from 'zod'
import errorHandeler from '@/prisma/errorHandler'
Expand Down
2 changes: 1 addition & 1 deletion src/app/(auth)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react'
import ImageLink from '@/components/Image/ImageLink'
import ImageLink from '@/app/components/Image/link/ImageLink'
import styles from './layout.module.scss'

type PropTypes = {
Expand Down
2 changes: 1 addition & 1 deletion src/app/(home)/Section.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react'
import ImageLink from '@/components/Image/ImageLink'
import ImageLink from '@/app/components/Image/link/ImageLink'
import Link from 'next/link'
import styles from './Section.module.scss'

Expand Down
2 changes: 1 addition & 1 deletion src/app/(home)/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import ImageLink from '@/components/Image/ImageLink'
import ImageLink from '@/app/components/Image/link/ImageLink'
import Link from 'next/link'
import SocialIcons from '@/components/SocialIcons/SocialIcons'
import Section from './Section'
Expand Down
14 changes: 12 additions & 2 deletions src/app/components/EditModeSwitch/EditModeSwitch.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use client'
import { useContext } from 'react'
import { useContext, useEffect, useRef } from 'react'
import { EditModeContext } from '@/context/EditMode'
import styles from './EditModeSwitch.module.scss'
import type { ChangeEvent } from 'react'
Expand All @@ -13,11 +13,21 @@ export default function EditModeSwitch() {
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
editingContext.setEditMode(e.target.checked)
}
const isAdmin = true

const ref = useRef<HTMLInputElement>(null)

useEffect(() => {
if (ref.current?.checked) {
ref.current.checked = editingContext.editMode
}
})
if (!isAdmin) return null

return (
<div className={styles.EditModeSwitch}>
<label>
<input checked={editingContext.editMode} type="checkbox" id="editModeSwitch" onChange={handleChange} />
<input ref={ref} checked={editingContext.editMode} type="checkbox" onChange={handleChange} />
<FontAwesomeIcon className={styles.EditModeSwitchIcon} icon={faPencil} />
</label>
</div>
Expand Down
6 changes: 6 additions & 0 deletions src/app/components/Footer/Footer.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
.pwa {
@include ohma.yellowIconLink;
padding-left: 0;
width: 100%;
height: 100%;
}
.icons {
display: flex;
Expand All @@ -67,6 +69,10 @@
> * {
margin: ohma.$gap;
}
a {
width: 100%;
height: 100%;
}
}

@media (min-width: 1100px) {
Expand Down
20 changes: 10 additions & 10 deletions src/app/components/Footer/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import ImageLink from '@/components/Image/ImageLink'
import ImageLink from '@/app/components/Image/link/ImageLink'
import Link from 'next/link'
import SocialIcons from '../SocialIcons/SocialIcons'

Expand All @@ -14,9 +14,9 @@ function Footer() {
Robotikk (MTTK) ved Norges Tekniske-Naturvitenskapelige Universitet (NTNU)
</p>
<div>
<Link className={styles.pwa} href="/infopages/pwa">
<ImageLink name="pwa" width={200}/>
</Link>
<ImageLink name="pwa" width={200} >
<Link className={styles.pwa} href="/infopages/pwa" />
</ImageLink>
<div className={styles.icons}>
<SocialIcons />
</div>
Expand All @@ -38,12 +38,12 @@ function Footer() {
<p>7491 Trondheim</p>
</div>
<div className={styles.sponsors}>
<Link href="http://www.nordicsemi.com" target="_blank">
<ImageLink name="nordic" width={170} />
</Link>
<Link href="http://www.kongsberg.com" target="_blank">
<ImageLink name="kongsberg" width={100} />
</Link>
<ImageLink name="nordic" width={170}>
<Link href="http://www.nordicsemi.com" target="_blank" />
</ImageLink>
<ImageLink name="kongsberg" width={100}>
<Link href="http://www.kongsberg.com" target="_blank" />
</ImageLink>
</div>
</footer>
)
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/Form/Form.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
}
.submit {
margin-top: ohma.$gap;
button:not(.cross) {
> button:not(.cross) {
width: 150px;
margin: 0;
color: ohma.$colors-black;
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/Form/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ export default function Form<GiveActionReturn>({
}

return (
<form className={styles.Form} action={actionWithError} {...props}>
<form {...props} className={`${styles.Form} ${props.className}`} action={actionWithError}>
{title && <h2>{title}</h2>}
{
inputs.map(({ input, errors }, i) => (
Expand Down
71 changes: 71 additions & 0 deletions src/app/components/Image/Collection/CollectionCard.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
@use '@/styles/ohma';

.CollectionCard {
margin: ohma.$gap;
overflow: hidden;
@include ohma.round;
position: relative;
place-self: center;
display: block;
> .imageCount {
position: absolute;
top: 0;
right: 0;
padding: 0.3em;
color: ohma.$colors-white;
background-color: ohma.$colors-black;
border-radius: 0 0 0 1em;
min-width: 30px;
z-index: 1;
text-align: center;
}
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: radial-gradient(ellipse at center bottom, transparent 20%, ohma.$colors-secondary 70%, ohma.$colors-secondary 100%);
rotate: 180deg;
scale: 1.5;
z-index: 0;
}
> *:first-child {
position: absolute;
top: 0;
left: 0;
width: 100% !important;
height: 100%;
> img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
transition: scale 0.5s;
}
}
> .info {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
padding: 0.3em;
color: ohma.$colors-black;
text-decoration: none;
transition: min-height 0.5s;
padding: ohma.$gap;
z-index: 1;
i {
margin-top: ohma.$gap;
transition: opacity 0.5s;
text-overflow: ellipsis;
white-space: nowrap;
}
}
&:hover img {
scale: 1.2;
}
}
32 changes: 32 additions & 0 deletions src/app/components/Image/Collection/CollectionCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import Link from 'next/link'
import styles from './CollectionCard.module.scss'
import Image from '@/components/Image/Image'
import type { Image as ImageT, ImageCollection } from '@prisma/client'

type PropTypes = {
collection: ImageCollection & {
coverImage: ImageT | null,
numberOfImages: number,
},
className?: string,
}

export default function CollectionCard({ collection, className }: PropTypes) {
return (
<Link href={`/images/collections/${collection.id}`} className={`${styles.CollectionCard} ${className}`} key={collection.id}>
{
collection.coverImage ? (
<Image width={100} image={collection.coverImage} />
) : (
<p>Something went wrong</p>
)
}
<div className={styles.info}>
<h2>{collection.name}</h2>
<i>{collection.description}</i>
<p>{collection.createdAt.toUTCString().split(' ').slice(0, 4).join(' ')}</p>
</div>
<p className={styles.imageCount}>{collection.numberOfImages}</p>
</Link>
)
}
Loading

0 comments on commit e1c6679

Please sign in to comment.