1
0
Fork 0

Add /contact and /photography

This commit is contained in:
Moritz Ruth 2021-12-17 15:09:41 +01:00
parent 2863beed61
commit 18d65f5fe4
No known key found for this signature in database
GPG key ID: AFD57E23E753841B
16 changed files with 771 additions and 418 deletions

View file

@ -3,10 +3,8 @@
🔥 [**moritzruth.de**](https://moritzruth.de)
TODO:
- Start
- Blog
- Contact
- Photography
- Projects
- Apps
- Libraries
- Legal Notice
- Terms

View file

@ -1,12 +1,12 @@
<template>
<div class="min-h-100vh w-100vw text-light-900 overflow-x-hidden">
<div class="h-100vh w-100vw text-light-100 overflow-x-hidden">
<NuxtPage/>
</div>
</template>
<style module>
html, body {
background: #070707;
@apply bg-background;
overflow-x: hidden;
width: 100vw;
min-height: 100vh;

14
assets/photos.ts Normal file
View file

@ -0,0 +1,14 @@
export const photos = [
{
"file": "Late_afternoon.webp",
"title": "Late afternoon",
"date": "2019",
"description": "Taken in London during a sunny afternoon.\nSeems to be 65 Curzon St."
},
{
"file": "Martyrdom.webp",
"title": "Martyrdom",
"date": "2020-10-19",
"description": "The Sankt-Laurentius church right by the Mosel river in Bremm (Germany)."
}
]

View file

@ -0,0 +1,62 @@
<template>
<div class="relative flex flex-col justify-center space-y-4">
<component
:is="link.to ? 'router-link' : 'a'"
v-for="link in links"
:key="link.to"
:to="link.to"
:href="link.href"
class="px-5 sm:px-6 py-4 bg-light-300 bg-opacity-5 rounded-lg backdrop-blur-lg flex cursor-pointer
hover:bg-opacity-10 focus-visible:bg-opacity-10 transform hover:scale-104 transition duration-200 group"
>
<div class="flex items-center justify-center text-xl sm:text-2xl relative pr-4 sm:pr-5" :class="link.iconClasses">
<template v-if="typeof link.icon === 'string'">
{{ link.icon }}
</template>
<component :is="getSafeLinkIconComponent(link.icon)" v-else/>
</div>
<div class="flex-grow">
<div class="text-lg font-bold">
{{ link.label }}
</div>
<div class="opacity-60 -sm:text-sm">
{{ link.description }}
</div>
</div>
</component>
</div>
</template>
<style module>
</style>
<script lang="ts">
import { Component, ComponentCustomOptions, PropType } from "vue"
type Link = {
label: string
description: string
iconClasses?: string
icon: Component | string
} & ({
to: string
} | {
href: string
})
export default {
name: "LinkCardList",
props: {
links: {
type: Array as PropType<Link[]>,
required: true
}
},
methods: {
getSafeLinkIconComponent(icon: string | Component) {
return icon as ComponentCustomOptions
}
}
}
</script>

View file

@ -0,0 +1,44 @@
<template>
<div class="w-full max-w-1000px mx-auto">
<div class="bg-background bg-opacity-70 backdrop-filter backdrop-blur-sm backdrop-saturate-200 shadow-2xl px-6 py-8 text-light-900 sticky top-0 z-10 flex items-center justify-between">
<div class="w-0">
<router-link :to="backTarget" class="w-8 flex items-center group relative">
<ArrowLeftIcon class="text-2xl"/>
<div class="text-lg absolute left-10 opacity-0 sm:can-hover:group-hover:opacity-100 pointer-events-none transition duration-200">
Back
</div>
</router-link>
</div>
<div class="font-bold text-2xl text-center transform -translate-y-2px">
{{ title }}
</div>
<div/>
</div>
<div class="pt-8 pb-10 px-5">
<slot/>
</div>
</div>
</template>
<style module>
</style>
<script>
import ArrowLeftIcon from "~icons/ph/arrow-left"
export default {
name: "TopBarLayout",
components: { ArrowLeftIcon },
props: {
backTarget: {
type: String,
required: true
},
title: {
type: String,
required: true
}
}
}
</script>

View file

@ -1,24 +1,17 @@
import { defineNuxtConfig } from "nuxt3"
import Icons from "unplugin-icons/vite"
// https://v3.nuxtjs.org/docs/directory-structure/nuxt.config
export default defineNuxtConfig({
ssr: true,
target: "static",
buildModules: [
"nuxt-windicss"
"nuxt-windicss",
"unplugin-icons/nuxt"
],
css: [
"@fontsource/plus-jakarta-sans/400.css",
"@fontsource/plus-jakarta-sans/700.css"
],
vite: {
plugins: [
Icons({
autoInstall: true
})
]
},
build: {
loaders: {
css: {

View file

@ -17,9 +17,8 @@
},
"dependencies": {
"@fontsource/plus-jakarta-sans": "^4.5.0",
"@fontsource/syne": "^4.5.0",
"@iconify/json": "^1.1.441",
"@vueuse/core": "^7.2.2",
"@windicss/plugin-interaction-variants": "^1.0.0",
"blobs": "^2.2.1-beta.1",
"unplugin-icons": "^0.12.23",
"vue": "^3.2.26"

93
pages/contact.vue Normal file
View file

@ -0,0 +1,93 @@
<template>
<TopBarLayout back-target="/" title="Contact">
<div class="text-lg p-5 max-w-130 mx-auto">
<div class="space-y-4 text-xl">
<p>For business inquiries, please use Matrix or Email.</p>
<p>Matrix should be used when encryption is desired.</p>
</div>
<div class="pt-6 relative flex items-center">
<div class="absolute w-full">
<BlurredBlobCanvas
:blur="30"
:size="200"
:randomness="80"
:minimum-duration="600"
:duration-variation="400"
:minimum-opacity="0.2"
:opacity-variation="0.5"
:colors="['#eb34cf', '#6577fc']"
class="mx-auto"
/>
</div>
<LinkCardList :links="links" class="w-full"/>
</div>
</div>
</TopBarLayout>
</template>
<style module>
</style>
<script lang="ts">
import TopBarLayout from "../components/TopBarLayout.vue"
import LinkCardList from "../components/LinkCardList.vue"
import BlurredBlobCanvas from "../components/BlurredBlobCanvas.vue"
import MatrixIcon from "~icons/simple-icons/matrix"
import TwitterIcon from "~icons/simple-icons/twitter"
import EmailIcon from "~icons/carbon/email"
import { computed } from "vue"
import { useRoute } from "vue-router"
export default {
name: "ContactPage",
components: { BlurredBlobCanvas, LinkCardList, TopBarLayout },
setup() {
const route = useRoute()
return {
links: computed(() => {
const l = []
if (route.query.ref === "jamrss") {
l.push({
icon: EmailIcon,
href: "mailto:apps@moritzruth.de",
label: "Email (regarding apps)",
description: "apps@moritzruth.de"
}, {
icon: EmailIcon,
href: "mailto:hey@deltaa.xyz",
label: "Email (everything else)",
description: "hey@deltaa.xyz"
})
} else {
l.push({
icon: EmailIcon,
href: "mailto:hey@deltaa.xyz",
label: "Email",
description: "hey@deltaa.xyz"
})
}
l.push(
{
icon: MatrixIcon,
href: "https://moritzruth.de/matrix",
label: "Matrix",
description: "@moritz:moritzruth.de"
},
{
icon: TwitterIcon,
href: "https://twitter.com/moritzruth",
label: "Twitter",
description: "moritzruth"
}
)
return l
})
}
}
}
</script>

View file

@ -1,5 +1,5 @@
<template>
<div class="h-100vh w-full max-w-[1200px] mx-auto flex justify-between -lg:flex-col p-5 sm:p-10">
<div class="h-100vh w-full max-w-1200px mx-auto flex justify-between -lg:flex-col p-5 sm:p-10">
<section class="relative pt-20">
<div class="absolute top-60 -left-20 lg:-left-10">
<BlurredBlobCanvas
@ -13,7 +13,7 @@
:colors="['#eb34cf', '#6577fc']"
/>
</div>
<div class="relative max-w-130 p-2 lg:pl-10">
<main class="relative max-w-130 p-2 lg:pl-10">
<div class="font-extrabold text-3xl sm:text-4xl">
Moritz Ruth
</div>
@ -34,7 +34,7 @@
</div>
<XSpacer v="10"/>
<router-link to="/contact" :class="$style.reachOut">Reach out</router-link>
</div>
</main>
</section>
<section class="relative lg:pr-20 pt-20 pb-10 mt-0">
<div class="absolute w-full pt-20 flex justify-center">
@ -49,23 +49,7 @@
:colors="['#eb34cf', '#6577fc']"
/>
</div>
<div class="relative flex flex-col justify-center space-y-4">
<router-link
v-for="link in navigationLinks"
:key="link.to"
:to="link.to"
class="px-5 sm:px-6 py-4 bg-light-300 bg-opacity-5 rounded-lg backdrop-blur-lg flex
hover:bg-opacity-10 focus-visible:bg-opacity-10 transform hover:scale-104 transition duration-200 group"
>
<div class="flex items-center justify-center text-xl sm:text-2xl relative pr-3 sm:pr-5" :class="link.emojiClasses">
{{ link.emoji }}
</div>
<div class="flex-grow">
<div class="text-lg font-bold">{{ link.label }}</div>
<div class="opacity-60 -sm:text-sm">{{ link.text }}</div>
</div>
</router-link>
</div>
<LinkCardList :links="navigationLinks"/>
</section>
</div>
</template>
@ -101,38 +85,40 @@
<script>
import BlurredBlobCanvas from "../components/BlurredBlobCanvas.vue"
import XSpacer from "../components/XSpacer.vue"
import LinkCardList from "../components/LinkCardList.vue"
const NAVIGATION_LINKS = [
{
emoji: "📝",
icon: "📝",
to: "/blog",
label: "Blog",
text: "My thoughts, mostly on dev things"
description: "My thoughts, mostly on dev things"
},
{
emoji: "✨",
icon: "✨",
to: "/projects",
label: "Projects",
text: "Apps and open-source projects"
description: "Apps and open-source projects"
},
{
emojiClasses: "top-[-0.25rem]",
emoji: "📷",
iconClasses: "top-[-0.25rem]",
icon: "📷",
to: "/photography",
label: "Photography",
text: "Some photos Im proud of"
description: "Some photos Im proud of"
},
{
emoji: "💬",
icon: "💬",
to: "/contact",
label: "Contact me",
text: "Email, Matrix, Twitter"
description: "Email, Matrix, Twitter"
}
]
export default {
name: "IndexPage",
components: {
LinkCardList,
XSpacer,
BlurredBlobCanvas
},

48
pages/photography.vue Normal file
View file

@ -0,0 +1,48 @@
<template>
<TopBarLayout title="Photography" back-target="/">
<div class="flex flex-col space-y-30 lg:space-y-20">
<div
v-for="photo in photos"
:key="photo.file"
class="flex -lg:space-y-10 lg:space-x-10 -lg:flex-col -lg:items-center"
>
<img
:src="photo.file"
:alt="photo.title"
class="w-full lg:max-w-150 max-h-80vh block object-contain"
>
<div>
<div class="uppercase opacity-70 text-sm pt-1">
{{ photo.date }}
</div>
<div class="font-bold text-2xl opacity-90">
{{ photo.title }}
</div>
<div class="opacity-90 max-w-100 space-y-1 pt-4 whitespace-pre-line">
{{ photo.description }}
</div>
</div>
</div>
</div>
</TopBarLayout>
</template>
<style module>
</style>
<script lang="ts">
import TopBarLayout from "../components/TopBarLayout.vue"
import { photos } from "assets/photos"
import XSpacer from "~/components/XSpacer.vue"
export default {
name: "PhotographyPage",
components: { XSpacer, TopBarLayout },
setup() {
return {
photos
}
}
}
</script>

834
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 KiB

View file

@ -3,7 +3,8 @@
"extends": "./.nuxt/tsconfig.json",
"compilerOptions": {
"types": [
"nuxt-windicss"
"nuxt-windicss",
"unplugin-icons/types/vue"
]
}
}

7
webstorm-shims.d.ts vendored Normal file
View file

@ -0,0 +1,7 @@
// Taken from https://github.com/antfu/unplugin-icons/issues/128#issuecomment-992718883
declare module "~icons/*" {
import { FunctionalComponent, SVGAttributes } from "vue"
const component: FunctionalComponent<SVGAttributes>
export default component
}

View file

@ -1,6 +1,7 @@
import { defineConfig } from "windicss/helpers"
import colors from "windicss/colors"
import interactionVariantsPlugin from "@windicss/plugin-interaction-variants"
import scrollSnapPlugin from "windicss/plugin/scroll-snap"
import plugin from "windicss/plugin"
export default defineConfig({
darkMode: "media",
@ -12,14 +13,19 @@ export default defineConfig({
green: colors.green,
blue: colors.blue,
dark: colors.dark,
light: colors.light
light: colors.light,
background: "#070707"
},
fontFamily: {
sans: ["Plus Jakarta Sans", "sans-serif"],
special: ["SyneVariable", "monospace"]
sans: ["Plus Jakarta Sans", "sans-serif"]
}
},
plugins: [
interactionVariantsPlugin
scrollSnapPlugin,
plugin(({ addVariant }) => {
addVariant("can-hover", ({ atRule }) => {
return atRule("@media(hover: hover)")
})
})
]
})