Adding features
This commit is contained in:
parent
600fef2b7c
commit
2b55ca4104
75 changed files with 9796 additions and 2759 deletions
|
|
@ -1,288 +1,31 @@
|
|||
<template>
|
||||
<footer
|
||||
class="py-16 border-t"
|
||||
:class="[
|
||||
backgroundClass,
|
||||
borderClass
|
||||
]"
|
||||
>
|
||||
<UContainer>
|
||||
<!-- Main Footer Content -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8 mb-12">
|
||||
<!-- Brand Section -->
|
||||
<div class="lg:col-span-1">
|
||||
<div class="flex items-center gap-2 mb-4">
|
||||
<div class="w-8 h-8 rounded-full flex items-center justify-center" :class="logoBackgroundClass">
|
||||
<div class="w-4 h-4 bg-white rounded-sm" />
|
||||
</div>
|
||||
<div class="w-6 h-6" :class="logoBackgroundClass" style="clip-path: polygon(50% 0%, 0% 100%, 100% 100%)" />
|
||||
<span class="text-2xl font-bold ml-2" :class="brandTextClass">{{ brandName }}</span>
|
||||
</div>
|
||||
<p :class="textColorClass" class="text-sm leading-relaxed">
|
||||
{{ description }}
|
||||
<footer class="mt-32 pb-16 px-8 md:px-12 lg:px-16">
|
||||
<!-- Minimal footer content -->
|
||||
<div class="max-w-4xl">
|
||||
<div
|
||||
class="flex flex-col md:flex-row justify-between items-start md:items-end gap-8"
|
||||
>
|
||||
<!-- Left: Copyright and minimal info -->
|
||||
<div>
|
||||
<p class="text-stone-500 text-xs mb-2">
|
||||
© {{ currentYear }} Ghost Guild
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Navigation Links -->
|
||||
<div class="lg:col-span-1">
|
||||
<h3 class="font-semibold mb-4" :class="headingColorClass">Navigation</h3>
|
||||
<ul class="space-y-2">
|
||||
<li v-for="link in navigationLinks" :key="link.path">
|
||||
<NuxtLink
|
||||
:to="link.path"
|
||||
:class="linkColorClass"
|
||||
class="text-sm hover:underline transition-colors"
|
||||
>
|
||||
{{ link.label }}
|
||||
</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Community Links -->
|
||||
<div class="lg:col-span-1">
|
||||
<h3 class="font-semibold mb-4" :class="headingColorClass">Community</h3>
|
||||
<ul class="space-y-2">
|
||||
<li v-for="link in communityLinks" :key="link.path">
|
||||
<NuxtLink
|
||||
:to="link.path"
|
||||
:class="linkColorClass"
|
||||
class="text-sm hover:underline transition-colors"
|
||||
>
|
||||
{{ link.label }}
|
||||
</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Contact/Social -->
|
||||
<div class="lg:col-span-1">
|
||||
<h3 class="font-semibold mb-4" :class="headingColorClass">Connect</h3>
|
||||
<ul class="space-y-2">
|
||||
<li v-for="link in socialLinks" :key="link.href">
|
||||
<a
|
||||
:href="link.href"
|
||||
:class="linkColorClass"
|
||||
class="text-sm hover:underline transition-colors"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{{ link.label }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- Right: Contact links -->
|
||||
<div class="flex flex-wrap gap-6 text-xs">
|
||||
<a
|
||||
href="mailto:hello@ghostguild.org"
|
||||
class="text-stone-500 hover:text-stone-300 transition-colors"
|
||||
>
|
||||
Contact
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Decorative Elements (matching wireframe) -->
|
||||
<div class="flex items-center justify-between mb-8">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="w-8 h-8 rounded-full flex items-center justify-center" :class="logoBackgroundClass">
|
||||
<div class="w-4 h-4 bg-white rounded-sm" />
|
||||
</div>
|
||||
<div class="w-6 h-6" :class="logoBackgroundClass" style="clip-path: polygon(50% 0%, 0% 100%, 100% 100%)" />
|
||||
</div>
|
||||
|
||||
<div class="hidden md:flex items-center gap-8">
|
||||
<div class="space-y-2">
|
||||
<div class="h-1 w-16 rounded-full" :class="decorativeBarClass" />
|
||||
<div class="h-1 w-12 rounded-full" :class="decorativeBarSecondaryClass" />
|
||||
<div class="h-1 w-14 rounded-full" :class="decorativeBarTertiaryClass" />
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<div class="h-1 w-12 rounded-full" :class="decorativeBarClass" />
|
||||
<div class="h-1 w-16 rounded-full" :class="decorativeBarSecondaryClass" />
|
||||
<div class="h-1 w-10 rounded-full" :class="decorativeBarTertiaryClass" />
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<div class="h-1 w-14 rounded-full" :class="decorativeBarClass" />
|
||||
<div class="h-1 w-10 rounded-full" :class="decorativeBarSecondaryClass" />
|
||||
<div class="h-1 w-16 rounded-full" :class="decorativeBarTertiaryClass" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Copyright -->
|
||||
<div class="pt-8 text-center" :class="borderClass">
|
||||
<p :class="textColorClass" class="text-sm">
|
||||
© {{ currentYear }} {{ brandName }}. {{ copyrightText }}
|
||||
</p>
|
||||
</div>
|
||||
</UContainer>
|
||||
</div>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
theme: {
|
||||
type: String,
|
||||
default: 'purple',
|
||||
validator: (value) => ['purple', 'blue', 'emerald', 'gray'].includes(value)
|
||||
},
|
||||
brandName: {
|
||||
type: String,
|
||||
default: 'Ghost Guild'
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
default: 'A community for game developers exploring cooperative models and building sustainable studios together.'
|
||||
},
|
||||
copyrightText: {
|
||||
type: String,
|
||||
default: 'All rights reserved.'
|
||||
},
|
||||
customNavigationLinks: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
customCommunityLinks: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
customSocialLinks: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
})
|
||||
|
||||
const currentYear = new Date().getFullYear()
|
||||
|
||||
const navigationLinks = computed(() => {
|
||||
if (props.customNavigationLinks.length > 0) {
|
||||
return props.customNavigationLinks
|
||||
}
|
||||
return [
|
||||
{ label: 'Home', path: '/' },
|
||||
{ label: 'About', path: '/about' },
|
||||
{ label: 'Events', path: '/events' },
|
||||
{ label: 'Join', path: '/join' },
|
||||
{ label: 'Contact', path: '/contact' }
|
||||
]
|
||||
})
|
||||
|
||||
const communityLinks = computed(() => {
|
||||
if (props.customCommunityLinks.length > 0) {
|
||||
return props.customCommunityLinks
|
||||
}
|
||||
return [
|
||||
{ label: 'Upcoming Events', path: '/events' },
|
||||
{ label: 'Past Events', path: '/events/past' },
|
||||
{ label: 'Event Calendar', path: '/events/calendar' },
|
||||
{ label: 'Members Directory', path: '/members' }
|
||||
]
|
||||
})
|
||||
|
||||
const socialLinks = computed(() => {
|
||||
if (props.customSocialLinks.length > 0) {
|
||||
return props.customSocialLinks
|
||||
}
|
||||
return [
|
||||
{ label: 'Discord Community', href: 'https://discord.gg/ghostguild' },
|
||||
{ label: 'Twitter', href: 'https://twitter.com/ghostguild' },
|
||||
{ label: 'GitHub', href: 'https://github.com/ghostguild' },
|
||||
{ label: 'Contact Us', href: 'mailto:hello@ghostguild.org' }
|
||||
]
|
||||
})
|
||||
|
||||
const backgroundClass = computed(() => {
|
||||
const themes = {
|
||||
purple: 'bg-purple-50 dark:bg-purple-900/20',
|
||||
blue: 'bg-blue-50 dark:bg-blue-900/20',
|
||||
emerald: 'bg-emerald-50 dark:bg-emerald-900/20',
|
||||
gray: 'bg-gray-50 dark:bg-gray-900'
|
||||
}
|
||||
return themes[props.theme] || themes.purple
|
||||
})
|
||||
|
||||
const borderClass = computed(() => {
|
||||
const themes = {
|
||||
purple: 'border-purple-200 dark:border-purple-800',
|
||||
blue: 'border-blue-200 dark:border-blue-800',
|
||||
emerald: 'border-emerald-200 dark:border-emerald-800',
|
||||
gray: 'border-gray-200 dark:border-gray-700'
|
||||
}
|
||||
return themes[props.theme] || themes.purple
|
||||
})
|
||||
|
||||
const logoBackgroundClass = computed(() => {
|
||||
const themes = {
|
||||
purple: 'bg-purple-500',
|
||||
blue: 'bg-blue-500',
|
||||
emerald: 'bg-emerald-500',
|
||||
gray: 'bg-gray-500'
|
||||
}
|
||||
return themes[props.theme] || themes.purple
|
||||
})
|
||||
|
||||
const brandTextClass = computed(() => {
|
||||
const themes = {
|
||||
purple: 'text-purple-600 dark:text-purple-400',
|
||||
blue: 'text-blue-600 dark:text-blue-400',
|
||||
emerald: 'text-emerald-600 dark:text-emerald-400',
|
||||
gray: 'text-gray-900 dark:text-white'
|
||||
}
|
||||
return themes[props.theme] || themes.purple
|
||||
})
|
||||
|
||||
const headingColorClass = computed(() => {
|
||||
const themes = {
|
||||
purple: 'text-purple-900 dark:text-purple-100',
|
||||
blue: 'text-blue-900 dark:text-blue-100',
|
||||
emerald: 'text-emerald-900 dark:text-emerald-100',
|
||||
gray: 'text-gray-900 dark:text-white'
|
||||
}
|
||||
return themes[props.theme] || themes.purple
|
||||
})
|
||||
|
||||
const textColorClass = computed(() => {
|
||||
const themes = {
|
||||
purple: 'text-purple-600 dark:text-purple-400',
|
||||
blue: 'text-blue-600 dark:text-blue-400',
|
||||
emerald: 'text-emerald-600 dark:text-emerald-400',
|
||||
gray: 'text-gray-600 dark:text-gray-400'
|
||||
}
|
||||
return themes[props.theme] || themes.purple
|
||||
})
|
||||
|
||||
const linkColorClass = computed(() => {
|
||||
const themes = {
|
||||
purple: 'text-purple-700 dark:text-purple-300 hover:text-purple-900 dark:hover:text-purple-100',
|
||||
blue: 'text-blue-700 dark:text-blue-300 hover:text-blue-900 dark:hover:text-blue-100',
|
||||
emerald: 'text-emerald-700 dark:text-emerald-300 hover:text-emerald-900 dark:hover:text-emerald-100',
|
||||
gray: 'text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-gray-100'
|
||||
}
|
||||
return themes[props.theme] || themes.purple
|
||||
})
|
||||
|
||||
const decorativeBarClass = computed(() => {
|
||||
const themes = {
|
||||
purple: 'bg-purple-500',
|
||||
blue: 'bg-blue-500',
|
||||
emerald: 'bg-emerald-500',
|
||||
gray: 'bg-gray-500'
|
||||
}
|
||||
return themes[props.theme] || themes.purple
|
||||
})
|
||||
|
||||
const decorativeBarSecondaryClass = computed(() => {
|
||||
const themes = {
|
||||
purple: 'bg-purple-400',
|
||||
blue: 'bg-blue-400',
|
||||
emerald: 'bg-emerald-400',
|
||||
gray: 'bg-gray-400'
|
||||
}
|
||||
return themes[props.theme] || themes.purple
|
||||
})
|
||||
|
||||
const decorativeBarTertiaryClass = computed(() => {
|
||||
const themes = {
|
||||
purple: 'bg-purple-300',
|
||||
blue: 'bg-blue-300',
|
||||
emerald: 'bg-emerald-300',
|
||||
gray: 'bg-gray-300'
|
||||
}
|
||||
return themes[props.theme] || themes.purple
|
||||
})
|
||||
</script>
|
||||
const currentYear = new Date().getFullYear();
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue