Refactor components to use ModalDialog and StatusMessage; update styles and remove unused files
Some checks failed
Gitea Actions Demo / build-and-push (push) Failing after 9s
Some checks failed
Gitea Actions Demo / build-and-push (push) Failing after 9s
- Replaced inline modal dialogs in ParentView with a reusable ModalDialog component. - Introduced StatusMessage component for loading and error states in ParentView. - Updated styles to use new colors.css and styles.css for consistent theming. - Removed ChildRewardList.vue and ChildTaskList.vue components as they were no longer needed. - Adjusted RewardAssignView and TaskAssignView to use new styles and shared button styles. - Cleaned up imports across components to reflect the new styles and removed unused CSS files.
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted, computed } from 'vue'
|
||||
import ModalDialog from '../shared/ModalDialog.vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import ChildDetailCard from './ChildDetailCard.vue'
|
||||
import ScrollingList from '../shared/ScrollingList.vue'
|
||||
import { eventBus } from '@/common/eventBus'
|
||||
import '@/assets/view-shared.css'
|
||||
import '@/assets/styles.css'
|
||||
import type {
|
||||
Child,
|
||||
Event,
|
||||
@@ -317,8 +319,91 @@ onUnmounted(() => {
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="loading" class="loading">Loading...</div>
|
||||
<div v-else-if="error" class="error">Error: {{ error }}</div>
|
||||
<StatusMessage :loading="loading" :error="error" />
|
||||
|
||||
<div v-if="!loading && !error" class="layout">
|
||||
<div class="main">
|
||||
<ChildDetailCard :child="child" />
|
||||
<ScrollingList
|
||||
title="Chores"
|
||||
ref="childChoreListRef"
|
||||
:fetchBaseUrl="`/api/task/list?ids=${tasks.join(',')}`"
|
||||
:ids="tasks"
|
||||
itemKey="tasks"
|
||||
imageField="image_id"
|
||||
@trigger-item="triggerTask"
|
||||
:getItemClass="(item) => ({ bad: !item.is_good, good: item.is_good })"
|
||||
:filter-fn="
|
||||
(item) => {
|
||||
return item.is_good
|
||||
}
|
||||
"
|
||||
>
|
||||
<template #item="{ item }">
|
||||
<div class="item-name">{{ item.name }}</div>
|
||||
<img v-if="item.image_url" :src="item.image_url" alt="Task Image" class="item-image" />
|
||||
<div
|
||||
class="item-points"
|
||||
:class="{ 'good-points': item.is_good, 'bad-points': !item.is_good }"
|
||||
>
|
||||
{{ item.is_good ? item.points : -item.points }} Points
|
||||
</div>
|
||||
</template>
|
||||
</ScrollingList>
|
||||
<ScrollingList
|
||||
title="Penalties"
|
||||
ref="childPenaltyListRef"
|
||||
:fetchBaseUrl="`/api/task/list?ids=${tasks.join(',')}`"
|
||||
:ids="tasks"
|
||||
itemKey="tasks"
|
||||
imageField="image_id"
|
||||
@trigger-item="triggerTask"
|
||||
:getItemClass="(item) => ({ bad: !item.is_good, good: item.is_good })"
|
||||
:filter-fn="
|
||||
(item) => {
|
||||
return !item.is_good
|
||||
}
|
||||
"
|
||||
>
|
||||
<template #item="{ item }">
|
||||
<div class="item-name">{{ item.name }}</div>
|
||||
<img v-if="item.image_url" :src="item.image_url" alt="Task Image" class="item-image" />
|
||||
<div
|
||||
class="item-points"
|
||||
:class="{ 'good-points': item.is_good, 'bad-points': !item.is_good }"
|
||||
>
|
||||
{{ item.is_good ? item.points : -item.points }} Points
|
||||
</div>
|
||||
</template>
|
||||
</ScrollingList>
|
||||
<ScrollingList
|
||||
title="Rewards"
|
||||
ref="childRewardListRef"
|
||||
:fetchBaseUrl="`/api/child/${child?.id}/reward-status`"
|
||||
itemKey="reward_status"
|
||||
imageField="image_id"
|
||||
@trigger-item="triggerReward"
|
||||
:getItemClass="
|
||||
(item) => ({ reward: true, disabled: hasPendingRewards && !item.redeeming })
|
||||
"
|
||||
>
|
||||
<template #item="{ item }: { item: RewardStatus }">
|
||||
<div class="item-name">{{ item.name }}</div>
|
||||
<img
|
||||
v-if="item.image_url"
|
||||
:src="item.image_url"
|
||||
alt="Reward Image"
|
||||
class="item-image"
|
||||
/>
|
||||
<div class="item-points">
|
||||
<span v-if="item.redeeming" class="pending">PENDING</span>
|
||||
<span v-if="item.points_needed <= 0" class="ready">REWARD READY</span>
|
||||
<span v-else>{{ item.points_needed }} more points</span>
|
||||
</div>
|
||||
</template>
|
||||
</ScrollingList>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="layout">
|
||||
<div class="main">
|
||||
@@ -404,76 +489,38 @@ onUnmounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="showRewardDialog && dialogReward" class="modal-backdrop">
|
||||
<div class="modal">
|
||||
<div class="reward-info">
|
||||
<img
|
||||
v-if="dialogReward.image_url"
|
||||
:src="dialogReward.image_url"
|
||||
alt="Reward Image"
|
||||
class="reward-image"
|
||||
/>
|
||||
<div class="reward-details">
|
||||
<div class="reward-name">{{ dialogReward.name }}</div>
|
||||
<div class="reward-points">{{ dialogReward.cost }} pts</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dialog-message" style="margin-bottom: 1.2rem">
|
||||
Would you like to redeem this reward?
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button @click="confirmRedeemReward" class="btn btn-primary">Yes</button>
|
||||
<button @click="cancelRedeemReward" class="btn btn-secondary">No</button>
|
||||
</div>
|
||||
<ModalDialog
|
||||
v-if="showRewardDialog && dialogReward"
|
||||
:imageUrl="dialogReward?.image_url"
|
||||
:title="dialogReward.name"
|
||||
:subtitle="`${dialogReward.cost} pts`"
|
||||
>
|
||||
<div class="modal-message">Would you like to redeem this reward?</div>
|
||||
<div class="modal-actions">
|
||||
<button @click="confirmRedeemReward" class="btn btn-primary">Yes</button>
|
||||
<button @click="cancelRedeemReward" class="btn btn-secondary">No</button>
|
||||
</div>
|
||||
</div>
|
||||
</ModalDialog>
|
||||
|
||||
<div v-if="showCancelDialog && dialogReward" class="modal-backdrop">
|
||||
<div class="modal">
|
||||
<div class="reward-info">
|
||||
<img
|
||||
v-if="dialogReward.image_url"
|
||||
:src="dialogReward.image_url"
|
||||
alt="Reward Image"
|
||||
class="reward-image"
|
||||
/>
|
||||
<div class="reward-details">
|
||||
<div class="reward-name">{{ dialogReward.name }}</div>
|
||||
<div class="reward-points">{{ dialogReward.cost }} pts</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dialog-message" style="margin-bottom: 1.2rem">
|
||||
This reward is pending.<br />
|
||||
Would you like to cancel the pending reward request?
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button @click="cancelPendingReward" class="btn btn-primary">Yes</button>
|
||||
<button @click="closeCancelDialog" class="btn btn-secondary">No</button>
|
||||
</div>
|
||||
<ModalDialog
|
||||
v-if="showCancelDialog && dialogReward"
|
||||
:imageUrl="dialogReward?.image_url"
|
||||
:title="dialogReward.name"
|
||||
:subtitle="`${dialogReward.cost} pts`"
|
||||
>
|
||||
<div class="modal-message">
|
||||
This reward is pending.<br />
|
||||
Would you like to cancel the pending reward request?
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
<button @click="cancelPendingReward" class="btn btn-primary">Yes</button>
|
||||
<button @click="closeCancelDialog" class="btn btn-secondary">No</button>
|
||||
</div>
|
||||
</ModalDialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.assign-buttons {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
justify-content: center;
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
background: var(--back-btn-bg);
|
||||
border: 0;
|
||||
padding: 0.6rem 1rem;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
margin-bottom: 1.5rem;
|
||||
color: var(--back-btn-color);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.item-points {
|
||||
color: var(--item-points-color, #ffd166);
|
||||
font-size: 1rem;
|
||||
|
||||
Reference in New Issue
Block a user