feat: 🎸 update portal ui

This commit is contained in:
zhangqingwu
2024-07-01 16:52:04 +08:00
committed by Lyric Wai
parent 8cc38e0e18
commit 7f1ea7e49e
8 changed files with 134 additions and 25 deletions

View File

@@ -11,12 +11,17 @@
<div class="items-container">
<div class="items">
<div v-for="(item, index) in items" :key="index" class="item">
<div v-for="(item, index) in comments" :key="index" class="item">
<img class="quote" src="/portal-static/icon/double-quote.svg" />
<div class="top">
<span>
<img width="56" height="56" :src="item.avatar" />
<img
width="56"
height="56"
class="rounded-full"
:src="item.avatar"
/>
</span>
<div class="ml-3">
@@ -38,37 +43,44 @@ export default {
</script>
<script lang="ts" setup>
import { request } from "@/utils/http";
const items = ref([
{
avatar: "/portal-static/images/avatar/avatar31766.jpg",
mixinId: 31766,
avatar: "/portal-static/avatars/31766.jpg",
name: "阿信",
hint: "连续打卡 1,000 天",
text: "发现自己发音错误很有帮助,之前是不知不觉,现在注意到了,开始纠正练习。",
},
{
avatar: "/portal-static/images/avatar.png",
name: "东心木",
hint: "连续打卡 1,000 天",
text: "朗读更流利了,表达更地道了。",
},
{
avatar: "/portal-static/images/avatar/avatar39503702.jpg",
mixinId: 39503702,
avatar: "/portal-static/avatars/39503702.jpg",
name: "二十初仲夏的树",
hint: "连续打卡 1,000 天",
text: "五个月,语感和口语熟练度提高了很多,附带着阅读能力也提高了,感觉读多了以后大胆了很多,估计碰到外国人敢开口了,有时候甚至自己都能小小造句了。",
},
{
avatar: "/portal-static/images/avatar/avatar37300002.jpg",
mixinId: 37300002,
avatar: "/portal-static/avatars/37300002.jpg",
name: "黄明英",
hint: "连续打卡 1,000 天",
text: "跟着朗读,慢慢有停顿、升调降调感觉。",
},
{
avatar: "/portal-static/images/avatar/avatar39440639.jpg",
mixinId: 39440639,
avatar: "/portal-static/avatars/39440639.jpg",
name: "朱国庆",
hint: "连续打卡 1,000 天",
text: "App 帮助我解决发音问题,就像一位私人教练,随时纠正发音错误,很多旧的发音习惯得到了纠正,让我的英语发音比之前有了很大的提高。 ",
},
{
mixinId: 40303463,
avatar: "/portal-static/images/avatar.png",
name: "东心木",
hint: "连续打卡 1,000 天",
text: "朗读更流利了,表达更地道了。",
},
{
avatar: "/portal-static/images/avatar.png",
name: "匿名用户",
@@ -106,6 +118,41 @@ const items = ref([
text: "听力更清晰,特别是在听背的熟练的说法时。",
},
]);
const infos = ref<any[]>([]);
const comments = computed(() => {
return items.value.map((item) => {
const info = infos.value.find((info) => info.mixinId === item.mixinId);
if (!info) return item;
return {
...item,
name: info.mixinId,
avatar: info.avatar_url,
hint: `连续打卡 ${Number(info.recordings_count).toLocaleString()}`,
};
});
});
onMounted(async () => {
requestUserInfo();
});
async function requestUserInfo() {
infos.value = await Promise.all(
items.value
.filter((item) => item.mixinId)
.map(async (item) => {
const resp = await request(
`https://enjoy.bot/api/users/${item.mixinId}/stats`
);
return { ...resp, mixinId: item.mixinId };
})
);
}
</script>
<style lang="scss" scoped>
.comments {
@@ -139,6 +186,10 @@ const items = ref([
gap: 16px;
animation: scroll 30s linear infinite;
&:hover {
animation-play-state: paused;
}
.item {
padding: 24px;
border-radius: 4px;

View File

@@ -28,14 +28,24 @@
一起享受这1000小时
</div>
<div class="mt-6">
<button
class="action hover:bg-primary bg-greyscale_2 text-white px-5 py-4 inline-flex rounded-full items-center text-[14px] md:text-[16px]"
>
<span class="mr-1">体验 Enjoy App</span>
<div class="mt-6 max-sm:inline-flex max-sm:gap-4 max-sm:flex-col">
<a href="https://1000h.org/intro.html" target="_blank">
<button
class="action px-4 py-3 md:px-5 md:py-4 text-[14px] md:text-[16px] max-sm:w-[260px]"
>
<span class="mr-1">开启我的 1000 小时</span>
<img src="/portal-static/icon/arrow-right.svg" width="24" />
</button>
<img src="/portal-static/icon/arrow-right.svg" width="24" />
</button>
</a>
<a href="https://1000h.org/enjoy-app/install.html" target="_blank">
<button
class="action secondary px-4 py-3 md:px-5 md:py-4 text-[14px] md:text-[16px] sm:ml-4 max-sm:w-[260px]"
>
<span class="mr-1">体验 Enjoy App</span>
</button>
</a>
</div>
</div>
@@ -69,6 +79,27 @@ export default {
.action {
transition: ease-in-out 0.2s;
display: inline-flex;
align-items: center;
justify-content: center;
background: #252525;
color: white;
border-radius: 9999px;
&:hover {
background: #4797f5;
}
}
.action.secondary {
border: 2px solid #252525;
color: #252525;
background: white;
&:hover {
color: #4797f5;
border-color: #4797f5;
}
}
.demo {

View File

@@ -1,6 +1,6 @@
<template>
<div class="footer">
<div>© {{year}} ANEX Inc.</div>
<div>© {{ year }} ANEX Inc.</div>
<div class="opacity-50 mt-1">All rights reserved.</div>
</div>
</template>
@@ -9,13 +9,13 @@
export default {
name: "PageFooter",
};
const year = computed(() => {
return (new Date()).getFullYear();
})
</script>
<script lang="ts" setup></script>
<script lang="ts" setup>
const year = computed(() => {
return new Date().getFullYear();
});
</script>
<style lang="scss" scoped>
.footer {

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,27 @@
export async function request(url: string) {
const perfix = "http-cache";
const key = `${perfix}-${url}`;
try {
const value = JSON.parse(localStorage.getItem(key) || "");
if (Number(value.expire_time) > new Date().getTime()) {
return value.data;
}
} catch (error) {
// ignore
}
const resp = await fetch(url, { method: "Get" });
const data = await resp.json();
localStorage.setItem(
key,
JSON.stringify({
expire_time: new Date().getTime() + 1000 * 60 * 60 * 24,
data,
})
);
return data;
}