Kaynağa Gözat

appointment

冯诚 3 yıl önce
ebeveyn
işleme
173f74fdf1

BIN
src/assets/success-s.png


BIN
src/assets/warn-s.png


+ 55 - 0
src/pages/appointment/StepFive.vue

@@ -0,0 +1,55 @@
+<template>
+  <h3 class="ptc-title">Confirm appointment</h3>
+  <div class="ptc-block">
+    <p class="sub-title">
+      Monday, October 10 9:00 -9:30 PTC Browns Plains Kiosk
+    </p>
+    <div class="mt48">
+      <div class="cell">
+        <span class="cell-label">Phone Brand:</span>
+        <span class="cell-value">Apple</span>
+      </div>
+      <div class="cell">
+        <span class="cell-label">Phone Model:</span>
+        <span class="cell-value">iPhone 12</span>
+      </div>
+      <div class="cell">
+        <span class="cell-label">Phone Number:</span>
+        <span class="cell-value">6668888</span>
+      </div>
+      <div class="cell">
+        <span class="cell-label">IMEI:</span>
+        <span class="cell-value">iPhonaskfjoaxxx</span>
+      </div>
+      <div class="cell">
+        <span class="cell-label">Service:</span>
+        <span class="cell-value">Batery Replacement</span>
+      </div>
+      <div class="cell">
+        <span class="cell-label">Member Price:</span>
+        <span class="cell-value">$35</span>
+      </div>
+      <div class="cell mt48">
+        <span class="cell-label">Postcript:</span>
+        <span class="cell-value"
+          >This is my remark,This is my remarkThis is my remark</span
+        >
+      </div>
+    </div>
+  </div>
+  <div class="ptc-wrap mt48">
+    <button class="ptc-button mb36" @click="$emit('next')">
+      Confirm appointment
+    </button>
+    <button class="ptc-button ptc-button--stroke" @click="$emit('reselect')">
+      Reselect
+    </button>
+  </div>
+</template>
+
+<script setup lang="ts">
+defineEmits<{
+  (e: 'next'): void
+  (e: 'reselect'): void
+}>()
+</script>

+ 16 - 0
src/pages/appointment/StepFour.vue

@@ -0,0 +1,16 @@
+<template>
+  <h3 class="ptc-title">Provide contact information</h3>
+  <div class="ptc-block">
+    <p class="t1">Is there anything to pay attention to, nothing to skip。</p>
+    <textarea placeholder="Please enter, up to 1000 characters"></textarea>
+  </div>
+  <div class="ptc-wrap mt48">
+    <button class="ptc-button" @click="$emit('next')">CONTINUE</button>
+  </div>
+</template>
+
+<script setup lang="ts">
+defineEmits<{
+  (e: 'next'): void
+}>()
+</script>

+ 63 - 0
src/pages/appointment/StepOne.vue

@@ -0,0 +1,63 @@
+<template>
+  <h3 class="ptc-title">Choose a store</h3>
+  <div class="ptc-block">
+    <div class="search-wrap">
+      <input
+        type="text"
+        class="search-input ptc-input"
+        placeholder="Search by zip code"
+        @input="autocomplete"
+      />
+      <div role="button" class="search-btn ptc-button"></div>
+    </div>
+    <div v-if="showSuggestions" class="search-suggestions">
+      <div class="suggestion">PTC Browns Plains Kiosk</div>
+      <div class="suggestion">PTC Browns Plains Kiosk</div>
+    </div>
+    <template v-else>
+      <div class="tip">Nearby shops</div>
+      <ul class="shop-list">
+        <li class="shop-item border-bottom" @click="$emit('next')">
+          <div class="shop-name">
+            <span>PTC Browns Plains Kiosk</span>
+            <span>3.5KM</span>
+          </div>
+          <div class="shop-address">
+            Browns Plains Grand Plaza Shopping Centre, Shop K007 27-49 Browns
+            Plains Road, Browns Plains, QLD, 4118 (07) 3059 1014
+          </div>
+          <div class="shop-mark">
+            <i class="icon"></i>Available for appointment today
+          </div>
+        </li>
+        <li class="shop-item">
+          <div class="shop-name">
+            <span>PTC Browns Plains Kiosk</span>
+            <span>3.5KM</span>
+          </div>
+          <div class="shop-address">
+            Browns Plains Grand Plaza Shopping Centre, Shop K007 27-49 Browns
+            Plains Road, Browns Plains, QLD, 4118 (07) 3059 1014
+          </div>
+          <div class="shop-mark danger">
+            <i class="icon"></i>Available for appointment today
+          </div>
+        </li>
+      </ul>
+    </template>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue'
+
+defineEmits<{
+  (e: 'next'): void
+}>()
+
+const showSuggestions = ref(false)
+
+function autocomplete(e: any) {
+  showSuggestions.value = e.target.value.length > 0
+}
+</script>

+ 55 - 0
src/pages/appointment/StepSix.vue

@@ -0,0 +1,55 @@
+<template>
+  <div class="container">
+    <div class="alert">
+      <i class="alert-icon"></i>
+      <p class="alert-message">Monday, October 10 9:00 -9:30</p>
+    </div>
+    <div class="action">
+      <i class="icon-calendar"></i><strong>Add to calendar ></strong>
+    </div>
+    <div class="note">
+      <p class="note-title">Preparations:</p>
+      <ul class="note-list">
+        <li class="note-item">· You need to back up the data in advance</li>
+        <li class="note-item">· You need to back up the data in advance</li>
+      </ul>
+    </div>
+    <div class="detail">
+      <div class="cell">
+        <span class="cell-label">Store:</span>
+        <span class="cell-value">xxxxxxxxxx</span>
+      </div>
+      <div class="cell">
+        <span class="cell-label">Phone Brand:</span>
+        <span class="cell-value">xxxxxxxxxx</span>
+      </div>
+      <div class="cell">
+        <strong class="ptc-text">Navigation></strong>
+      </div>
+      <div class="cell">
+        <span class="cell-label">Phone Model:</span>
+        <span class="cell-value">xxxxxxxxxx</span>
+      </div>
+      <div class="cell">
+        <span class="cell-label">Phone Number:</span>
+        <span class="cell-value">xxxxxxxxxx</span>
+      </div>
+      <div class="cell">
+        <span class="cell-label">IMEI:</span>
+        <span class="cell-value">xxxxxxxxxx</span>
+      </div>
+      <div class="cell">
+        <span class="cell-label">Service:</span>
+        <span class="cell-value">xxxxxxxxxx</span>
+      </div>
+      <div class="cell">
+        <span class="cell-label">Member Price:</span>
+        <span class="cell-value">$35</span>
+      </div>
+    </div>
+    <div class="mt48">
+      <button class="ptc-button mb36">Reselect time</button>
+      <button class="ptc-button ptc-button--stroke">Cancel appointment</button>
+    </div>
+  </div>
+</template>

+ 20 - 0
src/pages/appointment/StepThree.vue

@@ -0,0 +1,20 @@
+<template>
+  <h3 class="ptc-title">Provide contact information</h3>
+  <div class="ptc-block">
+    <p class="t1">
+      Please provide a mobile number so that the customer service can confirm
+      the details with you。
+    </p>
+    <p class="t2">Phone number</p>
+    <input type="text" class="ptc-input" placeholder="Please enter" />
+  </div>
+  <div class="ptc-wrap mt48">
+    <button class="ptc-button" @click="$emit('next')">CONTINUE</button>
+  </div>
+</template>
+
+<script setup lang="ts">
+defineEmits<{
+  (e: 'next'): void
+}>()
+</script>

+ 49 - 0
src/pages/appointment/StepTwo.vue

@@ -0,0 +1,49 @@
+<template>
+  <h3 class="ptc-title">Appointment</h3>
+  <div class="ptc-block">
+    <div class="shop-name">PTC Browns Plains Kiosk</div>
+    <div class="shop-address">
+      Browns Plains Grand Plaza Shopping Centre, Shop K007 27-49 Browns Plains
+      Road, Browns Plains, QLD, 4118 (07) 3059 1014
+    </div>
+  </div>
+  <div class="ptc-block">
+    <div class="ptc-cell">
+      <p class="ptc-label">Select date</p>
+      <div class="ptc-value">
+        <PtcRadioGroup v-model="state.date" class="date-list">
+          <PtcRadio class="date" value="1">Mon,10</PtcRadio>
+          <PtcRadio class="date" value="2">Mon,10</PtcRadio>
+          <PtcRadio class="date" value="3">Mon,10</PtcRadio>
+          <PtcRadio class="date" value="4">Mon,10</PtcRadio>
+          <PtcRadio class="date" value="5">Mon,10</PtcRadio>
+          <PtcRadio class="date" value="6">Mon,10</PtcRadio>
+          <PtcRadio class="date" value="7">Mon,10</PtcRadio>
+        </PtcRadioGroup>
+      </div>
+    </div>
+  </div>
+  <div class="ptc-block">
+    <div class="ptc-cell">
+      <p class="ptc-label">Selection period</p>
+      <div class="ptc-value">
+        <div class="ptc-select">
+          <!-- <span class="ptc-select__placeholder">请选择</span> -->
+          <span class="ptc-select__value">9:00 - 9:30</span>
+        </div>
+      </div>
+    </div>
+  </div>
+  <div class="ptc-wrap mt48">
+    <button class="ptc-button" @click="$emit('next')">CONTINUE</button>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { PtcRadioGroup, PtcRadio } from '@/components/radio'
+import { state } from './store'
+
+defineEmits<{
+  (e: 'next'): void
+}>()
+</script>

+ 237 - 0
src/pages/appointment/index.vue

@@ -0,0 +1,237 @@
+<template>
+  <div class="p-appointment" :class="{ 'bg-gray': step < 5 }">
+    <component :is="Component" @next="next" />
+  </div>
+</template>
+
+<script setup lang="ts">
+import { useRoute, useRouter } from 'vue-router'
+import StepOne from './StepOne.vue'
+import StepTwo from './StepTwo.vue'
+import StepThree from './StepThree.vue'
+import StepFour from './StepFour.vue'
+import StepFive from './StepFive.vue'
+import StepSix from './StepSix.vue'
+
+const router = useRouter()
+const step = +((useRoute().query.step || '0') as string)
+const Component = [StepOne, StepTwo, StepThree, StepFour, StepFive, StepSix][
+  step
+]
+
+function next() {
+  router.push({
+    path: '',
+    query: {
+      step: step + 1,
+    },
+  })
+}
+</script>
+
+<style lang="scss">
+.p-appointment {
+  .search-wrap {
+    display: flex;
+    height: 88px;
+  }
+  .search-input {
+    flex: 1;
+    height: 100%;
+    border-radius: 8px 0 0 8px;
+    border-right: 0;
+  }
+  .search-btn {
+    width: 120px;
+    height: 100%;
+    border-radius: 0 8px 8px 0;
+    background: $primary-color url(@img/search.png) no-repeat center;
+    background-size: 48px 48px;
+  }
+
+  .suggestion {
+    padding: 48px 0 40px;
+    font-size: 32px;
+    color: #1a1a1a;
+    @include thin-border(bottom);
+    &:active {
+      background: #f2f5fb;
+    }
+  }
+
+  .tip {
+    margin-top: 48px;
+    line-height: 44px;
+    font-size: 32px;
+    color: #999;
+  }
+
+  .shop {
+    &-item {
+      padding: 48px 0;
+
+      &:last-child {
+        padding-bottom: 0;
+        &::before {
+          display: none;
+        }
+      }
+    }
+
+    &-name {
+      display: flex;
+      justify-content: space-between;
+      line-height: 56px;
+      font-size: 40px;
+      font-weight: 600;
+      color: #1a1a1a;
+      span {
+        &:last-child {
+          font-size: 24px;
+          font-weight: 400;
+          color: #999;
+        }
+      }
+    }
+    &-address {
+      margin: 24px 0;
+      line-height: 44px;
+      font-size: 32px;
+      color: #666;
+    }
+    &-mark {
+      position: relative;
+      display: inline-block;
+      vertical-align: top;
+      padding: 0 16px 0 56px;
+      line-height: 48px;
+      font-size: 28px;
+      color: $primary-color;
+      background: #dae1ef;
+      .icon {
+        @include icon('@img/success-s.png', 24px);
+        position: absolute;
+        left: 16px;
+        top: 10px;
+      }
+      &.danger {
+        background: #fce9de;
+        color: #fb5c00;
+
+        .icon {
+          background-image: url(@img/warn-s.png);
+        }
+      }
+    }
+  }
+
+  .date {
+    &-list {
+      display: flex;
+      flex-wrap: wrap;
+      justify-content: space-between;
+    }
+    width: 322px;
+    line-height: 116px;
+    text-align: center;
+    &:nth-child(n + 3) {
+      margin-top: 36px;
+    }
+  }
+
+  .t1 {
+    margin-bottom: 48px;
+    font-size: 32px;
+    line-height: 44px;
+    color: #333;
+  }
+  .t2 {
+    margin-bottom: 48px;
+    font-size: 32px;
+    line-height: 44px;
+    color: #999;
+  }
+  textarea {
+    display: block;
+    padding: 22px 34px;
+    width: 678px;
+    height: 346px;
+    border-radius: 8px;
+    border: 2px solid #d9d9d9;
+    resize: none;
+    font-size: 32px;
+    font-family: inherit;
+    line-height: 44px;
+  }
+
+  .sub-title {
+    line-height: 44px;
+    font-size: 32px;
+    font-weight: 600;
+    color: #333;
+  }
+  .cell {
+    line-height: 64px;
+    font-size: 32px;
+    &-label {
+      margin-right: 8px;
+      color: #999;
+    }
+    &-value {
+      color: #333;
+    }
+  }
+  .mb36 {
+    margin-bottom: 36px;
+  }
+
+  .container {
+    padding: 0 72px;
+  }
+  .alert {
+    margin-top: 64px;
+    &-icon {
+      @include icon('@img/success.png', 96px);
+      display: block;
+      margin: auto;
+    }
+    &-message {
+      margin-top: 32px;
+      text-align: center;
+      line-height: 56px;
+      font-size: 40px;
+      font-weight: bold;
+      color: #333;
+    }
+  }
+  .icon-calendar {
+    margin-right: 8px;
+    width: 32px;
+    height: 32px;
+    background: #eee;
+  }
+  .action {
+    margin: 50px 0 48px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    font-size: 30px;
+    color: $primary-color;
+  }
+  .note {
+    margin-bottom: 48px;
+    padding: 24px 22px;
+    background: #f2f5fb;
+    font-size: 28px;
+    color: #193059;
+    &-title {
+      margin-bottom: 16px;
+      line-height: 40px;
+    }
+    &-list {
+      line-height: 46px;
+      font-size: inherit;
+    }
+  }
+}
+</style>

+ 6 - 0
src/pages/appointment/store.ts

@@ -0,0 +1,6 @@
+import { reactive } from 'vue'
+
+export const state = reactive({
+  date: '',
+  period: '',
+})

+ 5 - 0
src/router.ts

@@ -55,5 +55,10 @@ export default createRouter({
       component: () => import('./pages/renewal/index.vue'),
       props: true,
     },
+    {
+      path: '/appointment',
+      component: () => import('./pages/appointment/index.vue'),
+      props: true,
+    },
   ],
 })

+ 25 - 0
src/style/components.scss

@@ -88,3 +88,28 @@
   background: $danger-color;
   border-radius: 30px 4px 30px 4px;
 }
+
+.ptc-select {
+  position: relative;
+  padding: 0 114px 0 34px;
+  line-height: 84px;
+  border-radius: 8px;
+  border: 2px solid #D9D9D9;
+  font-size: 32px;
+  color: #1a1a1a;
+
+  &__placeholder {
+    color: $placeholder-color;
+  }
+
+  &::after {
+    content: '';
+    position: absolute;
+    top: 50%;
+    right: 34px;
+    transform: translateY(-50%);
+    width: 44px;
+    height: 44px;
+    background: #eee;
+  }
+}