Vue

by Mladen Mihajlovic

HTML

<div id="app">
  <h1>
    Original
  </h1>
  <div class="row" v-for="(payment, index) in paymentsToShow" :key="`a_${index}`">
    <template v-if="payment.amount >= 0">

      <template v-if="index === paymentsToShow.length - 1">
        <label>
          <strong v-if="index < payments.length - 1">
            Starting {{ format(payment.fulfill_at) }},
            pay
          </strong>
          <strong v-else>
            <!-- index is payments last line -->
            {{ format(payment.fulfill_at) }}, pay
          </strong>
        </label>
        <strong v-if="index < payments.length - 1">
          ${{ payment.amount }}/mo
        </strong>
        <strong v-else>${{ payment.amount}}</strong>
      </template>
      <template v-else>
        <!-- index is payments last line -->
        <span>On {{ format(payment.fulfill_at) }}, pay</span>
        <span> ${{ payment.amount}}</span>
      </template>

    </template>
    <template v-else>
      <!-- amount >= 0 -->
      <span class="color-ui-red">
        On {{ format(payment.fulfill_at) }}, refund
      </span>
      <span class="color-ui-red">
        ${{ payment.amount}}
      </span>
    </template>

  </div>

  <h1>New</h1>

  <template v-for="(row, idx) in mvvm">

    <div class="row" v-if="row.isLast" :key="idx">
      <label>
        <strong>{{ row.whenStr }}</strong>
      </label>
      <strong>{{ row.amtStr }}</strong>
    </div>
    
    <div class="row" v-else :key="idx">
      <span :class="row.redClass">{{ row.whenStr }}</span>
      <span :class="row.redClass">{{ row.amtStr }}</span>
    </div>
  </template>

</div>

CSS

.color-ui-red {
  color: red;
}

Vue

new Vue({
  el: "#app",
  data: {
    payments: [
    	{ amount: 10.95, fulfill_at: new Date('2018-1-1') },
      { amount: 20.95, fulfill_at: new Date('2018-2-1') },
      { amount: 0, fulfill_at: new Date('2018-3-1') },
      { amount: -40.95, fulfill_at: new Date('2018-4-1') },
      { amount: 10.95, fulfill_at: new Date('2019-1-1') },
      { amount: 20.95, fulfill_at: new Date('2019-2-1') },
      { amount: 0, fulfill_at: new Date('2019-3-1') },
      { amount: -40.95, fulfill_at: new Date('2019-4-1') },
      { amount: 50.95, fulfill_at: new Date('2019-5-1') },
      { amount: 50.95, fulfill_at: new Date('2020-1-1') },
      { amount: 40.95, fulfill_at: new Date('2020-2-1') },
    ]
  },
  computed: {
  	paymentsToShow() {
    	return this.payments
      	.filter(p => 1900 + p.fulfill_at.getYear() === 2019 );
    },
    mvvm() {
    	return this.paymentsToShow
      	.map((p, i) => {

        	const isLast = Boolean(i === this.paymentsToShow.length - 1);
          const isFinal = Boolean(i === this.payments.length - 1);
        	const starting = isFinal ? "Starting" : "On";
          const perMo = isFinal ? "/mo" : "";
          const refundPay = p.amount < 0 ? "refund" : "pay";
          
          return {
          	isLast,
            redClass: p.amount < 0 ? "color-ui-red" : "",
            amtStr: `${refundPay} $${p.amount}${perMo}`,
            whenStr: `${isFinal ? "Starting" : "On"}, ${this.format(p.fulfill_at)}`
          };
        })
    }
  },
  methods: {
  	format(d) {
    	return d.toLocaleDateString()
    }
  }
})