We use cookies to enhance your experience on the site
CodeWorlds

Reactivity in Practice - Control Panel

Let's combine everything in practical NOVA LAB system examples.

Reactor Configuration Panel with Validation

1<template>
2  <form @submit.prevent="submitConfig" class="reactor-config" style="background: #0a0e27; color: #00ff88;">
3    <div>
4      <label>Module name:</label>
5      <input v-model="config.name" style="background: #1a1e37; color: #00ff88;" />
6      <span v-if="errors.name" style="color: #ff4444;">{{ errors.name }}</span>
7    </div>
8
9    <div>
10      <label>Maximum temperature (K):</label>
11      <input v-model.number="config.maxTemp" type="number" style="background: #1a1e37; color: #00ff88;" />
12      <span v-if="errors.maxTemp" style="color: #ff4444;">{{ errors.maxTemp }}</span>
13    </div>
14
15    <div>
16      <label>Status:</label>
17      <input v-model="config.status" style="background: #1a1e37; color: #00ff88;" />
18    </div>
19
20    <button :disabled="!isValid" style="background: #00b4d8; color: #0a0e27;">Save configuration</button>
21  </form>
22</template>
23
24<script setup>
25import { reactive, computed } from 'vue'
26
27const config = reactive({
28  name: '',
29  maxTemp: null,
30  status: ''
31})
32
33const errors = reactive({
34  name: '',
35  maxTemp: ''
36})
37
38const isValid = computed(() => {
39  // Name validation
40  if (config.name.length < 3) {
41    errors.name = 'Name must be at least 3 characters'
42  } else {
43    errors.name = ''
44  }
45
46  // Temperature validation
47  if (config.maxTemp && (config.maxTemp < 1000 || config.maxTemp > 10000)) {
48    errors.maxTemp = 'Temperature must be between 1000 and 10000 K'
49  } else {
50    errors.maxTemp = ''
51  }
52
53  return !errors.name && !errors.maxTemp
54})
55
56function submitConfig() {
57  if (isValid.value) {
58    console.log('Sending configuration to NOVA LAB:', config)
59  }
60}
61</script>

Module Monitoring System

1<template>
2  <div class="module-monitor" style="background: #0a0e27; color: #00ff88;">
3    <input v-model="searchQuery" placeholder="Search module..." style="background: #1a1e37; color: #00ff88;" />
4    <select v-model="filterStatus" style="background: #1a1e37; color: #00ff88;">
5      <option value="">All statuses</option>
6      <option value="ACTIVE">Active</option>
7      <option value="STANDBY">Standby</option>
8    </select>
9
10    <ul>
11      <li v-for="module in filteredModules" :key="module.id" style="border-bottom: 1px solid #00b4d8;">
12        {{ module.name }} - {{ module.status }}
13      </li>
14    </ul>
15
16    <p>Found: {{ filteredModules.length }} modules</p>
17  </div>
18</template>
19
20<script setup>
21import { ref, computed } from 'vue'
22
23const searchQuery = ref('')
24const filterStatus = ref('')
25
26const modules = ref([
27  { id: 1, name: 'Oxygen Generator Alpha', status: 'ACTIVE' },
28  { id: 2, name: 'Plasma Core Beta', status: 'STANDBY' },
29  { id: 3, name: 'Water Recycler Gamma', status: 'ACTIVE' },
30  { id: 4, name: 'Power Distributor Delta', status: 'STANDBY' }
31])
32
33const filteredModules = computed(() => {
34  return modules.value.filter(module => {
35    const matchesSearch = module.name
36      .toLowerCase()
37      .includes(searchQuery.value.toLowerCase())
38
39    const matchesStatus = !filterStatus.value ||
40      module.status === filterStatus.value
41
42    return matchesSearch && matchesStatus
43  })
44})
45</script>

Mission Supply System

1<template>
2  <div class="supply-cart" style="background: #0a0e27; color: #00ff88;">
3    <h2>Order ({{ supplies.itemCount }} items)</h2>
4
5    <div v-for="item in supplies.items" :key="item.id" style="border-bottom: 1px solid #00b4d8;">
6      {{ item.name }} - {{ item.quantity }} x {{ item.price }} CR
7      <button @click="removeItem(item.id)" style="background: #ff4444; color: #fff;">Remove</button>
8    </div>
9
10    <p><strong>Total: {{ supplies.total }} CR (Credits)</strong></p>
11  </div>
12</template>
13
14<script setup>
15import { reactive } from 'vue'
16
17const supplies = reactive({
18  items: [
19    { id: 1, name: 'Oxygen Canister', quantity: 10, price: 50 },
20    { id: 2, name: 'Plasma Cell', quantity: 5, price: 200 }
21  ],
22
23  // Computed as property
24  get itemCount() {
25    return this.items.reduce((sum, item) => sum + item.quantity, 0)
26  },
27
28  get total() {
29    return this.items.reduce((sum, item) =>
30      sum + item.quantity * item.price, 0)
31  }
32})
33
34function removeItem(id) {
35  const index = supplies.items.findIndex(item => item.id === id)
36  if (index > -1) {
37    supplies.items.splice(index, 1)
38  }
39}
40</script>
Go to CodeWorlds