new project cards with modals!

This commit is contained in:
Tabby 2025-04-23 21:32:06 +10:00
parent 99c911c5d4
commit d33022ac09
7 changed files with 316 additions and 11 deletions

View file

@ -0,0 +1,56 @@
<template>
<div>
<!-- <button @click="$emit('close')"> Close </button> -->
<img src="public\img\close.png" class="close-button" @click="$emit('close')">
<h2>{{title}}</h2>
<p>{{description}}</p>
<br>
<!-- <ClientOnly> -->
<div class="buttons">
<SmallButton v-for="(data, i) of buttons" :key="i" class="button" :text="data.text"
:href="data.link" />
</div>
<!-- </ClientOnly> -->
<br>
<p class="multiline-css-fix">{{longDescription}}</p>
</div>
</template>
<script lang="ts" setup>
import {defineProps, defineEmits} from 'vue'
export interface ButtonData {
text: string,
link: string,
}
const props = defineProps<{
title: string,
description: string,
longDescription?: string,
buttons?: Array<ButtonData>,
}>();
defineEmits("close")
</script>
<style scoped>
.close-button{
float:right;
/* display: block; */
/* margin-left: auto; */
width: 32px;
&:hover{
filter: invert();
}
}
.multiline-css-fix{
white-space: pre-wrap;
}
</style>

View file

@ -0,0 +1,139 @@
<template>
<div class="top-level">
<!-- <button @click="isOpen=true">Open</button> -->
<!-- Project Card -->
<div @click="isOpen=true" class="card">
<img class="project-image" :src="props.src">
<div class="content">
<h2>{{props.title}}</h2>
<p>{{props.description}}</p>
</div>
</div>
<!-- Popup Modal -->
<Teleport to="body">
<div class="modal" v-if="isOpen">
<div>
<ProjectCardContent
@close="isOpen = false"
:title=props.title
:description=props.description
:long-description=props.longDescription
:buttons=props.buttons
/>
</div>
</div>
</Teleport>
</div>
</template>
<script lang="ts" setup>
import {ref, defineProps} from 'vue'
import ProjectCardContent from './ProjectCardContent.vue';
const isOpen = ref(false)
export interface ButtonData {
text: string,
link: string,
}
const props = defineProps<{
title: string,
description: string,
longDescription?: string,
src: string,
buttons?: Array<ButtonData>,
}>();
</script>
<style scoped>
.root{
position:relative
}
.top-level{
margin-right: 10px;
}
.card{
position: relative;
text-align: center;
overflow: hidden;
border-color: var(--accent);
border-width: 3px;
border-style: solid;
width: 100%;
/* overflow: auto; */
height: max-content;
&:hover{
border-color: white;
cursor: pointer;
}
}
.project-image{
width: 100%;
}
.content{
position: absolute;
bottom: 8px;
left: 16px;
text-align: left ;
visibility:hidden;
/* &:hover{
visibility: visible;
} */
}
.card>img:hover{
/* filter: brightness(40%) blur(2px); */
}
.card:hover, .content:hover{
border-color: white;
cursor: pointer;
.content{
visibility: visible;
}
.project-image{
filter: brightness(40%) blur(2px);
}
}
.modal {
position: fixed;
top: 0;
left: 0;
z-index: 100;
background-color: rgba(0,0,0,0.1);
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.modal > div{
background-color: rgb(53, 53, 53);
padding: 50px;
border-radius: 10px;
margin: 10%;
max-height: calc(100vh - 210px);
overflow-y: auto;
}
</style>

View file

@ -0,0 +1,41 @@
<script setup lang="ts">
const props = defineProps({
href: String,
text: String
});
</script>
<template>
<a class="button" :href="props.href">
<p>{{ props.text }}</p>
</a>
</template>
<style scoped>
.button {
background-color: #8904aa;
border: none;
color: white;
padding: 5px;
border-radius: 5px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
overflow: hidden;
margin-right: 5px;
}
.button:hover{
background-color: var(--accent);
color: black;
}
p{
font-weight: 100;
margin: 0;
}
</style>