177 lines
3.7 KiB
Vue
177 lines
3.7 KiB
Vue
<template>
|
|
<div class="media">
|
|
<img class="bg" src="@/assets/images/media/bg.jpg" alt="" />
|
|
<section class="header">
|
|
<h1 v-custom-animation.once duration="1s" translate-y-s="-100" opacity-s="0">Media</h1>
|
|
</section>
|
|
<section class="content">
|
|
<div class="box">
|
|
<div class="nav">
|
|
<span
|
|
class="hover-bottom-animation center"
|
|
v-for="v in navList"
|
|
:key="v.value"
|
|
:class="{ active: v.value === nav }"
|
|
@click="nav = v.value"
|
|
>{{ v.label }}</span
|
|
>
|
|
</div>
|
|
<div class="list">
|
|
<div class="item" v-for="v in list" :key="nav + v.text">
|
|
<span class="date">{{ FormatDate(v.date, 'SM D, YYYY') }}</span>
|
|
<span class="text">{{ v.text }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</template>
|
|
<script setup lang="ts">
|
|
import { computed, ref } from 'vue'
|
|
import listEn from './list-en.js'
|
|
import listZhCn from './list-zh-cn.js'
|
|
import listZhTw from './list-zh-tw.js'
|
|
import { LangType } from '../../lang'
|
|
import { useI18n } from 'vue-i18n'
|
|
const { locale } = useI18n()
|
|
const allList = computed(() => {
|
|
if (locale.value === LangType.zhCn) {
|
|
return listZhCn
|
|
}
|
|
if (locale.value === LangType.zhTw) {
|
|
return listZhTw
|
|
}
|
|
return listEn
|
|
})
|
|
const list = computed(() => {
|
|
return allList.value.filter((v) =>
|
|
nav.value === 0 ? true : new Date(v.date).getFullYear() === nav.value
|
|
)
|
|
})
|
|
const nav = ref(0)
|
|
const navList = computed(() => {
|
|
const arr = [
|
|
{
|
|
label: 'All',
|
|
value: 0
|
|
}
|
|
]
|
|
allList.value.forEach((v) => {
|
|
const year = new Date(v.date).getFullYear()
|
|
if (!arr.find((item) => item.value === year)) {
|
|
arr.push({
|
|
label: String(year),
|
|
value: year
|
|
})
|
|
}
|
|
})
|
|
return arr
|
|
})
|
|
const FormatDate = (value = new Date(), format: string = 'YYYY-MM-DD HH:mm:ss') => {
|
|
const d = new Date(value)
|
|
if (!d || isNaN(d.getTime())) return 'Invalid Date'
|
|
const pad = (n) => String(n).padStart(2, '0')
|
|
const months = [
|
|
'Jan',
|
|
'Feb',
|
|
'Mar',
|
|
'Apr',
|
|
'May',
|
|
'Jun',
|
|
'Jul',
|
|
'Aug',
|
|
'Sep',
|
|
'Oct',
|
|
'Nov',
|
|
'Dec'
|
|
]
|
|
const tokens = {
|
|
YYYY: d.getFullYear(),
|
|
YY: String(d.getFullYear()).slice(-2),
|
|
MM: pad(d.getMonth() + 1),
|
|
M: d.getMonth() + 1,
|
|
SM: months[d.getMonth()],
|
|
DD: pad(d.getDate()),
|
|
D: d.getDate(),
|
|
HH: pad(d.getHours()),
|
|
H: d.getHours(),
|
|
hh: pad(d.getHours() % 12 || 12),
|
|
h: d.getHours() % 12 || 12,
|
|
mm: pad(d.getMinutes()),
|
|
m: d.getMinutes(),
|
|
ss: pad(d.getSeconds()),
|
|
s: d.getSeconds(),
|
|
A: d.getHours() < 12 ? 'AM' : 'PM',
|
|
a: d.getHours() < 12 ? 'am' : 'pm'
|
|
}
|
|
const reg = new RegExp(Object.keys(tokens).join('|'), 'g')
|
|
return format.replace(reg, (match) => tokens[match])
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
.media {
|
|
> * {
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
> .bg {
|
|
height: 464px;
|
|
width: 100%;
|
|
object-fit: cover;
|
|
position: fixed;
|
|
top: 0;
|
|
z-index: 0;
|
|
}
|
|
> .header {
|
|
height: 464px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
> h1 {
|
|
font-size: 64px;
|
|
font-weight: 600;
|
|
letter-spacing: 2px;
|
|
color: #fff;
|
|
}
|
|
}
|
|
> .content {
|
|
width: 100%;
|
|
padding: 100px 0;
|
|
background-color: #fff;
|
|
font-size: 14px;
|
|
> .box {
|
|
max-width: 1140px;
|
|
margin: 0 auto;
|
|
> .nav {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 30px;
|
|
> span {
|
|
--background-color: #a4004f;
|
|
line-height: 34px;
|
|
color: #333;
|
|
}
|
|
}
|
|
> .list {
|
|
padding: 14px;
|
|
> div {
|
|
animation: opacity-in 0.3s ease-in-out;
|
|
margin-top: 14px;
|
|
margin-bottom: 10px;
|
|
display: flex;
|
|
> .date {
|
|
min-width: 130px;
|
|
margin-right: 10px;
|
|
color: #999;
|
|
}
|
|
> .text {
|
|
color: #222;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|