UI/UX tweaks and improvements.
This commit is contained in:
parent
4daec9b624
commit
418d3cc402
32 changed files with 2725 additions and 1201 deletions
|
|
@ -1,60 +1,31 @@
|
|||
<template>
|
||||
<ClientOnly>
|
||||
<div v-if="shouldShowBanner" class="w-full">
|
||||
<div
|
||||
:class="[
|
||||
'backdrop-blur-sm border rounded-lg p-4 flex items-start gap-4',
|
||||
statusConfig.bgColor,
|
||||
statusConfig.borderColor,
|
||||
]"
|
||||
>
|
||||
<Icon
|
||||
:name="statusConfig.icon"
|
||||
:class="['w-5 h-5 flex-shrink-0 mt-0.5', statusConfig.textColor]"
|
||||
/>
|
||||
|
||||
<div class="flex-1 min-w-0">
|
||||
<h3 :class="['font-semibold mb-1', statusConfig.textColor]">
|
||||
{{ statusConfig.label }}
|
||||
</h3>
|
||||
<p :class="['text-sm', statusConfig.textColor, 'opacity-90']">
|
||||
{{ bannerMessage }}
|
||||
</p>
|
||||
<div v-if="shouldShowBanner" class="status-banner">
|
||||
<div class="status-banner-inner">
|
||||
<div class="status-banner-text">
|
||||
<strong class="status-banner-label">{{ statusConfig.label }}</strong>
|
||||
<span class="status-banner-msg">{{ bannerMessage }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 flex-shrink-0">
|
||||
<div v-if="nextAction" class="status-banner-actions">
|
||||
<!-- Payment button for pending payment status -->
|
||||
<UButton
|
||||
v-if="isPendingPayment && nextAction"
|
||||
:color="getButtonColor(nextAction.color)"
|
||||
size="sm"
|
||||
:loading="isProcessingPayment"
|
||||
<button
|
||||
v-if="isPendingPayment"
|
||||
:disabled="isProcessingPayment"
|
||||
class="btn btn-primary"
|
||||
@click="handleActionClick"
|
||||
class="whitespace-nowrap"
|
||||
>
|
||||
{{ isProcessingPayment ? "Processing..." : nextAction.label }}
|
||||
</UButton>
|
||||
</button>
|
||||
|
||||
<!-- Link button for other actions -->
|
||||
<NuxtLink
|
||||
v-else-if="nextAction && nextAction.link"
|
||||
v-else-if="nextAction.link"
|
||||
:to="nextAction.link"
|
||||
:class="[
|
||||
'px-4 py-2 rounded-lg font-medium text-sm whitespace-nowrap transition-all',
|
||||
getActionButtonClass(nextAction.color),
|
||||
]"
|
||||
class="btn"
|
||||
>
|
||||
{{ nextAction.label }}
|
||||
</NuxtLink>
|
||||
|
||||
<button
|
||||
v-if="dismissible"
|
||||
@click="isDismissed = true"
|
||||
class="text-guild-400 hover:text-guild-200 transition-colors"
|
||||
:aria-label="`Dismiss ${statusConfig.label} banner`"
|
||||
>
|
||||
<Icon name="heroicons:x-mark" class="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -62,17 +33,6 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
dismissible: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
compact: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const {
|
||||
isPendingPayment,
|
||||
isSuspended,
|
||||
|
|
@ -81,11 +41,9 @@ const {
|
|||
getNextAction,
|
||||
getBannerMessage,
|
||||
} = useMemberStatus();
|
||||
|
||||
const { completePayment, isProcessingPayment } = useMemberPayment();
|
||||
|
||||
const isDismissed = ref(false);
|
||||
|
||||
// Handle action button click
|
||||
const handleActionClick = async () => {
|
||||
if (isPendingPayment.value) {
|
||||
try {
|
||||
|
|
@ -96,33 +54,57 @@ const handleActionClick = async () => {
|
|||
}
|
||||
};
|
||||
|
||||
// Map color names to UButton color props
|
||||
const getButtonColor = (color) => {
|
||||
const colorMap = {
|
||||
orange: "warning",
|
||||
blue: "primary",
|
||||
gray: "neutral",
|
||||
};
|
||||
return colorMap[color] || "primary";
|
||||
};
|
||||
|
||||
// Only show banner if status is not active
|
||||
const shouldShowBanner = computed(() => {
|
||||
if (isDismissed.value) return false;
|
||||
return isPendingPayment.value || isSuspended.value || isCancelled.value;
|
||||
});
|
||||
const shouldShowBanner = computed(
|
||||
() => isPendingPayment.value || isSuspended.value || isCancelled.value,
|
||||
);
|
||||
|
||||
const bannerMessage = computed(() => getBannerMessage());
|
||||
const nextAction = computed(() => getNextAction());
|
||||
|
||||
// Button styling based on color
|
||||
const getActionButtonClass = (color) => {
|
||||
const baseClass = "hover:scale-105 active:scale-95";
|
||||
const colorClasses = {
|
||||
orange: "bg-candlelight-600 text-white hover:bg-candlelight-700",
|
||||
blue: "bg-guild-600 text-white hover:bg-guild-500",
|
||||
gray: "bg-guild-700 text-guild-100 hover:bg-guild-600",
|
||||
};
|
||||
return `${baseClass} ${colorClasses[color] || colorClasses.blue}`;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.status-banner {
|
||||
width: 100%;
|
||||
background: var(--parch);
|
||||
}
|
||||
|
||||
.status-banner-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 10px 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.status-banner-text {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.status-banner-label {
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
color: var(--parch-text);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.status-banner-msg {
|
||||
font-size: 12px;
|
||||
color: var(--parch-text-dim);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.status-banner-actions {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Ensure no border-radius leaks in from global resets or UButton */
|
||||
.status-banner .btn {
|
||||
border-radius: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue