workin on document creation: frontend work
This commit is contained in:
@@ -10,6 +10,7 @@ public class Constants {
|
|||||||
private Constants(){}
|
private Constants(){}
|
||||||
|
|
||||||
public static final Pattern POST_CODE = compile("(.*\\w+.*)\n(.*\\d+.*)\n(\\d{5}) (\\w+)",DOTALL);
|
public static final Pattern POST_CODE = compile("(.*\\w+.*)\n(.*\\d+.*)\n(\\d{5}) (\\w+)",DOTALL);
|
||||||
|
public static final String CONTACTS = "contacts";
|
||||||
|
|
||||||
public static final String CUSTOMER_NUMBER_PREFIX = "customer_number_prefix";
|
public static final String CUSTOMER_NUMBER_PREFIX = "customer_number_prefix";
|
||||||
public static final String DECIMAL_SEPARATOR = "decimal_separator";
|
public static final String DECIMAL_SEPARATOR = "decimal_separator";
|
||||||
@@ -77,7 +78,6 @@ public class Constants {
|
|||||||
public static final String PATH_ADD_TIME = "add_time";
|
public static final String PATH_ADD_TIME = "add_time";
|
||||||
public static final String PATH_COMPANIES = "companies";
|
public static final String PATH_COMPANIES = "companies";
|
||||||
public static final String PATH_COMPANY = "company";
|
public static final String PATH_COMPANY = "company";
|
||||||
public static final String PATH_CONTACTS = "contacts";
|
|
||||||
public static final String PATH_DOCUMENT = "document";
|
public static final String PATH_DOCUMENT = "document";
|
||||||
public static final String PATH_PDF = "pdf";
|
public static final String PATH_PDF = "pdf";
|
||||||
public static final String PATH_POSITIONS = "positions";
|
public static final String PATH_POSITIONS = "positions";
|
||||||
@@ -94,4 +94,5 @@ public class Constants {
|
|||||||
|
|
||||||
public static final String COMPANIES = "companies";
|
public static final String COMPANIES = "companies";
|
||||||
public static final String COMPANY = "company";
|
public static final String COMPANY = "company";
|
||||||
|
public static final String CUSTOMERS = "customers";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,7 @@ import static de.srsoftware.tools.MimeType.MIME_FORM_URL;
|
|||||||
import static de.srsoftware.umbrella.core.Constants.ERROR_MISSING_FIELD;
|
import static de.srsoftware.umbrella.core.Constants.ERROR_MISSING_FIELD;
|
||||||
import static de.srsoftware.umbrella.core.Paths.LIST;
|
import static de.srsoftware.umbrella.core.Paths.LIST;
|
||||||
import static de.srsoftware.umbrella.core.Util.request;
|
import static de.srsoftware.umbrella.core.Util.request;
|
||||||
import static de.srsoftware.umbrella.documents.Constants.COMPANIES;
|
import static de.srsoftware.umbrella.documents.Constants.*;
|
||||||
import static de.srsoftware.umbrella.documents.Constants.COMPANY;
|
|
||||||
import static java.lang.System.Logger.Level.WARNING;
|
import static java.lang.System.Logger.Level.WARNING;
|
||||||
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
|
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
|
||||||
|
|
||||||
@@ -23,6 +22,10 @@ import java.io.IOException;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import de.srsoftware.umbrella.documents.model.Type;
|
||||||
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
public class DocumentApi extends BaseHandler {
|
public class DocumentApi extends BaseHandler {
|
||||||
@@ -47,6 +50,8 @@ public class DocumentApi extends BaseHandler {
|
|||||||
var head = path.pop();
|
var head = path.pop();
|
||||||
return switch (head){
|
return switch (head){
|
||||||
case COMPANIES -> getCompanies(ex,user.get(),token.orElse(null));
|
case COMPANIES -> getCompanies(ex,user.get(),token.orElse(null));
|
||||||
|
case CONTACTS -> getContacts(ex,user.get(),token.orElse(null));
|
||||||
|
case PATH_TYPES -> getDocTypes(ex);
|
||||||
case null, default -> super.doGet(path,ex);
|
case null, default -> super.doGet(path,ex);
|
||||||
};
|
};
|
||||||
} catch (UmbrellaException e) {
|
} catch (UmbrellaException e) {
|
||||||
@@ -75,6 +80,15 @@ public class DocumentApi extends BaseHandler {
|
|||||||
return sendContent(ex,getLegacyCompanies(ex,user,token));
|
return sendContent(ex,getLegacyCompanies(ex,user,token));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean getContacts(HttpExchange ex, UmbrellaUser user, Token token) throws IOException, UmbrellaException {
|
||||||
|
return sendContent(ex,getLegacyContacts(ex,user,token));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean getDocTypes(HttpExchange ex) throws UmbrellaException, IOException {
|
||||||
|
var types = db.listTypes();
|
||||||
|
var map = types.values().stream().collect(Collectors.toMap(Type::id, Type::name));
|
||||||
|
return sendContent(ex,map);
|
||||||
|
}
|
||||||
private HashMap<Long, Map<String, Object>> getLegacyCompanies(HttpExchange ex, UmbrellaUser umbrellaUser, Token token) throws IOException, UmbrellaException {
|
private HashMap<Long, Map<String, Object>> getLegacyCompanies(HttpExchange ex, UmbrellaUser umbrellaUser, Token token) throws IOException, UmbrellaException {
|
||||||
var location = config.get("company.baseUrl").map(s -> s+"/json").orElseThrow(() -> new UmbrellaException(500,"umbrella.modules.company.baseUrl not configured!"));
|
var location = config.get("company.baseUrl").map(s -> s+"/json").orElseThrow(() -> new UmbrellaException(500,"umbrella.modules.company.baseUrl not configured!"));
|
||||||
var resp = request(location, token.asMap(),MIME_FORM_URL,null);
|
var resp = request(location, token.asMap(),MIME_FORM_URL,null);
|
||||||
@@ -84,6 +98,13 @@ public class DocumentApi extends BaseHandler {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private JSONArray getLegacyContacts(HttpExchange ex, UmbrellaUser umbrellaUser, Token token) throws IOException, UmbrellaException {
|
||||||
|
var location = config.get("contact.baseUrl").map(s -> s+"/json").orElseThrow(() -> new UmbrellaException(500,"umbrella.modules.company.baseUrl not configured!"));
|
||||||
|
var resp = request(location, token.asMap(),MIME_FORM_URL,null);
|
||||||
|
if (!(resp instanceof String s && s.startsWith("["))) throw new UmbrellaException(500,"{0} did not return JSON Array!",location);
|
||||||
|
return new JSONArray(s);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean listDocuments(HttpExchange ex, UmbrellaUser user, Token token) throws UmbrellaException {
|
private boolean listDocuments(HttpExchange ex, UmbrellaUser user, Token token) throws UmbrellaException {
|
||||||
try {
|
try {
|
||||||
var json = json(ex);
|
var json = json(ex);
|
||||||
|
|||||||
@@ -264,8 +264,8 @@ public final class Document implements Mappable {
|
|||||||
return Map.of(
|
return Map.of(
|
||||||
ID, id,
|
ID, id,
|
||||||
NUMBER, number,
|
NUMBER, number,
|
||||||
"type", format("<? {0} ?>", type.name()),
|
"type", type.name(),
|
||||||
STATE, Map.of(NAME,format("<? {0} ?>", state),ID,state.code),
|
STATE, Map.of(NAME,state.toString(),ID,state.code),
|
||||||
DATE, date,
|
DATE, date,
|
||||||
FIELD_CURRENCY, currency,
|
FIELD_CURRENCY, currency,
|
||||||
FIELD_CUSTOMER, customer.toMap(),
|
FIELD_CUSTOMER, customer.toMap(),
|
||||||
|
|||||||
37
frontend/src/Components/ContactSelector.svelte
Normal file
37
frontend/src/Components/ContactSelector.svelte
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<script>
|
||||||
|
import {onMount} from 'svelte';
|
||||||
|
import {t} from '../translations.svelte.js';
|
||||||
|
let { caption, onselect = (contact) => console.log('selected '+contact.FN||contact.ORG) } = $props();
|
||||||
|
let message = t('contacts.loading');
|
||||||
|
let contacts = $state(null);
|
||||||
|
let value = 0;
|
||||||
|
|
||||||
|
async function loadContacts(){
|
||||||
|
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/document/contacts`;
|
||||||
|
var resp = await fetch(url,{ credentials: 'include'});
|
||||||
|
if (resp.ok){
|
||||||
|
contacts = await resp.json();
|
||||||
|
} else {
|
||||||
|
message = await resp.text();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function select(){
|
||||||
|
onselect(contacts[value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(loadContacts)
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if contacts}
|
||||||
|
<select onchange={select} bind:value>
|
||||||
|
<option value={0}>{caption}</option>
|
||||||
|
{#each contacts as contact,idx}
|
||||||
|
<option value={idx}>{contact.FN||contact.ORG}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
{:else}
|
||||||
|
<span>{message}</span>
|
||||||
|
{/if}
|
||||||
|
|
||||||
@@ -14,7 +14,6 @@ async function fetchModules(){
|
|||||||
if (resp.ok){
|
if (resp.ok){
|
||||||
const arr = await resp.json();
|
const arr = await resp.json();
|
||||||
for (let entry of arr) modules.push({name:t('menu.'+entry.module),url:entry.url});
|
for (let entry of arr) modules.push({name:t('menu.'+entry.module),url:entry.url});
|
||||||
console.log(modules);
|
|
||||||
} else {
|
} else {
|
||||||
console.log('error');
|
console.log('error');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,141 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import { onMount } from 'svelte';
|
||||||
import { t } from '../../translations.svelte.js';
|
import { t } from '../../translations.svelte.js';
|
||||||
import { useTinyRouter } from 'svelte-tiny-router';
|
import { useTinyRouter } from 'svelte-tiny-router';
|
||||||
|
import ContactSelector from '../../Components/ContactSelector.svelte';
|
||||||
|
|
||||||
let router = useTinyRouter();
|
let router = useTinyRouter();
|
||||||
let company_id = router.query.company;
|
let company = $state(null);
|
||||||
|
let error = null;
|
||||||
|
let docType = $state(null);
|
||||||
|
let document = $state({
|
||||||
|
type : router.query.document_type,
|
||||||
|
company : router.query.company_id,
|
||||||
|
customer : {
|
||||||
|
addr : ''
|
||||||
|
},
|
||||||
|
sender : {
|
||||||
|
name : 'sender'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
async function loadCompanies(){
|
||||||
|
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/document/companies`;
|
||||||
|
var resp = await fetch(url,{ credentials: 'include'});
|
||||||
|
if (resp.ok){
|
||||||
|
const companies = await resp.json();
|
||||||
|
company = companies[document.company];
|
||||||
|
document.sender.name = '';
|
||||||
|
if (company.name) document.sender.name += company.name+"\n";
|
||||||
|
if (company.address) document.sender.name += company.address+"\n";
|
||||||
|
if (company.tax_number) document.sender.tax_id = company.tax_number;
|
||||||
|
if (company.bank_account) document.sender.bank_account = company.bank_account;
|
||||||
|
if (company.court) document.sender.court = company.court;
|
||||||
|
} else {
|
||||||
|
error = await resp.text();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadDocType(){
|
||||||
|
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/document/types`;
|
||||||
|
var resp = await fetch(url,{ credentials: 'include'});
|
||||||
|
if (resp.ok){
|
||||||
|
const types = await resp.json();
|
||||||
|
docType = t('document.type_'+types[document.type]);
|
||||||
|
} else {
|
||||||
|
error = await resp.text();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function load(){
|
||||||
|
loadCompanies();
|
||||||
|
loadDocType();
|
||||||
|
}
|
||||||
|
|
||||||
|
function contactSelected(contact){
|
||||||
|
var addr = '';
|
||||||
|
if (contact.ORG) addr += contact.ORG.trim()+"\n";
|
||||||
|
if (contact.N) {
|
||||||
|
var name = (contact.N.given+" "+contact.N.family).trim()+"\n";
|
||||||
|
if (name != addr) addr += name;
|
||||||
|
}
|
||||||
|
if (contact.ADR.street) addr += contact.ADR.street+"\n";
|
||||||
|
if (contact.ADR.locality) addr += contact.ADR.post_code + " "+ contact.ADR.locality + "\n";
|
||||||
|
if (contact.ADR.county) addr += contact.ADR.country+"\n";
|
||||||
|
document.customer.addr = addr;
|
||||||
|
document.customer.tax_number = contact['X-TAX-NUMBER'];
|
||||||
|
document.customer.id = contact['X-CUSTOMER-NUMBER'];
|
||||||
|
document.customer.email = contact.EMAIL.val;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function submit(){
|
||||||
|
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/document`;
|
||||||
|
const resp = await fetch(url,{
|
||||||
|
method: 'POST',
|
||||||
|
credentials: 'include',
|
||||||
|
body: JSON.stringify(document)
|
||||||
|
});
|
||||||
|
if (resp.ok){
|
||||||
|
} else {
|
||||||
|
error = await resp.text();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(load);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
label{display:block}
|
||||||
|
</style>
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{t('document.add_new')}</legend>
|
{#if docType}
|
||||||
Company: {company_id}
|
<legend>{t('document.add_new',docType)}</legend>
|
||||||
|
{/if}
|
||||||
|
{#if error}
|
||||||
|
<span class="error">{error}</span>
|
||||||
|
{/if}
|
||||||
|
{#if company}
|
||||||
|
Company: {company.name}
|
||||||
|
<fieldset>
|
||||||
|
<legend>{t('document.customer')}</legend>
|
||||||
|
<ContactSelector caption={t('document.select_customer')} onselect={contactSelected} />
|
||||||
|
<label>
|
||||||
|
<textarea bind:value={document.customer.addr}></textarea>
|
||||||
|
{t('document.customer_address')}
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<input bind:value={document.customer.tax_number} />
|
||||||
|
{t('document.tax_number')}
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<input bind:value={document.customer.id} />
|
||||||
|
{t('document.customer_id')}
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<input bind:value={document.customer.email} />
|
||||||
|
{t('document.email')}
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
{/if}
|
||||||
|
<fieldset>
|
||||||
|
<legend>{t('document.sender')}</legend>
|
||||||
|
<label>
|
||||||
|
<textarea bind:value={document.sender.name}></textarea>
|
||||||
|
{t('document.sender_name')}
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<input bind:value={document.sender.tax_id} />
|
||||||
|
{t('document.sender_tax_id')}
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<textarea bind:value={document.sender.bank_account}></textarea>
|
||||||
|
{t('document.sender_bank_account')}
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<input bind:value={document.sender.court} />
|
||||||
|
{t('document.sender_local_court')}
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
<button onclick={submit}>{t('document.create_new')}</button>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
@@ -2,18 +2,20 @@
|
|||||||
import { useTinyRouter } from 'svelte-tiny-router';
|
import { useTinyRouter } from 'svelte-tiny-router';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { t } from '../../translations.svelte.js';
|
import { t } from '../../translations.svelte.js';
|
||||||
|
import TypeSelector from './TypeSelector.svelte';
|
||||||
|
|
||||||
let error = null;
|
let error = null;
|
||||||
let companies = {};
|
let companies = {};
|
||||||
let documents = null;
|
let documents = null;
|
||||||
let selected_company = null;
|
let selected_company = null;
|
||||||
let router = useTinyRouter();
|
let router = useTinyRouter();
|
||||||
|
let docType = 0;
|
||||||
|
|
||||||
async function loadCompanies(){
|
async function loadCompanies(){
|
||||||
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/document/companies`;
|
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/document/companies`;
|
||||||
var resp = await fetch(url,{ credentials: 'include'});
|
var resp = await fetch(url,{ credentials: 'include'});
|
||||||
if (resp.ok){
|
if (resp.ok){
|
||||||
companies = await resp.json();
|
companies = await resp.json();
|
||||||
console.log(companies);
|
|
||||||
} else {
|
} else {
|
||||||
error = await resp.text();
|
error = await resp.text();
|
||||||
}
|
}
|
||||||
@@ -29,18 +31,20 @@
|
|||||||
});
|
});
|
||||||
if (resp.ok){
|
if (resp.ok){
|
||||||
documents = await resp.json();
|
documents = await resp.json();
|
||||||
console.log(documents);
|
|
||||||
} else {
|
} else {
|
||||||
error = await resp.text();
|
error = await resp.text();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDoc(){
|
||||||
|
router.navigate(`/document/add?company_id=${selected_company.id}&document_type=${docType}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(loadCompanies);
|
onMount(loadCompanies);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{name ? t( 'document.list_of',name) : t('document.list')}</legend>
|
<legend>{selected_company ? t( 'document.list_of',selected_company.name) : t('document.list')}</legend>
|
||||||
{#if error}
|
{#if error}
|
||||||
<div class="error">{error}</div>
|
<div class="error">{error}</div>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -51,19 +55,31 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{#if documents}
|
{#if documents}
|
||||||
<button onclick={() => router.navigate(`/document/add?company=${selected_company.id}`)}>{t('document.create_new')}</button>
|
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{t('document.number')}</th>
|
||||||
|
<th>{t('document.date')}</th>
|
||||||
|
<th>{t('document.customer')}</th>
|
||||||
|
<th>{t('document.gross_sum')}</th>
|
||||||
|
<th>{t('document.type')}</th>
|
||||||
|
<th>{t('document.state')}</th>
|
||||||
|
<th>
|
||||||
|
{t('document.actions')}
|
||||||
|
{docType}
|
||||||
|
<TypeSelector caption={t('document.create_new')} bind:value={docType} onchange={createDoc}/>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{#each Object.entries(documents) as [id,document]}
|
{#each Object.entries(documents).reverse() as [id,document]}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{id}</td>
|
|
||||||
<td>{document.number}</td>
|
<td>{document.number}</td>
|
||||||
<td>{document.date}</td>
|
<td>{document.date}</td>
|
||||||
<td>{document.customer.name.split('\n')[0]}</td>
|
<td>{document.customer.name.split('\n')[0]}</td>
|
||||||
<td>{document.sum/100 + document.currency}</td>
|
<td>{document.sum/100 + document.currency}</td>
|
||||||
|
<td>{t('document.type_'+document.type)}</td>
|
||||||
|
<td>{t('document.state_'+document.state.name)}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{/each}
|
{/each}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
33
frontend/src/routes/document/TypeSelector.svelte
Normal file
33
frontend/src/routes/document/TypeSelector.svelte
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<script>
|
||||||
|
import {onMount} from 'svelte';
|
||||||
|
import {t} from '../../translations.svelte.js';
|
||||||
|
let { caption, value = $bindable(0), onchange = () => console.log('changed')} = $props();
|
||||||
|
let message = t('document.loading');
|
||||||
|
let types = $state(null);
|
||||||
|
|
||||||
|
async function loadTypes(){
|
||||||
|
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/document/types`;
|
||||||
|
var resp = await fetch(url,{ credentials: 'include'});
|
||||||
|
if (resp.ok){
|
||||||
|
types = await resp.json();
|
||||||
|
} else {
|
||||||
|
message = await resp.text();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(loadTypes)
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if types}
|
||||||
|
<select bind:value onchange={onchange}>
|
||||||
|
<option value={0}>{caption}</option>
|
||||||
|
{#each Object.entries(types) as [id,type]}
|
||||||
|
<option value={id}>{t('document.type_'+type)}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
{:else}
|
||||||
|
<span>{message}</span>
|
||||||
|
{/if}
|
||||||
|
|
||||||
@@ -21,10 +21,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
console.log(location.search);
|
|
||||||
let params = new URLSearchParams(location.search);
|
let params = new URLSearchParams(location.search);
|
||||||
key = params.get('key');
|
key = params.get('key');
|
||||||
console.log({param:key});
|
|
||||||
if (key) doSearch();
|
if (key) doSearch();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
async function checkToken(){
|
async function checkToken(){
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
const token = urlParams.get('token');
|
const token = urlParams.get('token');
|
||||||
console.log({token:token,params:urlParams});
|
|
||||||
if (token) {
|
if (token) {
|
||||||
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/user/validate/${token}`;
|
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/user/validate/${token}`;
|
||||||
const resp = await fetch(url,{
|
const resp = await fetch(url,{
|
||||||
|
|||||||
@@ -1,8 +1,27 @@
|
|||||||
{
|
{
|
||||||
"document": {
|
"document": {
|
||||||
|
"actions": "Aktionen",
|
||||||
|
"add_new": "{0} anlegen",
|
||||||
|
"create_new": "neues Dokument",
|
||||||
|
"customer": "Kunde",
|
||||||
|
"date": "Datum",
|
||||||
|
"gross_sum": "Brutto-Summe",
|
||||||
"list": "Dokumente",
|
"list": "Dokumente",
|
||||||
"list_of": "Dokumente von {0}",
|
"list_of": "Dokumente von {0}",
|
||||||
"select_company" : "Wählen Sie eine ihrer Firmen:"
|
"number": "Nummer",
|
||||||
|
"select_company" : "Wählen Sie eine ihrer Firmen:",
|
||||||
|
"select customer": "Kunde auswählen",
|
||||||
|
"sender": "Absender",
|
||||||
|
"state": "Status",
|
||||||
|
"state_declined": "abgelehnt",
|
||||||
|
"state_new":"neu",
|
||||||
|
"state_payed": "bezahlt",
|
||||||
|
"state_sent": "versendet",
|
||||||
|
"type": "Dokumententyp",
|
||||||
|
"type_confirmation": "Bestätigung",
|
||||||
|
"type_invoice": "Rechnung",
|
||||||
|
"type_offer": "Angebot",
|
||||||
|
"type_reminder": "Erinnerung"
|
||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
"message" : "Umbrella ist ein Produkt von {0}."
|
"message" : "Umbrella ist ein Produkt von {0}."
|
||||||
|
|||||||
Reference in New Issue
Block a user