Skip to content

Commit

Permalink
feat: highlights
Browse files Browse the repository at this point in the history
  • Loading branch information
colinlienard committed May 16, 2024
1 parent 5267d51 commit f00e204
Show file tree
Hide file tree
Showing 9 changed files with 176 additions and 143 deletions.
2 changes: 1 addition & 1 deletion app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<Title>GitHundred • Top 100 starred GitHub repositories</Title>
<Meta
name="description"
content="Explore the world's top 100 most starred GitHub repositories, from frameworks to languages to learning resources, with an insightful chart."
content="Explore the world's top 100 most starred GitHub repositories, from frameworks to languages to learning resources, with a highlight section."
/>
</Head>
<Layout>
Expand Down
40 changes: 31 additions & 9 deletions components/InsightCard.vue → components/HighlightCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,28 @@ const { card, index } = defineProps<{ card: Card; index: number }>();
const flippedCards = useFlippedCards();
const flipped = computed(() => flippedCards.value.includes(card.title));
const isFlipping = ref(false);
watch(flipped, (newFlipped) => {
if (!newFlipped) return;
isFlipping.value = true;
setTimeout(() => {
isFlipping.value = false;
}, 1000);
});
const [translateX, translateY, rotate] = (() => {
switch (index) {
case 0:
return ['-1rem', '1rem', '-4deg'];
return ['1rem', '1rem', '4deg'];
case 1:
return ['0rem', '2rem', '2deg'];
return ['0', '1rem', '2deg'];
case 2:
return ['0rem', '0rem', '-2deg'];
return ['0', '0', '-2deg'];
case 3:
return ['1rem', '-2rem', '1deg'];
case 4:
return ['2rem', '2rem', '4deg'];
return ['1rem', '0', '-2deg'];
case 5:
default:
return ['1rem', '-2rem', '-6deg'];
Expand All @@ -32,12 +41,15 @@ const [translateX, translateY, rotate] = (() => {

<template>
<li
class="[perspective:1000px] hover:z-10"
:style="{ transform: `translateX(${translateX}) translateY(${translateY}) rotate(${rotate})` }"
class="[perspective:1000px]"
:style="{
transform: `translateX(${translateX}) translateY(${translateY}) rotate(${rotate})`,
zIndex: isFlipping ? 10 : 0,
}"
@click="!flipped && flippedCards.value.push(card.title)"
>
<div
:class="`card ${flipped && 'flipped'} relative h-96 w-64 cursor-pointer rounded-lg border border-solid border-slate-200 bg-slate-50 text-center shadow-lg transition-all [transform-style:preserve-3d] *:absolute *:flex *:h-full *:w-full *:flex-col *:items-center *:justify-center *:gap-2 *:p-10 *:[backface-visibility:hidden]`"
:class="`card ${flipped && 'flipped'} relative h-96 w-64 cursor-pointer rounded-lg border border-solid border-slate-200 bg-slate-50 text-center transition-all [transform-style:preserve-3d] *:absolute *:flex *:h-full *:w-full *:flex-col *:items-center *:justify-center *:gap-2 *:p-10 *:[backface-visibility:hidden]`"
@click="!flipped && flippedCards.value.push(card.title)"
>
<div>
Expand All @@ -55,11 +67,18 @@ const [translateX, translateY, rotate] = (() => {
</template>

<style scoped>
.card {
--shadow-color: rgba(100, 116, 139, 0.2);
--shadow--blur: 0.5rem;
box-shadow: 0.1rem 0.1rem var(--shadow--blur) var(--shadow-color);
}
.card:hover {
transform: scale(1.05);
transform: scale(1.02);
}
.card.flipped {
box-shadow: -0.1rem 0.1rem var(--shadow--blur) var(--shadow-color);
transform: rotateY(180deg);
animation: flip 1s cubic-bezier(0.6, 0, 0.8, 1);
cursor: default;
Expand All @@ -82,18 +101,21 @@ const [translateX, translateY, rotate] = (() => {
@keyframes flip {
0% {
transform: scale(1) rotateY(0deg);
box-shadow: 0.1rem 0.1rem var(--shadow--blur) var(--shadow-color);
}
20% {
40% {
transform: scale(1.2) rotateY(140deg);
}
80% {
transform: scale(1.3) rotateY(170deg);
box-shadow: -5rem 5rem var(--shadow--blur) var(--shadow-color);
}
95% {
transform: scale(0.9) rotateY(180deg);
}
100% {
transform: scale(1) rotateY(180deg);
box-shadow: -0.1rem 0.1rem var(--shadow--blur) var(--shadow-color);
}
}
Expand Down
41 changes: 3 additions & 38 deletions components/Layout.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
<script setup lang="ts">
import { ArrowPathIcon, CheckIcon, MagnifyingGlassIcon, XMarkIcon } from 'heroicons';
import { ArrowPathIcon } from 'heroicons';
const buildTime = useState(() => Date.now());
const duration = Date.now() - buildTime.value;
const hours = Math.floor(duration / 60 / 60 / 1000);
const lastUpdated = hours > 0 ? `${hours} hour${hours > 1 ? 's' : ''}` : 'less than an hour';
const pointer = usePointer();
const settings = useSettings();
const languages = useLanguages();
onMounted(() => {
window.addEventListener('mousemove', pointer.mousemove);
Expand Down Expand Up @@ -41,7 +39,7 @@ onUnmounted(() => {
GitHub
</NuxtLink>
</header>
<main class="flex w-full flex-col items-center *:max-md:px-6">
<main class="flex w-full flex-col items-center gap-12 *:max-md:px-6 md:gap-16">
<div class="relative flex w-full flex-col items-center gap-6">
<h2
class="max-w-96 text-center font-serif text-5xl font-semibold md:max-w-2xl md:text-6xl"
Expand Down Expand Up @@ -73,40 +71,7 @@ onUnmounted(() => {
<p class="text-sm">Last updated {{ lastUpdated }} ago</p>
</div>
</div>
<div class="flex gap-4">
<NuxtLink to="/">list</NuxtLink>
<NuxtLink to="/insights">insights</NuxtLink>
</div>
<div
class="mt-8 grid w-full grid-cols-[1fr_1fr] gap-2 py-8 [grid-template-areas:'a_a''b_b''c_d'] md:mt-16 md:flex"
>
<Input
v-model="settings.search"
placeholder="Search by name"
class="w-full [grid-area:a]"
>
<MagnifyingGlassIcon />
</Input>
<Select
v-model="settings.languages"
:options="languages.value"
placeholder="Languages"
class="w-full [grid-area:b]"
/>
<Button class="[grid-area:c]" @click="settings.showOwners = !settings.showOwners">
<CheckIcon v-if="settings.showOwners" />
<XMarkIcon v-else />
Show owners
</Button>
<Button
class="[grid-area:d]"
@click="settings.showFullDescription = !settings.showFullDescription"
>
<CheckIcon v-if="settings.showFullDescription" />
<XMarkIcon v-else />
Show full description
</Button>
</div>
<Navigation />
<div class="w-full max-md:overflow-auto">
<slot />
</div>
Expand Down
25 changes: 25 additions & 0 deletions components/Navigation.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<script setup lang="ts">
import { LightBulbIcon, ListBulletIcon } from 'heroicons';
const route = useRoute();
const isHome = computed(() => route.path === '/');
</script>

<template>
<nav
class="relative flex rounded-full border-8 border-solid border-slate-100 bg-slate-200 *:z-10 *:flex *:w-32 *:items-center *:justify-center *:gap-1 *:p-3 *:text-center *:transition-all"
>
<NuxtLink to="/" :style="{ color: isHome ? 'white' : '' }">
<ListBulletIcon class="h-4" />
List
</NuxtLink>
<NuxtLink to="/highlights" :style="{ color: isHome ? '' : 'white' }">
<LightBulbIcon class="h-4" />
Highlights
</NuxtLink>
<div
class="absolute !z-0 h-full w-32 rounded-full bg-slate-800 transition-all"
:style="{ left: isHome ? '0' : '50%' }"
/>
</nav>
</template>
4 changes: 0 additions & 4 deletions composables/useLanguages.ts

This file was deleted.

8 changes: 0 additions & 8 deletions composables/useSettings.ts

This file was deleted.

9 changes: 4 additions & 5 deletions pages/insights.vue → pages/highlights.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup lang="ts">
import type { Card } from '~/components/InsightCard.vue';
import type { Card } from '~/components/HighlightCard.vue';
const { data } = await useFetch('/api/insights');
const { data } = await useFetch('/api/highlights');
type Entries<T> = {
[K in keyof T]: [K, T[K]];
Expand Down Expand Up @@ -64,10 +64,9 @@ const flippedCards = useFlippedCards();
<template>
<div class="flex flex-col items-center gap-6">
<h3 class="text-xl font-semibold">Across all these repositories...</h3>
<ul class="-gap-4 grid w-fit grid-cols-3">
<InsightCard v-for="(card, index) of cards" :key="card.title" :card="card" :index="index" />
<ul class="flex w-fit grid-cols-3 flex-col gap-8 md:grid md:gap-0">
<highlightCard v-for="(card, index) of cards" :key="card.title" :card="card" :index="index" />
</ul>
<Confetti v-if="flippedCards.value.length === 6" />
<button @click="flippedCards.value = []">reset</button>
</div>
</template>
Loading

0 comments on commit f00e204

Please sign in to comment.