Heb er een PWA van gemaakt en layout gecorrigeerd

This commit is contained in:
LogJurgenR
2026-08-19 16:46:29 +02:00
parent d3cab99d86
commit 686339325e
21 changed files with 1629 additions and 103 deletions
+1
View File
@@ -0,0 +1 @@
export const SESSION_COOKIE = "adc_session";
+7
View File
@@ -0,0 +1,7 @@
// lib/config.ts
export const config = {
nodeEnv: process.env.NODE_ENV,
logLevel: process.env.LOG_LEVEL ?? "info",
destinationName: process.env.SAPB1_DESTINATION,
};
+117
View File
@@ -0,0 +1,117 @@
export const LOCALE_COOKIE = "adc_locale";
export const locales = ["nl", "en", "yue"] as const;
export type Locale = (typeof locales)[number];
type TranslationKey =
| "appName"
| "articles.title"
| "articles.description"
| "articles.count"
| "articles.heading"
| "articles.code"
| "articles.descriptionColumn"
| "articles.loading"
| "articles.emptyTitle"
| "articles.emptyDescription"
| "articles.error"
| "auth.logout"
| "login.title"
| "login.description"
| "login.demoCredentials"
| "login.username"
| "login.password"
| "login.submit"
| "login.submitting"
| "login.invalidCredentials"
| "login.unexpectedError"
| "language.label";
const translations: Record<Locale, Record<TranslationKey, string>> = {
nl: {
appName: "ADC BestelApp",
"articles.title": "SAP Business One Artikelen",
"articles.description": "Overzicht van artikelen opgehaald via de SAP Business One Service Layer.",
"articles.count": "Aantal artikelen",
"articles.heading": "Artikelen",
"articles.code": "Artikelcode",
"articles.descriptionColumn": "Omschrijving",
"articles.loading": "Artikelen laden...",
"articles.emptyTitle": "Geen artikelen gevonden",
"articles.emptyDescription": "De Service Layer heeft geen artikelen teruggegeven.",
"articles.error": "Er is een fout opgetreden bij het ophalen van de artikelen.",
"auth.logout": "Uitloggen",
"login.title": "Inloggen",
"login.description": "Log in om de artikelen te bekijken.",
"login.demoCredentials": "Gebruikersnaam: admin, wachtwoord: admin",
"login.username": "Gebruikersnaam",
"login.password": "Wachtwoord",
"login.submit": "Inloggen",
"login.submitting": "Bezig met inloggen...",
"login.invalidCredentials": "Ongeldige gebruikersnaam of wachtwoord.",
"login.unexpectedError": "Er is een fout opgetreden. Probeer het opnieuw.",
"language.label": "Taal",
},
en: {
appName: "ADC Order App",
"articles.title": "SAP Business One Items",
"articles.description": "Overview of items retrieved through the SAP Business One Service Layer.",
"articles.count": "Number of items",
"articles.heading": "Items",
"articles.code": "Item code",
"articles.descriptionColumn": "Description",
"articles.loading": "Loading items...",
"articles.emptyTitle": "No items found",
"articles.emptyDescription": "The Service Layer returned no items.",
"articles.error": "An error occurred while retrieving the items.",
"auth.logout": "Log out",
"login.title": "Sign in",
"login.description": "Sign in to view the items.",
"login.demoCredentials": "Username: admin, password: admin",
"login.username": "Username",
"login.password": "Password",
"login.submit": "Sign in",
"login.submitting": "Signing in...",
"login.invalidCredentials": "Invalid username or password.",
"login.unexpectedError": "An error occurred. Please try again.",
"language.label": "Language",
},
yue: {
appName: "ADC 訂貨應用程式",
"articles.title": "SAP Business One 貨品",
"articles.description": "透過 SAP Business One Service Layer 取得嘅貨品一覽。",
"articles.count": "貨品數量",
"articles.heading": "貨品",
"articles.code": "貨品編號",
"articles.descriptionColumn": "描述",
"articles.loading": "載入貨品中...",
"articles.emptyTitle": "搵唔到貨品",
"articles.emptyDescription": "Service Layer 冇返回任何貨品。",
"articles.error": "取得貨品時發生錯誤。",
"auth.logout": "登出",
"login.title": "登入",
"login.description": "登入後查看貨品。",
"login.demoCredentials": "使用者名稱:admin,密碼:admin",
"login.username": "使用者名稱",
"login.password": "密碼",
"login.submit": "登入",
"login.submitting": "登入中...",
"login.invalidCredentials": "使用者名稱或密碼錯誤。",
"login.unexpectedError": "發生錯誤,請再試一次。",
"language.label": "語言",
},
};
export function getLocale(value?: string): Locale {
return locales.includes(value as Locale) ? (value as Locale) : "nl";
}
export function t(locale: Locale, key: TranslationKey): string {
return translations[locale][key];
}
export function getLanguageName(locale: Locale): string {
return { nl: "Nederlands", en: "English", yue: "廣東話" }[locale];
}
export type { TranslationKey };
+24
View File
@@ -0,0 +1,24 @@
import { executeHttpRequest } from "@sap-cloud-sdk/http-client";
type Item = {
ItemCode: string;
ItemName: string;
};
export async function getItems(): Promise<{ items: Item[]; error: string }> {
try {
const response = await executeHttpRequest(
{ destinationName: "SAP4SL" },
{ method: "GET", url: "/b1s/v2/Items" },
);
return { items: response.data.value || [], error: "" };
} catch (error) {
console.error(error);
return {
items: [],
error: "items_request_failed",
};
}
}
+5
View File
@@ -0,0 +1,5 @@
import pino from "pino";
export const logger = pino({
level: process.env.LOG_LEVEL || "info",
});
+57
View File
@@ -0,0 +1,57 @@
import axios, { AxiosResponse } from "axios";
export async function login(): Promise<string> {
try {
console.log("Login naar:", `https://servicelayer.logres.nl:50000/b1s/v2/Login`);
const response = await axios.post(
"https://servicelayer.logres.nl:50000/b1s/v2/Login",
{
CompanyDB: "DEMONLJR",
UserName: "manager",
Password: "manager",
},
{
timeout: 10000,
headers: {
"Content-Type": "application/json",
},
validateStatus: () => true,
}
);
console.log("STATUS:", response.status);
console.log("DATA:", response.data);
console.log("COOKIES:", response.headers["set-cookie"]);
const setCookie = extractCookie(response);
if (!setCookie) {
throw new Error("Geen set-cookie header ontvangen van SAP Business One");
}
return Array.isArray(setCookie) ? setCookie.join("; ") : setCookie;
} catch (error: unknown) {
console.error("MESSAGE:", (error as Error).message);
console.error("CODE:", (error as { code: string }).code);
if ((error as { response: unknown }).response) {
console.error("STATUS:", (error as { response: { status: number } }).response.status);
console.error("DATA:", (error as { response: { data: unknown } }).response.data);
}
throw new Error((error as Error).message || "Login failed");
}
}
function extractCookie(response: AxiosResponse): string | null {
const setCookie = response.headers['set-cookie'];
if (!setCookie) {
return null;
}
return setCookie
.map((cookie: string) => cookie.split(";")[0])
.join("; ");
}