print-log.vue 6.46 KB
<template>
  <view class="page">
    <view class="header-hero" :style="{ paddingTop: statusBarHeight + 'px' }">
      <view class="top-bar">
        <view class="top-left" @click="goBack">
          <AppIcon name="chevronLeft" size="sm" color="white" />
        </view>
        <view class="top-center">
          <text class="page-title">Print Log</text>
          <LocationPicker />
        </view>
        <view class="top-right" @click="isMenuOpen = true">
          <AppIcon name="menu" size="sm" color="white" />
        </view>
      </view>
    </view>

    <scroll-view class="content" scroll-y>
      <view class="log-list">
        <view
          v-for="row in printLogData"
          :key="row.labelId"
          class="log-card"
        >
          <view class="card-header">
            <text class="product-name">{{ row.productName }}</text>
            <text class="label-id">{{ row.labelId }}</text>
          </view>
          <view class="card-tags">
            <text class="tag">{{ row.category }}</text>
            <text class="tag">{{ row.template }}</text>
          </view>
          <view class="card-details">
            <view class="detail-row">
              <AppIcon name="clock" size="sm" color="gray" />
              <text class="detail-text">{{ row.printedAt }}</text>
            </view>
            <view class="detail-row">
              <AppIcon name="user" size="sm" color="gray" />
              <text class="detail-text">{{ row.printedBy }}</text>
            </view>
            <view class="detail-row">
              <AppIcon name="mapPin" size="sm" color="gray" />
              <text class="detail-text">{{ row.location }}</text>
            </view>
            <view class="detail-row">
              <AppIcon name="calendar" size="sm" color="gray" />
              <text class="detail-text">Expires {{ row.expiryDate }}</text>
            </view>
          </view>
          <view class="card-footer">
            <view class="reprint-btn" @click="handleReprint(row)">
              <AppIcon name="printer" size="sm" color="white" />
              <text class="reprint-text">Reprint</text>
            </view>
          </view>
        </view>
      </view>
    </scroll-view>

    <SideMenu v-model="isMenuOpen" />
  </view>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import AppIcon from '../../components/AppIcon.vue'
import SideMenu from '../../components/SideMenu.vue'
import LocationPicker from '../../components/LocationPicker.vue'
import { getStatusBarHeight } from '../../utils/statusBar'

const statusBarHeight = getStatusBarHeight()
const isMenuOpen = ref(false)

const printLogData = ref([
  { labelId: '1-251201', productName: 'Whole Milk', category: 'Dairy', template: '2"x2" Basic', printedAt: '2024-03-20 09:30 AM', printedBy: 'Alice Johnson', location: 'Downtown Store (101)', expiryDate: '2024-03-27' },
  { labelId: '2-251201', productName: 'Ground Beef', category: 'Meat', template: '2"x2" Basic', printedAt: '2024-03-20 10:15 AM', printedBy: 'Bob Smith', location: 'Uptown Store (102)', expiryDate: '2024-03-23' },
  { labelId: '3-251201', productName: 'Croissant', category: 'Bakery', template: '2"x2" Basic', printedAt: '2024-03-19 14:00 PM', printedBy: 'Charlie Brown', location: 'Downtown Store (101)', expiryDate: '2024-03-20' },
  { labelId: '4-251201', productName: 'Caesar Salad', category: 'Deli', template: '2"x6" G\'n\'G !!!', printedAt: '2024-03-18 11:45 AM', printedBy: 'Alice Johnson', location: 'Downtown Store (101)', expiryDate: '2024-03-21' },
  { labelId: '5-251201', productName: 'Orange Juice', category: 'Beverage', template: '2"x2" Basic', printedAt: '2024-03-18 08:20 AM', printedBy: 'Bob Smith', location: 'Airport Kiosk (201)', expiryDate: '2024-03-25' },
])

const handleReprint = (row: any) => {
  uni.showToast({ title: 'Reprint: ' + row.productName, icon: 'none' })
}

const goBack = () => {
  const pages = getCurrentPages()
  if (pages.length > 1) {
    uni.navigateBack()
  } else {
    uni.redirectTo({ url: '/pages/index/index' })
  }
}
</script>

<style scoped>
.page {
  min-height: 100vh;
  background: #f3f4f6;
  display: flex;
  flex-direction: column;
}

.header-hero {
  background: linear-gradient(135deg, #1F3A8A, #142a6c);
  padding: 16rpx 32rpx 24rpx;
}

.top-bar {
  height: 96rpx;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.top-left,
.top-right {
  width: 64rpx;
  height: 64rpx;
  border-radius: 999rpx;
  background: rgba(255, 255, 255, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
}

.top-center {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.page-title {
  font-size: 34rpx;
  font-weight: 600;
  color: #fff;
}

.content {
  flex: 1;
  padding: 24rpx 28rpx 40rpx;
  box-sizing: border-box;
}

.log-list {
  display: flex;
  flex-direction: column;
  gap: 20rpx;
}

.log-card {
  background: #fff;
  border-radius: 24rpx;
  padding: 0;
  box-shadow: 0 2rpx 16rpx rgba(0, 0, 0, 0.04);
  overflow: hidden;
  border: 1rpx solid #e5e7eb;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 28rpx 28rpx 20rpx;
  background: linear-gradient(180deg, #fafbfc 0%, #fff 100%);
}

.product-name {
  font-size: 34rpx;
  font-weight: 700;
  color: #111827;
  flex: 1;
  line-height: 1.3;
  letter-spacing: -0.02em;
}

.label-id {
  font-size: 22rpx;
  color: #9ca3af;
  flex-shrink: 0;
  margin-left: 16rpx;
  padding: 6rpx 12rpx;
  background: #f3f4f6;
  border-radius: 8rpx;
}

.card-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 12rpx;
  padding: 0 28rpx 20rpx;
}

.tag {
  font-size: 24rpx;
  color: #1F3A8A;
  background: #e8ecf5;
  padding: 8rpx 18rpx;
  border-radius: 10rpx;
  font-weight: 500;
}

.card-details {
  display: flex;
  flex-direction: column;
  gap: 16rpx;
  padding: 24rpx 28rpx;
  background: #fafbfc;
  border-top: 1rpx solid #e5e7eb;
}

.detail-row {
  display: flex;
  align-items: center;
  gap: 12rpx;
}

.detail-text {
  font-size: 28rpx;
  color: #4b5563;
  line-height: 1.4;
}

.card-footer {
  padding: 20rpx 28rpx 24rpx;
  background: #fff;
  border-top: 1rpx solid #e5e7eb;
}

.reprint-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10rpx;
  padding: 16rpx 32rpx;
  background: linear-gradient(135deg, #1F3A8A, #1447E6);
  border-radius: 14rpx;
  box-shadow: 0 4rpx 12rpx rgba(31, 58, 138, 0.25);
}

.reprint-btn:active {
  opacity: 0.9;
  transform: scale(0.98);
}

.reprint-text {
  font-size: 28rpx;
  font-weight: 600;
  color: #fff;
}
</style>