Compare commits

...

7 commits

11 changed files with 687 additions and 141 deletions

168
package-lock.json generated
View file

@ -8,6 +8,8 @@
"name": "router-ui-frontend",
"version": "0.0.0",
"dependencies": {
"axios": "^1.7.7",
"axios": "^1.7.7",
"path": "^0.12.7",
"vue": "^3.4.37",
"vue-router": "^4.4.3"
@ -16,7 +18,7 @@
"@types/node": "^22.5.1",
"@vitejs/plugin-vue": "^5.1.3",
"typescript": "^5.5.3",
"vite": "^5.4.1",
"vite": "^5.4.3",
"vite-svg-loader": "^5.1.0",
"vue-tsc": "^2.0.29"
}
@ -838,6 +840,36 @@
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.38.tgz",
"integrity": "sha512-q0xCiLkuWWQLzVrecPb0RMsNWyxICOjPrcrwxTUEHb1fsnvni4dcuyG7RT/Ie7VPTvnjzIaWzRMUBsrqNj/hhw=="
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/axios": {
"version": "1.7.7",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
"integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/axios": {
"version": "1.7.7",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
"integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@ -859,6 +891,28 @@
"balanced-match": "^1.0.0"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/commander": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
@ -959,6 +1013,22 @@
"integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==",
"dev": true
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
@ -1068,6 +1138,38 @@
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
},
"node_modules/follow-redirects": {
"version": "1.15.8",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.8.tgz",
"integrity": "sha512-xgrmBhBToVKay1q2Tao5LI26B83UhrB/vM1avwVSDzt8rx3rO6AizBAaF46EgksTVr+rFTQaqZZ9MVBfUe4nig==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@ -1110,6 +1212,44 @@
"integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
"dev": true
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
@ -1181,9 +1321,9 @@
"integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="
},
"node_modules/postcss": {
"version": "8.4.41",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz",
"integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==",
"version": "8.4.45",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.45.tgz",
"integrity": "sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==",
"funding": [
{
"type": "opencollective",
@ -1215,6 +1355,16 @@
"node": ">= 0.6.0"
}
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"node_modules/rollup": {
"version": "4.21.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.0.tgz",
@ -1331,14 +1481,14 @@
}
},
"node_modules/vite": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.1.tgz",
"integrity": "sha512-1oE6yuNXssjrZdblI9AfBbHCC41nnyoVoEZxQnID6yvQZAFBzxxkqoFLtHUMkYunL8hwOLEjgTuxpkRxvba3kA==",
"version": "5.4.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.3.tgz",
"integrity": "sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==",
"dev": true,
"dependencies": {
"esbuild": "^0.21.3",
"postcss": "^8.4.41",
"rollup": "^4.13.0"
"postcss": "^8.4.43",
"rollup": "^4.20.0"
},
"bin": {
"vite": "bin/vite.js"

View file

@ -9,6 +9,7 @@
"preview": "vite preview"
},
"dependencies": {
"axios": "^1.7.7",
"path": "^0.12.7",
"vue": "^3.4.37",
"vue-router": "^4.4.3"
@ -17,7 +18,7 @@
"@types/node": "^22.5.1",
"@vitejs/plugin-vue": "^5.1.3",
"typescript": "^5.5.3",
"vite": "^5.4.1",
"vite": "^5.4.3",
"vite-svg-loader": "^5.1.0",
"vue-tsc": "^2.0.29"
}

View file

@ -0,0 +1,40 @@
<script setup lang="ts">
import { useRoute } from 'vue-router';
import { watch, shallowRef } from 'vue';
const {excludedPages} = defineProps<{
excludedPages?: string[]
}>();
const route = useRoute();
let showActionFooter = shallowRef(true);
const checkExluded = (path: string) => {
if(excludedPages){
for(let i = 0; i < excludedPages.length; i++) {
if(excludedPages[i] === path) {
showActionFooter.value = false;
break;
} else {
showActionFooter.value = true;
}
}
}
}
checkExluded(route.path);
watch(() => route.path, (newPath) => {
checkExluded(newPath);
});
</script>
<template>
<footer id="footer" v-if="showActionFooter">
<h2>Save Changes?</h2>
<div>
<button class="apply">Apply</button>
<button>Cancel</button>
</div>
</footer>
</template>

0
src/components/Popup.vue Normal file
View file

View file

@ -1,5 +1,6 @@
<script setup lang="ts">
import Navbar from '@/components/Navbar.vue';
import ActionFooter from '@/components/ActionFooter.vue'
interface NavbarItem {
name: string;
@ -31,6 +32,7 @@
</div>
<div id="basicComponents">
<RouterView/>
<ActionFooter :excludedPages="['/basic']"/>
</div>
</div>
</template>

View file

@ -1,62 +1,113 @@
<script lang="ts" setup>
import { shallowRef } from 'vue'
const pageTitle="Internet Setup"
interface sectionsType {
title: string,
ID: string,
forms: {
name: string,
class: string,
option: string,
label: string
}[]
}
const sections = shallowRef<sectionsType[]>([]);
sections.value = [
{
title: "Does your internet require a login?",
ID: "internetSetupLogin",
forms: [
{
name: "internetLoginOption",
class: "selectOption",
option: "radio",
label: "Yes"
},
{
name: "internetLoginOption",
class: "selectOption",
option: "radio",
label: "No"
}
]
},
{
title: "Internet IP Address",
ID: "internetSetupIP",
forms: [
{
name: "internetIPOption",
class: "selectOption",
option: "radio",
label: "Dynamic IP from ISP"
},
{
name: "internetIPOption",
class: "selectOption",
option: "radio",
label: "Static IP from ISP"
}
]
},
{
title: "DNS (Domain Name Server) Address",
ID: "internetSetupDNS",
forms: [
{
name: "internetDNSOption",
class: "selectOption",
option: "radio",
label: "Automatic DNS from ISP"
},
{
name: "internetDNSOption",
class: "selectOption",
option: "radio",
label: "Select DNS Servers"
}
]
}, {
title: "Router MAC Address",
ID: "internetSetupMAC",
forms: [
{
name: "internetMACOption",
class: "selectOption",
option: "radio",
label: "Default Address"
},
{
name: "internetMACOption",
class: "selectOption",
option: "radio",
label: "Computer MAC Address"
},
{
name: "internetMACOption",
class: "selectOption",
option: "radio",
label: "Specific MAC Adress"
}
]
}
]
</script>
<template>
<div id="internetSetupComponent">
<h2 class="title">Internet Setup</h2>
<section id="internetSetupLogin">
<h3>Does your internet connection require a login?</h3>
<!-- There will be no input (keyboard) for the time being because that requires backend to handle. -->
<h2 class="title">{{ pageTitle }}</h2>
<section v-for="section in sections" :id="section.ID" :key="section.ID">
<h3>{{ section.title }}</h3>
<form>
<label>
<input type="radio" name="internetLoginOption" value="1">
<p>Yes</p>
</label>
<label>
<input type="radio" name="internetLoginOption" value="2">
<p>No</p>
</label>
</form>
</section>
<section id="internetSetupIP">
<h3>Internet IP Address</h3>
<form>
<label>
<input type="radio" name="internetIPOption" value="1">
<p>Dynamic IP from ISP</p>
</label>
<label>
<input type="radio" name="internetIPOption" value="2">
<p>Static IP from ISP</p>
</label>
</form>
</section>
<section>
<h3>DNS (Domain Name Server) Address</h3>
<form>
<label>
<input type="radio" name="internetDNSOption" value="1">
<p>Automatic DNS from ISP</p>
</label>
<label>
<input type="radio" name="internetDNSOption" value="2">
<p>Select DNS Servers</p>
</label>
</form>
</section>
<section>
<h3>Router MAC Address</h3>
<form>
<label>
<input type="radio" name="internetMACOption" value="1">
<p>Default Address</p>
</label>
<label>
<input type="radio" name="internetMACOption" value="2">
<p>Computer MAC Address</p>
</label>
<label>
<input type="radio" name="internetMACOption" value="2">
<p>Specific MAC Adress</p>
<label :class="form.class" v-for="(form, index) in section.forms">
<input :type="form.option" :name="form.name" :value="index + 1" :key="form.label">
{{ form.label }}
</label>
</form>
<div class="seperator"></div>
</section>
</div>
</template>

View file

@ -1,4 +1,7 @@
<script setup lang="ts">
import { shallowRef, onMounted } from 'vue';
import axios from 'axios';
import internetIcon from '@/assets/overviewSvgs/Internet.svg'
import wifiIcon from '@/assets/overviewSvgs/Wifi.svg'
import devicesIcon from '@/assets/overviewSvgs/Devices.svg'
@ -7,6 +10,7 @@
import guestNetworkIcon from '@/assets/overviewSvgs/GuestNetwork.svg'
interface statusColorsType {
[key: string]: string;
goodStatus: string;
warningStatus: string;
badStatus: string;
@ -26,56 +30,88 @@
statusMessage: string;
}
const overviewItems: overviewItemsType[] = [
const backendOnline = shallowRef<boolean>(true);
const overviewItems = shallowRef<overviewItemsType[]>([]);
const internetMode = shallowRef<string | null>(null);
const wifiMode5Ghz = shallowRef<string | null>(null);
const wifiMode2Ghz = shallowRef<number | null>(null);
const devices = shallowRef<string | null>(null);
const fileShare = shallowRef<string | null>(null);
const qos = shallowRef<string | null>(null);
const guestNetwork = shallowRef<string | null>(null);
const fetchOverviewItems = async () => {
try {
const response = await axios.get('http://localhost:8080/overviewItems');
internetMode.value = response.data.internetMode;
wifiMode5Ghz.value = response.data.wifiMode5Ghz;
wifiMode2Ghz.value = response.data.wifiMode2Ghz;
devices.value = response.data.devices;
fileShare.value = response.data.fileShare;
qos.value = response.data.qos;
guestNetwork.value = response.data.guestNetwork
overviewItems.value = [
{
name: "Internet",
link: "/basic/internet",
icon: internetIcon,
statusColor: statusColors.goodStatus,
statusMessage: "Online: LAN4",
statusMessage: `Online: ${internetMode.value}`,
},
{
name: "Wifi",
link: "/basic/wireless",
icon: wifiIcon,
statusColor: statusColors.warningStatus,
statusMessage: "5Ghz: On | 2.4Ghz: Off",
statusMessage: `5Ghz: ${wifiMode5Ghz.value} | 2.4Ghz: ${wifiMode2Ghz.value}`,
},
{
name: "Devices",
link: "/basic/devices",
icon: devicesIcon,
statusColor: null,
statusMessage: "Online: 0",
statusMessage: `Online: ${devices.value}`,
},
{
name: "File Sharing",
link: "/basic/fileshare",
icon: fileSharingIcon,
statusColor: statusColors.badStatus,
statusMessage: "Offline",
statusMessage: `${fileShare.value}`,
},
{
name: "QoS",
link: "/basic/qos",
icon: qosIcon,
statusColor: statusColors.goodStatus,
statusMessage: "Online",
statusMessage: `${qos.value}`,
},
{
name: "Guest Network",
link: "/basic/guestnetwork",
icon: guestNetworkIcon,
statusColor: statusColors.badStatus,
statusMessage: "Offline",
statusMessage: `${guestNetwork}`,
}
]
];
} catch (error) {
return backendOnline.value = false;
}
};
onMounted(() => {
fetchOverviewItems();
})
</script>
<template>
<div id="overviewComponent">
<h2 class="title">Overview</h2>
<ul>
<ul v-if="backendOnline">
<RouterLink :to="overviewItem.link" v-for="overviewItem in overviewItems">
<li>
<component :is="overviewItem.icon"/>
@ -84,6 +120,7 @@
</li>
</RouterLink>
</ul>
<p class="error" v-else>Backend offline or not available, please try again later.</p>
</div>
</template>

View file

@ -1,6 +1,169 @@
<template>
<div>
<div id="wirelessSettingsComponent">
<h2 class="title">Wireless Settings</h2>
<!-- Backend required to finish -->
<section>
<h3>General Setup</h3>
<form>
<label class="selectOption">
<input type="checkbox"/>
Enable AX (OFDMA Feature)
</label>
<label class="selectOption">
<input type="checkbox"/>
Enable OFDMA (2.4Ghz)
</label>
<label class="selectOption">
<input type="checkbox"/>
Enable OFDMA (5Ghz)
</label>
<label class="selectOption">
<input type="checkbox"/>
Enable automatic 2.4Ghz & 5Ghz switching
</label>
</form>
</section>
<div class="seperator"></div>
<section>
<h3>Wireless 2.4GHz</h3>
<form>
<label class="selectOption">
<input type="checkbox">
Enable SSID Broadcast
</label>
<label class="selectOption">
<input type="checkbox">
Enable 20/40 MHz Coexistence
</label>
<label class="inputName">
<input type="text" name="wirelessName" value="SomeRandomNetwork"/>
Name (SSID)
</label>
<label class="dropdownBox">
<select>
<option valie="Auto">Auto</option>
<option value="01">01</option>
<option value="02">02</option>
<option value="03">03</option>
<option value="04">04</option>
<option value="05">05</option>
<option value="06">06</option>
<option value="07">07</option>
<option value="08">08</option>
<option value="09">09</option>
<option value="10">10</option>
<option value="11">11</option>
</select>
Channel
</label>
<label class="dropdownBox">
<select>
<option value="54">54 Mbps</option>
<option value="289">289 Mbps</option>
<option value="600">600 Mbps</option>
</select>
Mode
</label>
<label class="subSelect">
<label class="selectOption">
<input type="radio" name="securityOption" value="1">
None
</label>
<label class="selectOption">
<input type="radio" name="securityOption" value="2">
WPA2-personal [AES]
</label>
<label class="selectOption">
<input type="radio" name="securityOption" value="3">
WPA-Personal [TKIP] + WPA2-Personal [AES]
</label>
<label class="selectOption">
<input type="radio" name="securityOption" value="4">
WPA3-Personal [SAE]
</label>
<label class="selectOption">
<input type="radio" name="securityOption" value="5">
WPA2-personal [AES] + WPA3-Personal
</label>
Security Options
</label>
<label class="inputName">
<input type="password" name="wirelessName" value="SomeRandomPassword"/>
Password (Network)
</label>
</form>
</section>
<div class="seperator"></div>
<section>
<h3>Wireless 5GHz</h3>
<form>
<label class="selectOption">
<input type="checkbox">
Enable SSID Broadcast
</label>
<label class="selectOption">
<input type="checkbox">
Enable 20/40 MHz Coexistence
</label>
<label class="inputName">
<input type="text" name="wirelessName" value="SomeRandomNetwork"/>
Name (SSID)
</label>
<label class="dropdownBox">
<select>
<option valie="Auto">Auto</option>
<option value="01">01</option>
<option value="02">02</option>
<option value="03">03</option>
<option value="04">04</option>
<option value="05">05</option>
<option value="06">06</option>
<option value="07">07</option>
<option value="08">08</option>
<option value="09">09</option>
<option value="10">10</option>
<option value="11">11</option>
</select>
Channel
</label>
<label class="dropdownBox">
<select>
<option value="54">54 Mbps</option>
<option value="289">289 Mbps</option>
<option value="600">600 Mbps</option>
</select>
Mode
</label>
<label class="subSelect">
<label class="selectOption">
<input type="radio" name="securityOption" value="1">
None
</label>
<label class="selectOption">
<input type="radio" name="securityOption" value="2">
WPA2-personal [AES]
</label>
<label class="selectOption">
<input type="radio" name="securityOption" value="3">
WPA-Personal [TKIP] + WPA2-Personal [AES]
</label>
<label class="selectOption">
<input type="radio" name="securityOption" value="4">
WPA3-Personal [SAE]
</label>
<label class="selectOption">
<input type="radio" name="securityOption" value="5">
WPA2-personal [AES] + WPA3-Personal
</label>
Security Options
</label>
<label class="inputName">
<input type="password" name="wirelessName" value="SomeRandomPassword"/>
Password (Network)
</label>
</form>
</section>
<div class="seperator"></div>
</div>
</template>

View file

@ -15,7 +15,7 @@ import BasicGuestNetwork from "../pages/basicDashboard/GuestNetwork.vue"
const routes = [
{
path: '/',
component: BasicDashboard,
redirect: '/basic'
},
{
path: '/advance',

View file

@ -1,3 +1,10 @@
.error {
text-align: center;
width: 100%;
margin-top: 30px;
font-size: 2rem;
}
#basicDashboard {
display: flex;
margin-top: 20px;
@ -102,56 +109,79 @@
}
}
#internetSetupComponent {
#internetSetupComponent, #wirelessSettingsComponent {
display: flex;
flex-direction: column;
gap: 20px;
align-items: center;
max-width: 70%;
margin: auto;
section {
margin-bottom: 10px;
display: flex;
flex-direction: column;
gap: 10px;
width: 400px;
width: 100%;
}
form {
display: flex;
flex-direction: column;
gap: 10px;
}
input[type="radio"] {
appearance: none;
-webkit-appearance: none;
width: 1.15em;
height:1.15em;
border: 0.15em solid #fff;
border-radius: 10%;
.seperator {
margin-top: 20px;
}
.selectOption {
display: flex;
align-items: center;
justify-content: center;
}
input[type="radio"]::before {
content: "";
background-color: var(--dark-bg-alt-2-color);
min-height: 50px;
width: 100%;
height: 100%;
border-radius: 10%;
transform: scale(0);
transition: 0.3s transform;
background-color: var(--dark-highlight-color);
border-radius: 5px;
padding: 10px;
font-size: 1.2rem;
user-select: none;
cursor: pointer;
}
input[type="radio"]:checked::before {
transform: scale(1);
}
label {
.inputName {
display: flex;
flex-direction: column-reverse;
input {
margin-top: 5px;
display: flex;
align-items: center;
background-color: var(--dark-bg-alt-2-color);
height: 50px;
min-height: 50px;
width: 100%;
border-radius: 5px;
padding: 10px;
p {
margin-left: 10px;
font-size: 1.2rem;
border: none;
color: #fff;
}
}
.dropdownBox {
display: flex;
flex-direction: column-reverse;
select {
margin-top: 5px;
display: flex;
align-items: center;
background-color: var(--dark-bg-alt-2-color);
min-height: 50px;
width: 100%;
border-radius: 5px;
padding: 10px;
font-size: 1.2rem;
border: none;
color: #fff;
}
}
.subSelect {
display: flex;
flex-direction: column-reverse;
gap: 5px;
}
}

View file

@ -33,6 +33,7 @@ body {
font-family: Noto-Sans, sans-serif;
min-height: 100vh;
padding: var(--padding);
overflow-x: hidden;
}
a {
@ -83,6 +84,40 @@ a {
}
}
#footer {
display: flex;
align-items: center;
justify-content: space-between;
background-color: var(--dark-bg-alt-2-color);
width: 70%;
margin: 20px auto;
padding: 15px;
border-radius: 5px;
div {
display: flex;
gap: 10px;
float: right;
}
button {
color: inherit;
background-color: var(--dark-bg-alt-2-color);
border: none;
height: 40px;
width: 70px;
border-radius: 5px;
cursor: pointer;
font-size: 1rem;
text-underline-offset: 2px;
}
button:hover {
text-decoration: underline;
}
.apply {
background-color: var(--dark-highlight-color);
}
}
.popup {
position: relative;
height: min-content;
@ -121,3 +156,40 @@ a {
.bad-indicator {
background-color: var(--bad-indicator) !important;
}
.seperator {
background-color: #4c4c4c;
height: 2px;
width: 100%;
}
input[type="radio"], input[type="checkbox"] {
appearance: none;
-webkit-appearance: none;
width: 15px;
height:15px;
border: 2px solid #fff;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 10px;
}
input[type="radio"]::before, input[type="checkbox"]::before {
content: "";
width: 100%;
height: 100%;
border-radius: 50%;
transform: scale(0);
transition: 0.3s transform;
background-color: var(--dark-highlight-color);
}
input[type="radio"]:checked::before, input[type="checkbox"]:checked::before {
transform: scale(1);
}
input[type="checkbox"], input[type="checkbox"]::before {
border-radius: 10%;
}