Skip to content

Commit

Permalink
Add member metadata and flip card
Browse files Browse the repository at this point in the history
  • Loading branch information
diamondburned committed Sep 28, 2022
1 parent 6128aa6 commit 52fe658
Showing 1 changed file with 227 additions and 10 deletions.
237 changes: 227 additions & 10 deletions src/routes/about/officer-profile.svelte
@@ -1,5 +1,12 @@
<script lang="ts">
import type { Officer } from '$lib/public/board/types';
import { Term, Social } from '$lib/public/board/types';
import GitHub from '$lib/components/svg/github.svelte';
import Public from '$lib/components/svg/public.svelte';
import Discord from '$lib/components/svg/discord.svelte';
import LinkedIn from '$lib/components/svg/linkedin.svelte';
import Instagram from '$lib/components/svg/instagram.svelte';
import { toast, ToastType } from '$lib/components/toaster/toasts';
import {
termIndex,
getOfficerTierByTermIndex,
Expand All @@ -10,8 +17,26 @@
export let placeholderPicture = 'placeholder.webp';
export let dev = false;
// earliestTerm returns the earliest term of the current officer. Blame Ethan
// for this whole idea of having an officer ID. OK, maybe some of it was mine.
function earliestTerm(): string {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for (const [_, key] of Object.entries(Term)) {
if (info.positions[key]) {
return key;
}
}
return 'null';
}
const officerID = info.fullName.toLowerCase().replace(/[^a-z0-9]/g, '-') + '-' + earliestTerm();
const officerName = info.fullName ?? '';
const officerPicture = info.picture ?? placeholderPicture;
const officerSocials = info.socials ?? {};
function copyDiscord() {
toast({ content: `Copied ${officerName}'s Discord tag to clipboard!` });
}
$: titleHTML = getPositionByTermIndex(info, $termIndex)
?.title.replace(/Algo\s/, `<b class="acm-purple">Algo&nbsp;</b>`)
Expand All @@ -26,24 +51,101 @@
$: officerTier = dev ? getOfficerTierByTermIndex(info, $termIndex) : '';
</script>

<div class="officer-container">
<img
class="officer-image"
src={`../assets/authors/${officerPicture}`}
alt={`Image of ${officerName}.`}
/>
<label
for="{officerID}-flipcard"
class="officer-container"
class:officer-has-socials={info.socials !== undefined}
>
<div class="officer-3d-flipcard">
<input type="checkbox" id="{officerID}-flipcard" />
<div class="officer-flipcard">
<img
class="officer-image"
src={`../assets/authors/${officerPicture}`}
alt={`Image of ${officerName}.`}
/>
<div class="officer-socials-box">
<div class="officer-socials">
<h3>Socials</h3>
<div class="officer-social-scrolls">
<div class="officer-social-links">
{#if officerSocials.website}
<p class="officer-website">
<a
target="blank"
title={officerSocials.website}
href="//{officerSocials.website}"
>
<Public /> Website
</a>
</p>
{/if}
{#if officerSocials.github}
<p class="officer-github">
<a
target="blank"
title={officerSocials.github}
href="https://github.com/{officerSocials.github}"
>
<GitHub /> GitHub
</a>
</p>
{/if}
{#if officerSocials.discord}
<p class="officer-discord">
<a
target="blank"
title={officerSocials.discord}
href="#"
on:click={(event) => {
copyDiscord();
event.preventDefault();
}}
>
<Discord /> Discord
</a>
</p>
{/if}

<div>
{#if officerSocials.linkedin}
<p class="officer-linkedin">
<a
target="blank"
title={officerSocials.linkedin}
href="https://www.linkedin.com/in/{officerSocials.linkedin}"
>
<LinkedIn /> LinkedIn
</a>
</p>
{/if}
{#if officerSocials.instagram}
<p class="officer-instagram">
<a
target="blank"
title={officerSocials.instagram}
href="https://www.instagram.com/{officerSocials.instagram}/"
>
<Instagram /> Instagram
</a>
</p>
{/if}
</div>
</div>
</div>
</div>
</div>
</div>

<div class="officer-placard">
<h3 class="brand-header">
{officerName}
{#if officerTier}<br />{officerTier}<br />{/if}
</h3>

<p class="brand-med">
{@html titleHTML}
</p>
</div>
</div>
</label>

<style lang="scss">
.officer-container {
Expand All @@ -53,7 +155,7 @@
align-items: center;
text-align: center;
.officer-image {
.officer-flipcard {
width: 200px;
height: auto;
}
Expand All @@ -62,4 +164,119 @@
max-width: 250px;
}
}
.officer-container.officer-has-socials {
cursor: pointer;
input:checked[type='checkbox'] + .officer-flipcard {
transform: rotateY(180deg);
}
&:hover .officer-image,
input:checked[type='checkbox'] + .officer-flipcard .officer-image {
/* This hack stays until we can resolve #348. */
filter: brightness(130%) contrast(85%);
}
}
.officer-3d-flipcard {
perspective: 2000px;
input[type='checkbox'] {
display: none;
}
.officer-flipcard {
position: relative;
height: 200px;
.officer-image,
.officer-socials-box {
top: 0;
left: 0;
position: absolute;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.officer-image {
height: 100%;
}
&,
.officer-socials-box {
transition: transform 0.3s ease;
transform-style: preserve-3d;
}
.officer-socials-box {
width: 100%;
height: 100%;
transform: rotateY(180deg);
display: flex;
align-items: center;
justify-content: center;
.officer-socials {
width: 180px;
height: 180px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-radius: 20px;
box-sizing: border-box;
background-color: var(--acm-canvas);
h3 {
line-height: 2.5em;
}
}
.officer-social-scrolls {
width: 100%;
overflow: scroll;
scroll-snap-type: y mandatory;
display: flex;
flex-direction: column;
align-items: center;
}
.officer-social-links {
display: flex;
flex-direction: column;
gap: 0.35em;
& > * {
scroll-snap-align: start;
}
}
p {
text-align: left;
line-height: 2em;
:global(svg) {
width: 1.65em;
height: 1.65em;
margin-bottom: -0.45em;
margin-right: 0.35em;
}
a {
text-decoration: none;
}
&:hover a {
color: var(--acm-sky);
}
}
}
}
}
</style>

0 comments on commit 52fe658

Please sign in to comment.