diff --git a/native/LoginScreen.qml b/native/LoginScreen.qml index d3a509c..ab326ad 100644 --- a/native/LoginScreen.qml +++ b/native/LoginScreen.qml @@ -4,7 +4,7 @@ import QtQuick.Controls.Basic -Window { +Rectangle { SystemPalette { id: activeColors; colorGroup: SystemPalette.Active } SystemPalette { id: inactiveColors; colorGroup: SystemPalette.Inactive } @@ -14,9 +14,6 @@ Window { return root.active ? activeColors : inactiveColors; } - - width: 400 - height: 400 visible: true signal loginSuccess(string token) @@ -42,25 +39,29 @@ Window { id: nameT anchors{ - horizontalCenter: parent.horizontalCenter - topMargin: 5 - top: loginL.bottom + horizontalCenter: parent.horizontalCenter + topMargin: 5 + top: loginL.bottom } placeholderText: qsTr("Name") + Keys.onReturnPressed: passwordField.focus = true + } TextField { id: passwordT anchors{ - horizontalCenter: parent.horizontalCenter - topMargin: 5 - top: nameT.bottom + horizontalCenter: parent.horizontalCenter + topMargin: 5 + top: nameT.bottom } placeholderText: qsTr("Password") + Keys.onReturnPressed: login() + echoMode: TextInput.Password } @@ -74,25 +75,27 @@ Window { text: qsTr("Submit") - onClicked: { - var xhr = new XMLHttpRequest(); - xhr.open("POST", "https://api.clan-war.net/api/v1/auth/login"); - xhr.setRequestHeader("Content-Type", "application/json"); - xhr.onreadystatechange = function() { - if (xhr.readyState === XMLHttpRequest.DONE) { - if (xhr.status === 200) { - var token = xhr.responseText.trim(); // Trim to remove any leading/trailing whitespace - loginSuccess(token); - } else { - console.log("Login failed: " + xhr.status); - } + onClicked: login() + } + + function login() { + var xhr = new XMLHttpRequest(); + xhr.open("POST", "https://api.clan-war.net/api/v1/auth/login"); + xhr.setRequestHeader("Content-Type", "application/json"); + xhr.onreadystatechange = function() { + if (xhr.readyState === XMLHttpRequest.DONE) { + if (xhr.status === 200) { + var token = xhr.responseText.trim(); // Trim to remove any leading/trailing whitespace + loginSuccess(token); + } else { + console.log("Login failed: " + xhr.status); } } - var data = JSON.stringify({ - email: nameT.text, - password: passwordT.text - }); - xhr.send(data); } + var data = JSON.stringify({ + email: nameT.text, + password: passwordT.text + }); + xhr.send(data); } } diff --git a/native/Main.qml b/native/Main.qml index cff0dbb..cc4bd1d 100644 --- a/native/Main.qml +++ b/native/Main.qml @@ -18,7 +18,7 @@ Window { visible: true color: getColors().window - title: qsTr("Alisa - License Managment") + title: qsTr("Alisa - License Management") property string authToken: "" @@ -31,9 +31,9 @@ Window { Component { id: loginPageComponent LoginScreen { - onLoginSuccess: { - authToken = token - stackView.push(mainPageComponent) + onLoginSuccess: function(token) { + authToken = token; + stackView.push(mainPageComponent); } } } @@ -42,6 +42,9 @@ Window { id: mainPageComponent MainPage { authToken: authToken + onLogout: { + stackView.push(loginPageComponent) + } } } } diff --git a/native/MainPage.qml b/native/MainPage.qml index 1d6fba3..797ce35 100644 --- a/native/MainPage.qml +++ b/native/MainPage.qml @@ -14,6 +14,8 @@ Rectangle { property string authToken: "" + signal logout() + Rectangle { id: s1 anchors { @@ -21,7 +23,6 @@ Rectangle { left: parent.left right: parent.right } - radius: 0 height: 50 color: getColors().midlight @@ -29,26 +30,24 @@ Rectangle { anchors{ verticalCenter: s1.verticalCenter rightMargin: 5 - right: logginB.left + right: loginB.left } - placeholderText: qsTr("Seach") + placeholderText: qsTr("Search") } Button{ - id: logginB + id: loginB anchors{ verticalCenter: s1.verticalCenter rightMargin: 10 right: s1.right } - text: qsTr("Login") + text: qsTr("Logout") onClicked: { - var component = Qt.createComponent("LoginScreen.qml") - var window = component.createObject(root) - window.show() + logout(); } } } @@ -97,34 +96,17 @@ Rectangle { } } - - Button { - id: testB - anchors { - bottom: parent.bottom - left: parent.left - } - text: qsTr("Test Window") - - onClicked: { - var component = Qt.createComponent("Test.qml") - var window = component.createObject(root) - window.show() - } - } Button { id: loginScreenB anchors { - left: testB.right bottom: parent.bottom + left: parent.left } text: qsTr("Login Screen") onClicked: { - var component = Qt.createComponent("LoginScreen.qml") - var window = component.createObject(root) - window.show() + logout(); } } } diff --git a/web/src/components/HeaderBar.vue b/web/src/components/HeaderBar.vue index d24018c..25cbfdf 100644 --- a/web/src/components/HeaderBar.vue +++ b/web/src/components/HeaderBar.vue @@ -76,8 +76,31 @@ :rules="licenseNameRules" class="mb-3" > + + + +
-
+
-
+
@@ -161,7 +186,33 @@ import { store } from "@/store"; import { SubmitEventPromise } from "vuetify"; import { ref } from "vue"; -import { Plus, LogOut, FolderPlus } from "lucide-vue-next"; +import { Plus, LogOut, Pencil, FolderPlus } from "lucide-vue-next"; +import { useQuery } from "@tanstack/vue-query"; +import axios from "axios"; +import { LicenseGroup } from "@/types"; + +const { data } = useQuery({ + queryKey: ["licenses"], + queryFn: async () => { + const res = await axios.get( + import.meta.env.VITE_BACKEND_URL + "/licenses", + { + headers: { + Authorization: `Bearer ${store.token}`, + }, + } + ); + return res.data; + }, + select: (data) => { + return data.map((group) => { + return { + title: group.name, + value: group.id, + }; + }); + }, +}); function handlelogout() { store.setToken(null); @@ -169,8 +220,21 @@ function handlelogout() { async function submit(event: SubmitEventPromise) { const result = await event; - console.log(result); + if (result.valid) { + console.log({ + name: addLicenseName.value, + group_id: addLicenseGroup.value, + amount: addAmount.value, + key: addLicenseKey.value, + start: addStartDate.value, + stop: addStopDate.value, + notes: addNotes.value, + }); + } else { + console.log("Invalid"); + } } + // // GROUP SECTION // @@ -178,6 +242,7 @@ async function submit(event: SubmitEventPromise) { const group = ref(false); // Dialog for Group const groupLicenseName = ref(""); +// Rules for Group Dialog const licenseGroupRules = [ (value: string) => { if (value) return true; @@ -191,6 +256,10 @@ const licenseGroupRules = [ const add = ref(false); // References for Add License Dialog const addLicenseName = ref(""); +const addLicenseKey = ref(""); +const addLicenseGroup = ref(); + +// Rules for Add License Dialog const licenseNameRules = [ (value: string) => { if (value) return true; @@ -198,6 +267,22 @@ const licenseNameRules = [ return "YOU MUST ENTER (A LICENSE NAME)"; }, ]; +const selectGroupRules = [ + (value: string) => { + if (value) return true; + + return "YOU MUST SELECT (A LICENSE GROUP)"; + }, +]; + +const licenseKeyRules = [ + (value: string) => { + if (value) return true; + + return "YOU MUST ENTER (A LICENSE KEY)"; + }, +]; +// Optional Fields const addAmount = ref(); const addNotes = ref(""); diff --git a/web/src/components/MainPage.vue b/web/src/components/MainPage.vue index dce2feb..ac102b8 100644 --- a/web/src/components/MainPage.vue +++ b/web/src/components/MainPage.vue @@ -6,7 +6,10 @@
Error: {{ error?.message }}
  • - +
@@ -19,37 +22,27 @@ import CategoryContainer from "./CategoryContainer.vue"; import { useQuery } from "@tanstack/vue-query"; import axios from "axios"; import { store } from "@/store"; +import { LicenseGroup } from "@/types"; -interface LicenseGroup { - id: string, - name: string, - licenses: License[] -} - -interface License { - name: string; - id: string; - start?: Date, - end?: Date, - key: string, - amount?: number, -} - -const {isPending, isError, data, error} = useQuery({ +const { isPending, isError, data, error } = useQuery({ queryKey: ["licenses"], queryFn: async () => { - const res = await axios.get(import.meta.env.VITE_BACKEND_URL + "/licenses", { - headers: { - Authorization: `Bearer ${store.token}` + const res = await axios.get( + import.meta.env.VITE_BACKEND_URL + "/licenses", + { + headers: { + Authorization: `Bearer ${store.token}`, + }, } - }) - return res.data - } -}) + ); + return res.data; + }, +}); diff --git a/web/src/types.ts b/web/src/types.ts new file mode 100644 index 0000000..2454aaf --- /dev/null +++ b/web/src/types.ts @@ -0,0 +1,14 @@ +export interface LicenseGroup { + id: string; + name: string; + licenses: License[]; +} + +export interface License { + name: string; + id: string; + start?: Date; + end?: Date; + key: string; + amount?: number; +}