feat: migrate ice venue module

This commit is contained in:
gqt
2026-06-08 21:00:32 +08:00
parent 8e1443f7e5
commit 0f4e04f4ad
28 changed files with 5684 additions and 0 deletions
@@ -0,0 +1,210 @@
<template>
<view class="state-panel" :class="[type, { compact }]">
<view class="state-mark" v-if="showMark">
<text class="state-mark-text">{{ markText }}</text>
</view>
<view class="state-copy" v-if="title || description">
<text class="state-title" v-if="title">{{ title }}</text>
<text class="state-description" v-if="description">{{ description }}</text>
</view>
<view class="state-actions" v-if="primaryText || secondaryText">
<button
v-if="primaryText"
class="state-btn primary"
:loading="loading"
:disabled="loading"
@tap="$emit('primary')"
>
{{ primaryText }}
</button>
<button
v-if="secondaryText"
class="state-btn secondary"
:disabled="loading"
@tap="$emit('secondary')"
>
{{ secondaryText }}
</button>
</view>
</view>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
title: {
type: String,
default: ''
},
description: {
type: String,
default: ''
},
primaryText: {
type: String,
default: ''
},
secondaryText: {
type: String,
default: ''
},
type: {
type: String,
default: 'default'
},
loading: {
type: Boolean,
default: false
},
compact: {
type: Boolean,
default: false
},
showMark: {
type: Boolean,
default: true
}
})
defineEmits(['primary', 'secondary'])
const markText = computed(() => {
const map = {
login: '登',
expired: '重',
profile: '档',
error: '!',
empty: '空',
loading: '...'
}
return map[props.type] || 'i'
})
</script>
<style lang="scss" scoped>
.state-panel {
min-height: 520rpx;
padding: 80rpx $spacing-lg;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
gap: $spacing-lg;
&.compact {
min-height: 280rpx;
padding: $spacing-xl $spacing-lg;
}
}
.state-mark {
width: 88rpx;
height: 88rpx;
border-radius: 44rpx;
background-color: $color-primary-light;
display: flex;
align-items: center;
justify-content: center;
.state-mark-text {
font-size: 30rpx;
font-weight: 800;
color: $color-primary;
}
}
.state-panel.expired,
.state-panel.error {
.state-mark {
background-color: $color-danger-light;
.state-mark-text {
color: $color-danger;
}
}
}
.state-panel.profile {
.state-mark {
background-color: $color-warning-light;
.state-mark-text {
color: $color-warning;
}
}
}
.state-panel.empty {
.state-mark {
background-color: $bg-color-hover;
.state-mark-text {
color: $text-color-light;
}
}
}
.state-copy {
display: flex;
flex-direction: column;
align-items: center;
gap: $spacing-sm;
max-width: 560rpx;
.state-title {
font-size: 34rpx;
line-height: 1.35;
font-weight: 700;
color: $text-color-main;
}
.state-description {
font-size: 26rpx;
line-height: 1.6;
color: $text-color-muted;
}
}
.state-actions {
width: 100%;
max-width: 520rpx;
display: flex;
flex-direction: column;
gap: $spacing-sm;
}
.state-btn {
width: 100%;
height: 88rpx;
border-radius: $border-radius-base;
font-size: 28rpx;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
&::after {
border: none;
}
&.primary {
color: #FFFFFF;
background-color: $text-color-main;
}
&.secondary {
color: $text-color-regular;
background-color: $bg-color-main;
border: 1rpx solid $border-color;
}
&[disabled] {
color: #FFFFFF;
background-color: $text-color-light;
}
}
</style>