2024-07-11 10:49:13 +02:00
|
|
|
import QtQuick 2.15
|
|
|
|
import QtQuick.Controls 2.15
|
2024-07-12 00:10:46 +02:00
|
|
|
import QtQuick.Layouts 2.15
|
2024-07-11 10:49:13 +02:00
|
|
|
|
|
|
|
Rectangle {
|
2024-07-12 00:10:46 +02:00
|
|
|
id: root
|
2024-07-11 21:54:27 +02:00
|
|
|
|
2024-07-11 10:49:13 +02:00
|
|
|
SystemPalette { id: activeColors; colorGroup: SystemPalette.Active }
|
|
|
|
SystemPalette { id: inactiveColors; colorGroup: SystemPalette.Inactive }
|
|
|
|
SystemPalette { id: disabledColors; colorGroup: SystemPalette.Disabled }
|
|
|
|
|
|
|
|
function getColors() {
|
2024-07-12 00:10:46 +02:00
|
|
|
return active ? activeColors : inactiveColors;
|
2024-07-11 10:49:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
property string authToken: ""
|
2024-07-11 22:06:53 +02:00
|
|
|
property string searchText: "" // Property to hold the search text
|
2024-07-11 10:49:13 +02:00
|
|
|
|
2024-07-11 11:25:08 +02:00
|
|
|
signal logout()
|
|
|
|
|
2024-07-11 10:49:13 +02:00
|
|
|
Rectangle {
|
|
|
|
id: s1
|
|
|
|
anchors {
|
|
|
|
top: parent.top
|
|
|
|
left: parent.left
|
|
|
|
right: parent.right
|
|
|
|
}
|
|
|
|
height: 50
|
|
|
|
color: getColors().midlight
|
|
|
|
|
2024-07-11 21:54:27 +02:00
|
|
|
RowLayout {
|
|
|
|
anchors.fill: parent
|
|
|
|
spacing: 10
|
|
|
|
anchors.margins: 5
|
2024-07-11 10:49:13 +02:00
|
|
|
|
2024-07-11 21:54:27 +02:00
|
|
|
TextField {
|
2024-07-11 22:06:53 +02:00
|
|
|
id: searchField
|
2024-07-11 21:54:27 +02:00
|
|
|
placeholderText: qsTr("Search")
|
|
|
|
Layout.alignment: Qt.AlignVCenter
|
|
|
|
Layout.fillWidth: true
|
2024-07-11 22:06:53 +02:00
|
|
|
onTextChanged: {
|
|
|
|
searchText = text
|
|
|
|
filterModel() // Filter model based on search text
|
|
|
|
}
|
2024-07-11 10:49:13 +02:00
|
|
|
}
|
|
|
|
|
2024-07-11 21:54:27 +02:00
|
|
|
Button {
|
|
|
|
text: qsTr("Add License")
|
|
|
|
Layout.alignment: Qt.AlignVCenter
|
|
|
|
onClicked: {
|
|
|
|
// Create and show a new window
|
2024-07-11 23:19:24 +02:00
|
|
|
var newWindow = addLicenseWindow.createObject(null, { authToken: authToken });
|
|
|
|
if (newWindow !== null) {
|
|
|
|
newWindow.show();
|
|
|
|
} else {
|
|
|
|
console.log("Failed to create new window");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Button {
|
|
|
|
text: qsTr("Add License Group")
|
|
|
|
Layout.alignment: Qt.AlignVCenter
|
|
|
|
onClicked: {
|
|
|
|
// Create and show a new window
|
|
|
|
var newWindow = addLicenseGroupWindow.createObject(null, { authToken: authToken });
|
2024-07-11 21:54:27 +02:00
|
|
|
if (newWindow !== null) {
|
|
|
|
newWindow.show();
|
|
|
|
} else {
|
|
|
|
console.log("Failed to create new window");
|
|
|
|
}
|
|
|
|
}
|
2024-07-11 10:49:13 +02:00
|
|
|
}
|
2024-07-11 18:34:40 +02:00
|
|
|
|
2024-07-12 11:15:01 +02:00
|
|
|
Button {
|
|
|
|
text: qsTr("Dellete Group")
|
|
|
|
Layout.alignment: Qt.AlignVCenter
|
|
|
|
onClicked: {
|
|
|
|
//
|
|
|
|
var newWindow = addDellgrup.createObject(null, { authToken: authToken });
|
|
|
|
if (newWindow !== null) {
|
|
|
|
newWindow.show();
|
|
|
|
} else {
|
|
|
|
console.log("Failed to create new window");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-11 21:54:27 +02:00
|
|
|
Button {
|
|
|
|
id: loginB
|
|
|
|
text: qsTr("Logout")
|
|
|
|
Layout.alignment: Qt.AlignVCenter
|
|
|
|
onClicked: {
|
|
|
|
logout();
|
2024-07-11 18:34:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-07-11 10:49:13 +02:00
|
|
|
}
|
|
|
|
|
2024-07-11 18:34:40 +02:00
|
|
|
Rectangle {
|
2024-07-11 10:49:13 +02:00
|
|
|
id: s2
|
|
|
|
anchors {
|
|
|
|
top: s1.bottom
|
|
|
|
left: parent.left
|
|
|
|
right: parent.right
|
|
|
|
bottom: parent.bottom
|
|
|
|
}
|
|
|
|
color: getColors().window
|
|
|
|
|
2024-07-11 22:02:36 +02:00
|
|
|
ColumnLayout {
|
2024-07-11 21:54:27 +02:00
|
|
|
anchors.fill: parent
|
2024-07-11 22:02:36 +02:00
|
|
|
spacing: 0
|
2024-07-11 16:01:37 +02:00
|
|
|
|
2024-07-11 22:02:36 +02:00
|
|
|
Rectangle {
|
2024-07-12 00:10:46 +02:00
|
|
|
height: 50
|
2024-07-12 01:06:31 +02:00
|
|
|
id: rect1
|
2024-07-12 00:10:46 +02:00
|
|
|
width: parent.width
|
2024-07-11 22:02:36 +02:00
|
|
|
color: getColors().midlight
|
2024-07-11 16:01:37 +02:00
|
|
|
|
2024-07-11 21:54:27 +02:00
|
|
|
RowLayout {
|
|
|
|
anchors.fill: parent
|
2024-07-11 16:01:37 +02:00
|
|
|
spacing: 10
|
2024-07-11 22:02:36 +02:00
|
|
|
anchors.margins: 5
|
|
|
|
|
2024-07-12 00:10:46 +02:00
|
|
|
Text { text: qsTr("Name"); color: getColors().text; Layout.preferredWidth: 150; font.bold: true }
|
|
|
|
Text { text: qsTr("Key"); color: getColors().text; Layout.preferredWidth: 150; font.bold: true }
|
|
|
|
Text { text: qsTr("Amount"); color: getColors().text; Layout.preferredWidth: 100; font.bold: true }
|
|
|
|
Text { text: qsTr("Start"); color: getColors().text; Layout.preferredWidth: 100; font.bold: true }
|
|
|
|
Text { text: qsTr("End"); color: getColors().text; Layout.preferredWidth: 100; font.bold: true }
|
|
|
|
Text { text: qsTr("Group"); color: getColors().text; Layout.preferredWidth: 150; font.bold: true }
|
2024-07-12 10:18:06 +02:00
|
|
|
Text { text: qsTr("Actions"); color: getColors().text; Layout.preferredWidth: 100; font.bold: true }
|
2024-07-11 22:02:36 +02:00
|
|
|
}
|
|
|
|
}
|
2024-07-11 16:01:37 +02:00
|
|
|
|
2024-07-12 01:06:31 +02:00
|
|
|
ScrollView {
|
2024-07-11 22:02:36 +02:00
|
|
|
Layout.fillWidth: true
|
|
|
|
Layout.fillHeight: true
|
2024-07-12 01:06:31 +02:00
|
|
|
|
|
|
|
ListView {
|
|
|
|
id: listView
|
|
|
|
Layout.fillWidth: true
|
|
|
|
Layout.fillHeight: true
|
|
|
|
model: filteredApiDataModel // Use the filtered model
|
|
|
|
|
|
|
|
delegate: Rectangle {
|
|
|
|
width: listView.width
|
|
|
|
height: 50
|
|
|
|
color: (index % 2 === 0) ? getColors().button : getColors().highlight // Alternating row colors
|
|
|
|
|
|
|
|
RowLayout {
|
|
|
|
anchors.fill: parent
|
|
|
|
spacing: 10
|
|
|
|
anchors.margins: 5
|
|
|
|
|
|
|
|
Text { text: model.name; color: getColors().text; Layout.preferredWidth: 150; elide: Text.ElideRight }
|
|
|
|
Text { text: model.key; color: getColors().text; Layout.preferredWidth: 150; elide: Text.ElideRight }
|
|
|
|
Text { text: model.amount; color: getColors().text; Layout.preferredWidth: 100; elide: Text.ElideRight }
|
|
|
|
Text { text: model.start; color: getColors().text; Layout.preferredWidth: 100; elide: Text.ElideRight }
|
|
|
|
Text { text: model.end; color: getColors().text; Layout.preferredWidth: 100; elide: Text.ElideRight }
|
|
|
|
Text { text: model.group; color: getColors().text; Layout.preferredWidth: 150; elide: Text.ElideRight }
|
2024-07-12 10:18:06 +02:00
|
|
|
|
|
|
|
Button {
|
|
|
|
text: qsTr("Delete")
|
|
|
|
Layout.preferredWidth: 100
|
|
|
|
onClicked: {
|
2024-07-12 11:04:10 +02:00
|
|
|
deleteLicense(model.id)
|
2024-07-12 10:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
2024-07-12 01:06:31 +02:00
|
|
|
}
|
2024-07-11 16:01:37 +02:00
|
|
|
}
|
2024-07-11 10:49:13 +02:00
|
|
|
}
|
2024-07-11 16:01:37 +02:00
|
|
|
}
|
2024-07-11 22:02:36 +02:00
|
|
|
|
|
|
|
ListModel {
|
|
|
|
id: apiDataModel
|
|
|
|
}
|
2024-07-11 22:06:53 +02:00
|
|
|
|
|
|
|
ListModel {
|
|
|
|
id: filteredApiDataModel
|
|
|
|
}
|
2024-07-11 16:01:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-11 18:34:40 +02:00
|
|
|
Component {
|
2024-07-11 23:19:24 +02:00
|
|
|
id: addLicenseWindow
|
2024-07-11 18:34:40 +02:00
|
|
|
AddData {
|
|
|
|
id: dataWindow
|
|
|
|
authToken: authToken
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-11 23:19:24 +02:00
|
|
|
Component {
|
|
|
|
id: addLicenseGroupWindow
|
|
|
|
AddGroup {
|
|
|
|
id: dataWindow
|
|
|
|
authToken: authToken
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-11 16:01:37 +02:00
|
|
|
Component.onCompleted: {
|
2024-07-12 10:18:06 +02:00
|
|
|
loadLicenses()
|
|
|
|
}
|
|
|
|
|
|
|
|
function loadLicenses() {
|
2024-07-11 16:01:37 +02:00
|
|
|
var xhr = new XMLHttpRequest();
|
|
|
|
xhr.open("GET", "https://api.clan-war.net/api/v1/licenses");
|
|
|
|
xhr.setRequestHeader("Authorization", "Bearer " + authToken);
|
|
|
|
xhr.onreadystatechange = function() {
|
|
|
|
if (xhr.readyState === XMLHttpRequest.DONE) {
|
|
|
|
if (xhr.status === 200) {
|
|
|
|
var jsonResponse = JSON.parse(xhr.responseText);
|
|
|
|
|
|
|
|
apiDataModel.clear();
|
|
|
|
for (var i = 0; i < jsonResponse.length; i++) {
|
|
|
|
for (var ii = 0; ii < jsonResponse[i].licenses.length; ii++) {
|
|
|
|
apiDataModel.append({
|
|
|
|
group: jsonResponse[i].name,
|
|
|
|
name: jsonResponse[i].licenses[ii].name,
|
|
|
|
start: jsonResponse[i].licenses[ii].start ?? "Indefinitely",
|
|
|
|
end: jsonResponse[i].licenses[ii].end ?? "Indefinitely",
|
2024-07-11 22:19:10 +02:00
|
|
|
amount: jsonResponse[i].licenses[ii].amount ? jsonResponse[i].licenses[ii].amount.toString() : "∞",
|
2024-07-12 11:04:10 +02:00
|
|
|
key: jsonResponse[i].licenses[ii].key,
|
|
|
|
id: jsonResponse[i].licenses[ii].id
|
2024-07-11 16:01:37 +02:00
|
|
|
});
|
|
|
|
}
|
2024-07-11 10:49:13 +02:00
|
|
|
}
|
2024-07-11 22:06:53 +02:00
|
|
|
filterModel() // Filter the model after loading data
|
2024-07-11 16:01:37 +02:00
|
|
|
} else {
|
|
|
|
console.log("Error: " + xhr.status);
|
2024-07-11 10:49:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-07-11 16:01:37 +02:00
|
|
|
xhr.send();
|
2024-07-11 10:49:13 +02:00
|
|
|
}
|
2024-07-11 22:06:53 +02:00
|
|
|
|
|
|
|
function filterModel() {
|
|
|
|
filteredApiDataModel.clear()
|
|
|
|
for (var i = 0; i < apiDataModel.count; ++i) {
|
|
|
|
var item = apiDataModel.get(i)
|
2024-07-11 22:15:50 +02:00
|
|
|
var name = item.name ? item.name.toString().toLowerCase() : ""
|
|
|
|
var key = item.key ? item.key.toString().toLowerCase() : ""
|
|
|
|
var amount = item.amount ? item.amount.toString().toLowerCase() : ""
|
|
|
|
var start = item.start ? item.start.toString().toLowerCase() : ""
|
|
|
|
var end = item.end ? item.end.toString().toLowerCase() : ""
|
|
|
|
var group = item.group ? item.group.toString().toLowerCase() : ""
|
|
|
|
|
|
|
|
if (name.indexOf(searchText.toLowerCase()) !== -1 ||
|
|
|
|
key.indexOf(searchText.toLowerCase()) !== -1 ||
|
|
|
|
amount.indexOf(searchText.toLowerCase()) !== -1 ||
|
|
|
|
start.indexOf(searchText.toLowerCase()) !== -1 ||
|
|
|
|
end.indexOf(searchText.toLowerCase()) !== -1 ||
|
|
|
|
group.indexOf(searchText.toLowerCase()) !== -1) {
|
2024-07-11 22:06:53 +02:00
|
|
|
filteredApiDataModel.append(item)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-07-12 10:18:06 +02:00
|
|
|
|
2024-07-12 11:04:10 +02:00
|
|
|
function deleteLicense(id) {
|
2024-07-12 10:18:06 +02:00
|
|
|
var xhr = new XMLHttpRequest();
|
2024-07-12 11:04:10 +02:00
|
|
|
xhr.open("DELETE", "https://api.clan-war.net/api/v1/licenses/" + id);
|
2024-07-12 10:18:06 +02:00
|
|
|
xhr.setRequestHeader("Authorization", "Bearer " + authToken);
|
|
|
|
xhr.onreadystatechange = function() {
|
|
|
|
if (xhr.readyState === XMLHttpRequest.DONE) {
|
|
|
|
if (xhr.status === 200) {
|
|
|
|
console.log("License deleted successfully");
|
|
|
|
loadLicenses(); // Reload licenses after deletion
|
|
|
|
} else {
|
|
|
|
console.log("Error deleting license: " + xhr.status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
xhr.send();
|
|
|
|
}
|
2024-07-11 10:49:13 +02:00
|
|
|
}
|