A comprehensive mission module registration form example in the NOVA LAB system.
1<template>
2 <form @submit.prevent="submitModule" class="module-form" style="background: #0a0e27; color: #00ff88;">
3 <h2>Mission module registration</h2>
4
5 <!-- Basic information -->
6 <fieldset style="border-color: #00b4d8;">
7 <legend>Basic information</legend>
8
9 <div class="form-group">
10 <label for="name">Module name *</label>
11 <input
12 id="name"
13 v-model.trim="module.name"
14 required
15 minlength="3"
16 style="background: #1a1e37; color: #00ff88;"
17 />
18 </div>
19
20 <div class="form-group">
21 <label for="type">Type *</label>
22 <input id="type" v-model.trim="module.type" required style="background: #1a1e37; color: #00ff88;" />
23 </div>
24
25 <div class="form-row">
26 <div class="form-group">
27 <label for="year">Deployment year</label>
28 <input
29 id="year"
30 v-model.number="module.year"
31 type="number"
32 min="2020"
33 max="2100"
34 style="background: #1a1e37; color: #00ff88;"
35 />
36 </div>
37
38 <div class="form-group">
39 <label for="status">Status</label>
40 <select id="status" v-model="module.status" style="background: #1a1e37; color: #00ff88;">
41 <option value="">Select...</option>
42 <option value="ACTIVE">Active</option>
43 <option value="STANDBY">Standby</option>
44 <option value="MAINTENANCE">Maintenance</option>
45 <option value="OFFLINE">Offline</option>
46 </select>
47 </div>
48 </div>
49 </fieldset>
50
51 <!-- Parameters -->
52 <fieldset style="border-color: #00b4d8;">
53 <legend>Parameters</legend>
54 <div class="form-row">
55 <div class="form-group">
56 <label>Max power (MW)</label>
57 <input v-model.number="module.params.maxPower" type="number" style="background: #1a1e37; color: #00ff88;" />
58 </div>
59 <div class="form-group">
60 <label>Temperature (K)</label>
61 <input v-model.number="module.params.temperature" type="number" style="background: #1a1e37; color: #00ff88;" />
62 </div>
63 <div class="form-group" v-if="needsPressure">
64 <label>Pressure (kPa)</label>
65 <input v-model.number="module.params.pressure" type="number" style="background: #1a1e37; color: #00ff88;" />
66 </div>
67 </div>
68 </fieldset>
69
70 <!-- Categories -->
71 <fieldset>
72 <legend>Categories</legend>
73 <div class="checkbox-group">
74 <label v-for="cat in availableCategories" :key="cat.value">
75 <input
76 type="checkbox"
77 v-model="module.categories"
78 :value="cat.value"
79 />
80 {{ cat.label }}
81 </label>
82 </div>
83 </fieldset>
84
85 <!-- Description -->
86 <fieldset>
87 <legend>Description</legend>
88 <textarea
89 v-model="module.description"
90 rows="4"
91 placeholder="Describe the mission module..."
92 ></textarea>
93 <p class="char-count">
94 {{ module.description.length }} / 500 characters
95 </p>
96 </fieldset>
97
98 <!-- Options -->
99 <fieldset>
100 <legend>Options</legend>
101 <label class="checkbox-label">
102 <input type="checkbox" v-model="module.isActive" />
103 Module active
104 </label>
105 <label class="checkbox-label">
106 <input type="checkbox" v-model="module.needsMaintenance" />
107 Requires maintenance
108 </label>
109
110 <div v-if="module.needsMaintenance" class="form-group">
111 <label>Maintenance budget (USD)</label>
112 <input v-model.number="module.maintenanceCost" type="number" min="0" />
113 </div>
114 </fieldset>
115
116 <!-- Buttons -->
117 <div class="form-actions">
118 <button type="button" @click="resetForm">Clear</button>
119 <button type="submit" :disabled="!isValid">Register module</button>
120 </div>
121
122 <!-- Preview -->
123 <details>
124 <summary>Data preview</summary>
125 <pre>{{ JSON.stringify(module, null, 2) }}</pre>
126 </details>
127 </form>
128</template>
129
130<script setup>
131import { reactive, computed } from 'vue'
132
133const initialState = {
134 name: '',
135 type: '',
136 year: null,
137 status: '',
138 params: { maxPower: null, temperature: null, pressure: null },
139 categories: [],
140 description: '',
141 isActive: true,
142 needsMaintenance: false,
143 maintenanceCost: null
144}
145
146const module = reactive({ ...initialState })
147
148const availableCategories = [
149 { value: 'lifesupport', label: 'Life support' },
150 { value: 'energy', label: 'Energy' },
151 { value: 'research', label: 'Research' },
152 { value: 'communication', label: 'Communication' },
153 { value: 'navigation', label: 'Navigation' }
154]
155
156const needsPressure = computed(() => {
157 return ['lifesupport', 'research'].some(c => module.categories.includes(c))
158})
159
160const isValid = computed(() => {
161 return module.name.length >= 3 && module.type
162})
163
164function resetForm() {
165 Object.assign(module, {
166 ...initialState,
167 params: { ...initialState.params },
168 categories: []
169 })
170}
171
172function submitModule() {
173 if (isValid.value) {
174 console.log('Registering:', JSON.parse(JSON.stringify(module)))
175 alert('Module has been registered!')
176 }
177}
178</script>