Skip to content

Commit

Permalink
💄 massive frontend update
Browse files Browse the repository at this point in the history
(orgs viewable, better structuring, improved components, etc.)
  • Loading branch information
MattMoony committed May 9, 2024
1 parent 791eae8 commit d70f3e2
Show file tree
Hide file tree
Showing 19 changed files with 1,237 additions and 540 deletions.
8 changes: 7 additions & 1 deletion web/package-lock.json

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

3 changes: 2 additions & 1 deletion web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
"vue": "^3.4.15",
"vue-codemirror": "^6.1.1",
"vue-dompurify-html": "^5.0.1",
"vue-router": "^4.2.5"
"vue-router": "^4.2.5",
"vue-spinner": "^1.0.4"
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.7.2",
Expand Down
3 changes: 3 additions & 0 deletions web/src/assets/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
--color-highlight: var(--vt-c-lightblue);

--section-gap: 160px;

--color-person: var(--vt-c-indigo);
--color-organization: var(--vt-c-lightblue);
}

@media (prefers-color-scheme: dark) {
Expand Down
3 changes: 1 addition & 2 deletions web/src/components/NavBarNew.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ const props = defineProps<{
* The result to display in the search bar.
*/
result?: Organ;
}>()
}>();
</script>

<template>
Expand Down
279 changes: 279 additions & 0 deletions web/src/components/OrganBanner.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,279 @@
<script setup lang="ts">
import { type Ref, ref } from 'vue';
import Organ from '../models/Organ';
import PopDropDown from './PopDropDown.vue';
const props = defineProps<{
/**
* The organ to display in the banner.
*/
organ: Organ|null;
/**
* The name to display in the banner.
*/
name?: string;
/**
* The origin date of the organ.
*/
from?: Date;
/**
* The end date of the organ.
*/
to?: Date;
/**
* The age of the organ.
*/
age?: number;
/**
* The social media links to display in the banner.
*/
socials?: {[name: string]: string[]};
/**
* Whether to show social media links.
*/
showSocials?: boolean;
/**
* Whether to show the banner in a small size.
*/
small?: boolean;
/**
* Whether to show the banner in an extra small size.
*/
extraSmall?: boolean;
}>();
const icons: {[name: string]: { icon: string, title: string, }} = {
phone: { icon: 'fa-solid fa-phone', title: 'Phone', },
email: { icon: 'fa-solid fa-envelope', title: 'Email', },
facebook: { icon: 'fa-brands fa-facebook', title: 'Facebook', },
instagram: { icon: 'fa-brands fa-instagram', title: 'Instagram', },
twitter: { icon: 'fa-brands fa-twitter', title: 'Twitter', },
telegram: { icon: 'fa-brands fa-telegram', title: 'Telegram', },
linkedin: { icon: 'fa-brands fa-linkedin', title: 'LinkedIn', },
xing: { icon: 'fa-brands fa-xing', title: 'Xing', },
youtube: { icon: 'fa-brands fa-youtube', title: 'YouTube', },
tiktok: { icon: 'fa-brands fa-tiktok', title: 'TikTok', },
website: { icon: 'fa-solid fa-globe', title: 'Website', },
other: { icon: 'fa-solid fa-hashtag', title: 'Other', },
};
const copyLink = (link: string) => {
navigator.clipboard.writeText(link);
};
const socialsShown: Ref<{[name: string]: boolean}> = ref({});
if (props.socials) {
Object.keys(props.socials).forEach((name) => {
socialsShown.value[name] = false;
});
}
</script>

<template>
<div
:class="[
'banner',
props.small||props.extraSmall ? 'small' : '',
props.extraSmall ? 'extra-small' : '',
]"
>
<div
v-if="props.extraSmall"
class="banner-image"
>
<img
:src="props.organ ? props.organ.pic.src() : '/john-doe.png'"
:alt="props.name ? props.name : 'Organ image'"
/>
</div>
<div
class="banner-facts"
v-if="props.organ"
>
<h1 v-if="!(props.small||props.extraSmall)">
{{ props.name }}
</h1>
<h3 v-else>
{{ props.name }}
</h3>
<div class="banner-birth-death">
<span v-if="props.from">
<font-awesome-icon icon="fa-solid fa-baby" />
{{ props.from.toLocaleDateString('en-us', { weekday:undefined, year:"numeric", month:"short", day:"numeric"}) }}
</span>
<span v-if="props.to">
<font-awesome-icon icon="fa-solid fa-skull" />
{{ props.to.toLocaleDateString('en-us', { weekday:undefined, year:"numeric", month:"short", day:"numeric"}) }}
</span>
<span v-if="props.age">
(Age: {{ props.age }})
</span>
</div>
<div v-if="props.showSocials && props.socials" class="banner-socials">
<template
v-for="name in Object.keys(props.socials)"
:key="name"
>
<font-awesome-icon
:icon="icons[name].icon"
:title="icons[name].title"
:style="{ color: socialsShown[name] ? 'var(--color-text-focus)' : 'var(--color-text)' }"
@click="() => {
Object.keys(socialsShown)
.filter(key => key !== name)
.forEach((key) => {
socialsShown[key] = false;
});
socialsShown[name] = !socialsShown[name];
}"
/>
<PopDropDown
:shown="socialsShown[name]"
>
<div
v-for="link in props.socials[name]"
:key="link"
class="banner-socials-link"
>
<font-awesome-icon
icon="fa-solid fa-copy"
title="Copy link to clipboard"
@click="() => copyLink(link)"
/>
<a
:href="link"
_target="blank"
>{{ link }}</a>
</div>
</PopDropDown>
</template>
</div>
</div>
<div
class="banner-facts"
v-else
>
<h1 v-if="!props.small">
<i>Organ doesn't exist (anymore) ...</i>
</h1>
<h3 v-else>
<i>Organ doesn't exist (anymore) ...</i>
</h3>
</div>
<div
v-if="!props.extraSmall"
class="banner-image"
>
<img
:src="props.organ ? props.organ.pic.src() : '/john-doe.png'"
:alt="props.name ? props.name : 'Organ image'"
/>
</div>
</div>
</template>

<style scoped>
.banner {
display: flex;
justify-content: stretch;
align-items: center;
gap: 1em;
border-bottom: 2px solid var(--color-border);
padding: 1.5em;
}
.banner.small {
padding: 1em;
}
.banner.extra-small {
border: none;
}
.banner-facts {
flex-grow: 1;
flex-basis: 0;
}
.banner-image img {
width: auto;
height: 12em;
border-radius: 5px;
}
.small .banner-image img {
height: 4em;
}
.extra-small .banner-image img {
height: 2em;
}
.banner-facts h1 {
font-size: 2em;
}
.banner-birth-death {
display: flex;
justify-content: flex-start;
align-items: center;
gap: 1em;
margin-top: .2em;
padding: 0 .5em;
}
.small .banner-birth-death {
padding: 0;
gap: .5em;
}
.extra-small .banner-birth-death {
font-size: .8em;
}
.banner-birth-death span {
display: flex;
justify-content: flex-start;
align-items: center;
gap: .5em;
}
.banner-socials {
display: flex;
justify-content: flex-start;
align-items: center;
gap: .4em;
font-size: 1.1em;
flex-wrap: wrap;
color: var(--color-text);
padding: .5em;
margin-top: .5em;
background-color: var(--color-background-mute);
user-select: none;
}
.banner-socials svg {
cursor: pointer;
transition: color .2s;
}
.banner-socials svg:hover {
color: var(--color-text-focus);
}
.banner-socials-link {
display: flex;
justify-content: flex-start;
align-items: center;
gap: .5em;
padding: .1em;
}
.banner-socials a {
font-size: .9em;
color: var(--color-text);
text-decoration: none;
}
</style>
Loading

0 comments on commit d70f3e2

Please sign in to comment.