Files

134 lines
4.0 KiB
JavaScript
Raw Permalink Normal View History

async function api(path, body) {
const res = await fetch(path, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
const json = await res.json().catch(() => ({}));
if (!res.ok) {
throw new Error(json.detail || res.statusText);
}
return json;
}
async function gql(query, variables) {
const headers = { "Content-Type": "application/json" };
const token = localStorage.getItem("access_token");
if (token) {
headers.Authorization = `Bearer ${token}`;
}
const res = await fetch("/graphql", {
method: "POST",
headers,
body: JSON.stringify({ query, variables }),
});
const json = await res.json();
if (json.errors && json.errors.length) {
throw new Error(json.errors[0].message);
}
return json.data;
}
const CLIENTS_QUERY = `
query { clients { id clientId name isConfidential redirectUris createdAt } }
`;
document.addEventListener("DOMContentLoaded", () => {
const loginForm = document.getElementById("login-form");
const panel = document.getElementById("panel");
const statusEl = document.getElementById("status");
const clientsBody = document.getElementById("clients-body");
const createBtn = document.getElementById("create-client");
const logoutBtn = document.getElementById("logout");
function setStatus(message, ok = false) {
statusEl.textContent = message || "";
statusEl.classList.toggle("ok", ok);
}
function setLoggedIn(isLoggedIn) {
loginForm.classList.toggle("hidden", isLoggedIn);
panel.classList.toggle("hidden", !isLoggedIn);
}
function renderClients(clients) {
clientsBody.textContent = "";
for (const client of clients) {
const row = document.createElement("tr");
const cells = [
client.id,
client.clientId,
client.name,
client.isConfidential ? "yes" : "no",
(client.redirectUris || []).join(", "),
client.createdAt,
];
for (const value of cells) {
const td = document.createElement("td");
td.textContent = value;
row.appendChild(td);
}
clientsBody.appendChild(row);
}
}
async function loadClients() {
try {
const data = await gql(CLIENTS_QUERY);
renderClients(data.clients);
setStatus("");
} catch (err) {
renderClients([]);
setStatus(err.message);
}
}
async function handleLogin(event) {
event.preventDefault();
setStatus("");
const email = document.getElementById("email").value;
const password = document.getElementById("password").value;
try {
const { access_token } = await api("/auth/login", { email, password });
localStorage.setItem("access_token", access_token);
setLoggedIn(true);
await loadClients();
} catch (err) {
setStatus(err.message);
}
}
async function handleCreateClient() {
const name = prompt("Название клиента");
if (!name) {
return;
}
try {
await gql(
"mutation ($name: String!) { createClient(name: $name) { id clientId name } }",
{ name }
);
setStatus("");
await loadClients();
} catch (err) {
setStatus(err.message);
}
}
function handleLogout() {
localStorage.removeItem("access_token");
setLoggedIn(false);
setStatus("");
loginForm.reset();
}
loginForm.addEventListener("submit", handleLogin);
createBtn.addEventListener("click", handleCreateClient);
logoutBtn.addEventListener("click", handleLogout);
if (localStorage.getItem("access_token")) {
setLoggedIn(true);
loadClients();
}
});