Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions nuxt-app/assets/icons/birthday-cake.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions nuxt-app/assets/icons/location.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions nuxt-app/assets/icons/star.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions nuxt-app/assets/icons/suitcase.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions nuxt-app/assets/images/background-glow-bl.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions nuxt-app/assets/images/background-glow-tr.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion nuxt-app/components/PrimaryPbButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const handleClick = () => {
<template>
<button
:class="[
'btn btn-primary rounded-full border-4 text-base font-bold leading-8 tracking-[2px] text-lime hover:bg-lime hover:text-black active:translate-y-1 ',
'btn btn-primary rounded-full border-4 text-base font-bold leading-8 tracking-[2px] text-lime bg-black hover:bg-lime hover:text-black active:translate-y-1 ',
isClicked ? 'animate-grow-fade' : '',
]"
@click="handleClick"
Expand Down
9 changes: 7 additions & 2 deletions nuxt-app/components/ProfileCreationMainInfos.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<script setup lang="ts">
import ProfilePicture from '~/components/ProfilePicture.vue'
import { useProfileCreationStore } from '~/composables/useProfileCreationStore'
import { computed, ref, watch } from 'vue'

Expand Down Expand Up @@ -30,6 +29,10 @@ function updateFirstName(value: string) {
function updateLastName(value: string) {
store.updateMainInfos({ ...mainInfos.value, lastName: value })
}

function updatePicture(file: File, previewUrl: string) {
store.updateProfilePicture(file, previewUrl)
}
</script>

<template>
Expand All @@ -41,7 +44,9 @@ function updateLastName(value: string) {
</div>

<div class="intro-text mb-2 mt-5 text-base font-light text-white md:text-4xl" v-html="introText"></div>
<ProfilePicture class="mb-10" />
<div class="flex w-full flex-col items-center justify-center my-10">
<ProfilePictureEditable @updated-profile-picture="updatePicture" class="h-24 w-24 md:h-64 md:w-64" />
</div>
<div class="flex w-full flex-col items-center justify-center">
<InputFieldWithHeadline
v-model="firstName"
Expand Down
27 changes: 27 additions & 0 deletions nuxt-app/components/ProfileHeader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<script setup lang="ts">
import BirthdayCakeIcon from '~/assets/icons/birthday-cake.svg'
import type { DirectusProfileItem } from '~/types'

defineProps<{
profile: DirectusProfileItem
}>()
</script>

<template>
<div class="mb-6 flex flex-row items-center">
<div class="h-24 w-24 md:h-64 md:w-64">
<ProfilePicture :image="profile.profile_image" />
</div>
<div class="flex h-full flex-col gap-6 pl-7">
<h1 class="text-4xl font-bold">{{ profile.first_name }} {{ profile.last_name }}</h1>
<p v-if="profile.display_name" class="text-3xl font-light italic">@{{ profile.display_name }}</p>
<div class="flex flex-row items-end gap-x-4 text-2xl font-light italic">
<BirthdayCakeIcon class="h-10 w-6 align-middle" />
<p>
Dabei seit dem
<NuxtTime :datetime="profile.date_created_prepared" month="long" day="numeric" year="numeric" />
</p>
</div>
</div>
</div>
</template>
39 changes: 39 additions & 0 deletions nuxt-app/components/ProfileHeaderMobile.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<script setup lang="ts">
import LocationIcon from '~/assets/icons/location.svg'
import StarIcon from '~/assets/icons/star.svg'
import SuitcaseIcon from '~/assets/icons/suitcase.svg'
import type { DirectusProfileItem } from '~/types'

defineProps<{
profile: DirectusProfileItem
}>()
</script>

<template>
<div class="mb-6 flex flex-col items-start gap-y-6 text-sm font-light">
<ProfilePicture class="h-24 w-32 md:h-64 md:w-64" :image="profile.profile_image" />

<div class="flex h-full flex-col">
<h1 class="text-3xl font-bold">{{ profile.first_name }} {{ profile.last_name }}</h1>
</div>
<div class="flex flex-col gap-y-4">
<div class="flex flex-row items-center gap-x-2">
<SuitcaseIcon class="w-6" />
<div>
<span v-if="profile.job_role"> {{ profile.job_role }}</span>
<span v-if="profile.job_employer"> bei {{ profile.job_employer }}</span>
</div>
</div>
<div class="flex flex-row items-center gap-x-2">
<LocationIcon class="w-5" />
<span>Frankfurt am Main</span>
</div>
<div v-if="profile.emojis_prepared" class="flex flex-row gap-x-2">
<StarIcon class="w-6" />
<span v-for="emoji of profile.emojis_prepared" :key="emoji.id" class="ml-1 text-2xl">{{
emoji.display_emoji
}}</span>
</div>
</div>
</div>
</template>
47 changes: 16 additions & 31 deletions nuxt-app/components/ProfilePicture.vue
Original file line number Diff line number Diff line change
@@ -1,44 +1,29 @@
<script setup lang="ts">
import EmptyProfilePicture from '~/assets/images/profile-picture-empty.svg'
import { useProfileCreationStore } from '~/composables/useProfileCreationStore'
import { ref } from 'vue'
import type { DirectusFileItem } from '~/types'
import type { ComputedRef } from 'vue'

const store = useProfileCreationStore()
const fileInput = ref<HTMLInputElement | null>(null)
const props = defineProps<{
image: DirectusFileItem | string | null
}>()

const handleFileUpload = (event: Event) => {
const target = event.target as HTMLInputElement
if (target.files && target.files.length > 0) {
const file = target.files[0]
const previewUrl = URL.createObjectURL(file)
store.updateProfilePicture(file, previewUrl)
}
}
const directusImage: ComputedRef<DirectusFileItem | null> = computed(() => {
return typeof props.image !== 'undefined' && typeof props.image !== 'string' ? props.image : null
})

const triggerFileInput = () => {
fileInput.value?.click()
}
const urlImage: ComputedRef<string | null> = computed(() => {
return typeof props.image === 'string' ? props.image : null
})
</script>

<template>
<div class="mt-10 flex flex-col items-center justify-center">
<div class="flex flex-col items-center justify-center">
<div
class="profile-picture flex h-24 w-24 flex-col items-center justify-center rounded-full border-4 border-white bg-gradient-to-t from-white/20 to-white/80 md:h-64 md:w-64"
class="profile-picture flex flex-col items-center justify-center overflow-clip rounded-full border-6 border-white bg-gradient-to-t from-white/20 to-white/80"
>
<img
v-if="store.profilePicture.previewUrl"
:src="store.profilePicture.previewUrl"
alt="Profile Picture"
class="h-full w-full rounded-full object-cover"
/>
<EmptyProfilePicture v-else />
<DirectusImage v-if="directusImage" :image="directusImage" :sizes="''" class="h-full w-full object-cover" />
<img v-else-if="urlImage" :src="urlImage" alt="Profile Picture" class="h-full w-full object-cover" />
<EmptyProfilePicture v-else class="h-full w-full" />
</div>
<input ref="fileInput" type="file" accept="image/*" class="hidden" @change="handleFileUpload" />
<PrimaryPbButton
class="mt-5 w-44 border-[1.4px] text-base font-light italic tracking-normal md:w-72 md:py-2 md:text-2xl md:tracking-wide"
@click="triggerFileInput"
>
Profilbild hochladen
</PrimaryPbButton>
</div>
</template>
58 changes: 58 additions & 0 deletions nuxt-app/components/ProfilePictureEditable.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<script setup lang='ts'>
import { type ComputedRef, ref } from 'vue';
import type { DirectusFileItem } from '~/types';

const emit = defineEmits<{
(e: 'updatedProfilePicture', file: File, previewUrl: string): void
}>()

const props = defineProps<{
image?: DirectusFileItem | null,
}>();

const fileInput = ref<HTMLInputElement | null>(null);
const updatedImagePath = ref<string | null>(null);

const currentImage: ComputedRef<DirectusFileItem | string | null> = computed(() => {
if (updatedImagePath.value) {
return updatedImagePath.value
}

if (props.image) {
return props.image
}

return null;
})

const handleFileSelection = (event: Event) => {
const target = event.target as HTMLInputElement;
if (target.files && target.files.length > 0) {
const file = target.files[0];
const previewUrl = URL.createObjectURL(file);
updatedImagePath.value = previewUrl;
emit('updatedProfilePicture', file, previewUrl);
}
};

const triggerFileInput = () => {
fileInput.value?.click();
};
</script>

<template>
<div class='flex flex-col items-center justify-center'>
<div
class='profile-picture flex flex-col items-center justify-center rounded-full border-4 border-white bg-gradient-to-t from-white/20 to-white/80 '
>
<ProfilePicture :image='currentImage' />
</div>
<input ref='fileInput' type='file' accept='image/*' class='hidden' @change='handleFileSelection'/>
<PrimaryPbButton
class='mt-5 w-44 border-[1.4px] text-base font-light italic tracking-normal md:w-72 md:py-2 md:text-2xl md:tracking-wide'
@click='triggerFileInput'
>
Profilbild hochladen
</PrimaryPbButton>
</div>
</template>
16 changes: 16 additions & 0 deletions nuxt-app/components/ProfileSection.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<script setup lang="ts">
defineProps<{
title: string
html?: string
content?: string
}>()
</script>

<template>
<div class="profile-section">
<h2 class="mb-6 mt-16 text-xl font-bold md:text-4xl">{{ title }}</h2>
<p v-if="content" class="text-base font-light md:text-3xl">{{ content }}</p>
<InnerHtml v-else-if="html" :html="html" class="text-base font-light md:text-3xl" />
<slot></slot>
</div>
</template>
39 changes: 33 additions & 6 deletions nuxt-app/composables/useDirectus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
type QueryFilter,
} from '@directus/sdk'
import type {
DirectusEmojiItem,
DirectusMemberItem,
DirectusPickOfTheDayItem,
DirectusProfileItem,
Expand Down Expand Up @@ -562,24 +563,50 @@ export function useDirectus() {
)
}

async function getProfileById(id: string) {
return (await directus
async function getProfileBySlug(slug: string) {
const profile = (await directus
.request(
readItems('profiles', {
fields: [
'id',
'date_created',
'first_name',
'last_name',
'display_name',
'description',
'job_role',
'job_employer',
'profile_image.*'
'profile_image.*',
'slug',
'interested_tags.tags_id.id',
'interested_tags.tags_id.name',
'emojis.emojis_id.id',
'emojis.emojis_id.title',
'emojis.emojis_id.display_emoji',
//'interested_tags.tag.id',
//'interested_tags.tag.name',
],
limit: 1,
filter: { id: { _eq: id } },
filter: { slug: { _eq: slug } },
})
))?.pop() as unknown as DirectusProfileItem
).then((results: any) => {
const items = results as DirectusProfileItem[];
return items.map((profile) => ({
...profile,
interested_tags_prepared: profile.interested_tags?.map((tag: any) => tag.tags_id).filter((tag) => tag) as TagItem[],
}))
}).then((results: any) => {
const items = results as DirectusProfileItem[];
return items.map((profile) => ({
...profile,
emojis_prepared: profile.emojis?.map((emoji: any) => emoji.emojis_id).filter((emoji) => emoji) as DirectusEmojiItem[],
}))
})
)?.pop() as unknown as DirectusProfileItem

profile.date_created_prepared = new Date(profile.date_created);

return profile;
}

async function getSingleSignOnProviders() {
Expand Down Expand Up @@ -657,6 +684,6 @@ export function useDirectus() {
getSingleSignOnProviders,
getCurrentUser,
registerNewUser,
getProfileById,
getProfileBySlug,
}
}
1 change: 1 addition & 0 deletions nuxt-app/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export default defineNuxtConfig({
// '@nuxtjs/sitemap',
'nuxt-jsonld',
'@pinia/nuxt',
'nuxt-time',
],

// Router configuration: https://nuxtjs.org/docs/configuration-glossary/configuration-router
Expand Down
12 changes: 12 additions & 0 deletions nuxt-app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading