first working version where transactions can be stored
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
@@ -10,10 +10,7 @@ import de.srsoftware.umbrella.core.api.AccountingService;
|
|||||||
import de.srsoftware.umbrella.core.constants.Field;
|
import de.srsoftware.umbrella.core.constants.Field;
|
||||||
import de.srsoftware.umbrella.core.constants.Text;
|
import de.srsoftware.umbrella.core.constants.Text;
|
||||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||||
import de.srsoftware.umbrella.core.model.Account;
|
import de.srsoftware.umbrella.core.model.*;
|
||||||
import de.srsoftware.umbrella.core.model.Token;
|
|
||||||
import de.srsoftware.umbrella.core.model.Transaction;
|
|
||||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -30,10 +27,8 @@ import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
|
|||||||
import static de.srsoftware.umbrella.core.ModuleRegistry.userService;
|
import static de.srsoftware.umbrella.core.ModuleRegistry.userService;
|
||||||
import static de.srsoftware.umbrella.core.Util.mapValues;
|
import static de.srsoftware.umbrella.core.Util.mapValues;
|
||||||
import static de.srsoftware.umbrella.core.constants.Path.JSON;
|
import static de.srsoftware.umbrella.core.constants.Path.JSON;
|
||||||
import static de.srsoftware.umbrella.core.constants.Path.SEARCH;
|
|
||||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.invalidField;
|
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.invalidField;
|
||||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingField;
|
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingField;
|
||||||
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
|
|
||||||
|
|
||||||
public class AccountingModule extends BaseHandler implements AccountingService {
|
public class AccountingModule extends BaseHandler implements AccountingService {
|
||||||
private final AccountDb accountDb;
|
private final AccountDb accountDb;
|
||||||
@@ -85,32 +80,27 @@ public class AccountingModule extends BaseHandler implements AccountingService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean getAccount(UmbrellaUser user, long accountId, HttpExchange ex) throws IOException {
|
private boolean getAccount(UmbrellaUser user, long accountId, HttpExchange ex) throws IOException {
|
||||||
var account = accountDb.loadAccount(accountId);
|
var account = accountDb.loadAccount(accountId);
|
||||||
var transactions = accountDb.loadTransactions(account);
|
var transactions = accountDb.loadTransactions(account);
|
||||||
var userMap = new HashMap<Long,UmbrellaUser>();
|
var userMap = new HashMap<Long,UmbrellaUser>();
|
||||||
var foundRequestingUser = false;
|
|
||||||
for (var i=0; i<transactions.size();i++){
|
for (var transaction : transactions){
|
||||||
var transaction = transactions.get(i);
|
var source = transaction.source();
|
||||||
try {
|
if (source.isId()) {
|
||||||
var userId = Long.parseLong(transaction.source());
|
var userId = source.id();
|
||||||
var u = userMap.get(userId);
|
if (!userMap.containsKey(userId)) userMap.put(source.id(),userService().loadUser(userId));
|
||||||
if (u == null) userMap.put(userId,u=userService().loadUser(userId));
|
}
|
||||||
if (!foundRequestingUser) foundRequestingUser = user.equals(u);
|
var destination = transaction.destination();
|
||||||
transaction = new Transaction(transaction.accountId(),transaction.date(),u.name(),transaction.destination(),transaction.amount(),transaction.purpose());
|
if (destination.isId()) {
|
||||||
transactions.set(i,transaction);
|
var userId = destination.id();
|
||||||
} catch (NumberFormatException ignored){}
|
if (!userMap.containsKey(userId)) userMap.put(destination.id(),userService().loadUser(userId));
|
||||||
try {
|
}
|
||||||
var userId = Long.parseLong(transaction.destination());
|
|
||||||
var u = userMap.get(userId);
|
|
||||||
if (u == null) userMap.put(userId,u=userService().loadUser(userId));
|
|
||||||
if (!foundRequestingUser) foundRequestingUser = user.equals(u);
|
|
||||||
transaction = new Transaction(transaction.accountId(),transaction.date(),transaction.source(),u.name(),transaction.amount(),transaction.purpose());
|
|
||||||
transactions.set(i,transaction);
|
|
||||||
} catch (NumberFormatException ignored){}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sendContent(ex, Map.of(
|
return sendContent(ex, Map.of(
|
||||||
Field.ACCOUNT,account.toMap(),
|
Field.ACCOUNT,account.toMap(),
|
||||||
Field.TRANSACTIONS,transactions.stream().map(Transaction::toMap).toList()
|
Field.TRANSACTIONS,transactions.stream().map(Transaction::toMap).toList(),
|
||||||
|
Field.USER_LIST,mapValues(userMap)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,26 +128,24 @@ public class AccountingModule extends BaseHandler implements AccountingService {
|
|||||||
if (!json.has(Field.DESTINATION)) throw missingField(Field.DESTINATION);
|
if (!json.has(Field.DESTINATION)) throw missingField(Field.DESTINATION);
|
||||||
if (!(json.get(Field.DESTINATION) instanceof JSONObject destinationData)) throw invalidField(Field.DESTINATION,JSON);
|
if (!(json.get(Field.DESTINATION) instanceof JSONObject destinationData)) throw invalidField(Field.DESTINATION,JSON);
|
||||||
|
|
||||||
String source = null, destination = null;
|
IdOrString source = null, destination = null;
|
||||||
|
|
||||||
if (sourceData.has(Field.USER_ID)) {
|
if (sourceData.has(Field.ID)) {
|
||||||
if (!(sourceData.get(Field.USER_ID) instanceof Number uid)) throw invalidField(String.join(".",Field.SOURCE,Field.USER_ID),Text.NUMBER);
|
if (!(sourceData.get(Field.ID) instanceof Number uid)) throw invalidField(String.join(".",Field.SOURCE,Field.ID),Text.NUMBER);
|
||||||
var u = userService().loadUser(uid.longValue());
|
source = IdOrString.of(userService().loadUser(uid.longValue()));
|
||||||
source = ""+u.id();
|
|
||||||
} else {
|
} else {
|
||||||
if (!sourceData.has(Field.DISPLAY)) throw missingField(String.join(".",Field.SOURCE,Field.DISPLAY));
|
if (!sourceData.has(Field.DISPLAY)) throw missingField(String.join(".",Field.SOURCE,Field.DISPLAY));
|
||||||
source = sourceData.getString(Field.DISPLAY);
|
source = IdOrString.of(sourceData.getString(Field.DISPLAY));
|
||||||
if (source.isBlank()) throw invalidField(String.join(".",Field.SOURCE,Field.DISPLAY),Text.STRING);
|
if (source.value().isBlank()) throw invalidField(String.join(".",Field.SOURCE,Field.DISPLAY),Text.STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (destinationData.has(Field.USER_ID)) {
|
if (destinationData.has(Field.ID)) {
|
||||||
if (!(destinationData.get(Field.USER_ID) instanceof Number uid)) throw invalidField(String.join(".",Field.DESTINATION,Field.USER_ID),Text.NUMBER);
|
if (!(destinationData.get(Field.ID) instanceof Number uid)) throw invalidField(String.join(".",Field.DESTINATION,Field.ID),Text.NUMBER);
|
||||||
var u = userService().loadUser(uid.longValue());
|
destination = IdOrString.of(userService().loadUser(uid.longValue()));
|
||||||
destination = ""+u;
|
|
||||||
} else {
|
} else {
|
||||||
if (!destinationData.has(Field.DISPLAY)) throw missingField(String.join(".",Field.DESTINATION,Field.DISPLAY));
|
if (!destinationData.has(Field.DISPLAY)) throw missingField(String.join(".",Field.DESTINATION,Field.DISPLAY));
|
||||||
destination = destinationData.getString(Field.DISPLAY);
|
destination = IdOrString.of(destinationData.getString(Field.DISPLAY));
|
||||||
if (destination.isBlank()) throw invalidField(String.join(".",Field.DESTINATION,Field.DISPLAY),Text.STRING);
|
if (destination.value().isBlank()) throw invalidField(String.join(".",Field.DESTINATION,Field.DISPLAY),Text.STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ public class SqliteDb extends BaseDb implements AccountDb {
|
|||||||
try {
|
try {
|
||||||
var timestamp = transaction.date().toEpochSecond(ZoneOffset.UTC);
|
var timestamp = transaction.date().toEpochSecond(ZoneOffset.UTC);
|
||||||
Query.replaceInto(TABLE_TRANSACTIONS,Field.ACCOUNT,Field.TIMESTAMP,Field.SOURCE,Field.DESTINATION, Field.AMOUNT,Field.DESCRIPTION)
|
Query.replaceInto(TABLE_TRANSACTIONS,Field.ACCOUNT,Field.TIMESTAMP,Field.SOURCE,Field.DESTINATION, Field.AMOUNT,Field.DESCRIPTION)
|
||||||
.values(transaction.accountId(),timestamp,transaction.source(),transaction.destination(),transaction.amount(),transaction.purpose())
|
.values(transaction.accountId(),timestamp,transaction.source().value(),transaction.destination().value(),transaction.amount(),transaction.purpose())
|
||||||
.execute(db).close();
|
.execute(db).close();
|
||||||
return transaction;
|
return transaction;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package de.srsoftware.umbrella.core.model;
|
||||||
|
|
||||||
|
import de.srsoftware.tools.Mappable;
|
||||||
|
import de.srsoftware.umbrella.core.constants.Field;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class IdOrString implements Mappable {
|
||||||
|
private final Long id;
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
public IdOrString(String val){
|
||||||
|
this.value = val;
|
||||||
|
this.id = parseOrNull(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IdOrString(long id){
|
||||||
|
this.value = ""+id;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isId(){
|
||||||
|
return id != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IdOrString of(String val){
|
||||||
|
return new IdOrString(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IdOrString of(UmbrellaUser user) {
|
||||||
|
return new IdOrString(user.id());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Long parseOrNull(String val) {
|
||||||
|
try {
|
||||||
|
return Long.parseLong(val);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long id(){
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> toMap() {
|
||||||
|
var map = new HashMap<String,Object>();
|
||||||
|
map.put(Field.VALUE,value);
|
||||||
|
if (isId()) map.put(Field.ID, id);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String value(){
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,20 +5,20 @@ import de.srsoftware.umbrella.core.constants.Field;
|
|||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static de.srsoftware.umbrella.core.ModuleRegistry.userService;
|
public record Transaction(long accountId, LocalDateTime date, IdOrString source, IdOrString destination, double amount, String purpose) implements Mappable {
|
||||||
|
|
||||||
|
|
||||||
public record Transaction(long accountId, LocalDateTime date, String source, String destination, double amount, String purpose) implements Mappable {
|
|
||||||
public static Transaction of(ResultSet rs) throws SQLException {
|
public static Transaction of(ResultSet rs) throws SQLException {
|
||||||
var accountId = rs.getLong(Field.ACCOUNT);
|
var accountId = rs.getLong(Field.ACCOUNT);
|
||||||
var timestamp = rs.getLong(Field.TIMESTAMP);
|
var timestamp = rs.getLong(Field.TIMESTAMP);
|
||||||
var date = LocalDateTime.ofEpochSecond(timestamp,0, ZoneOffset.UTC);
|
var date = LocalDateTime.ofEpochSecond(timestamp,0, ZoneOffset.UTC);
|
||||||
var source = rs.getString(Field.SOURCE);
|
var source = IdOrString.of(rs.getString(Field.SOURCE));
|
||||||
var destination = rs.getString(Field.DESTINATION);
|
var destination = IdOrString.of(rs.getString(Field.DESTINATION));
|
||||||
var amount = rs.getDouble(Field.AMOUNT);
|
var amount = rs.getDouble(Field.AMOUNT);
|
||||||
var purpose = rs.getString(Field.DESCRIPTION);
|
var purpose = rs.getString(Field.DESCRIPTION);
|
||||||
return new Transaction(accountId,date,source,destination,amount,purpose);
|
return new Transaction(accountId,date,source,destination,amount,purpose);
|
||||||
@@ -26,25 +26,11 @@ public record Transaction(long accountId, LocalDateTime date, String source, Str
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> toMap() {
|
public Map<String, Object> toMap() {
|
||||||
var source = this.source;
|
|
||||||
try {
|
|
||||||
var userId = Long.parseLong(source);
|
|
||||||
var user = userService().loadUser(userId);
|
|
||||||
source = user.name();
|
|
||||||
} catch (NumberFormatException ignored) {}
|
|
||||||
|
|
||||||
var destination = this.destination;
|
|
||||||
try {
|
|
||||||
var userId = Long.parseLong(destination);
|
|
||||||
var user = userService().loadUser(userId);
|
|
||||||
destination = user.name();
|
|
||||||
} catch (NumberFormatException ignored) {}
|
|
||||||
|
|
||||||
return Map.of(
|
return Map.of(
|
||||||
Field.ACCOUNT, accountId,
|
Field.ACCOUNT, accountId,
|
||||||
Field.DATE, date.toLocalDate(),
|
Field.DATE, date.toLocalDate(),
|
||||||
Field.SOURCE, source,
|
Field.SOURCE, source.toMap(),
|
||||||
Field.DESTINATION, destination,
|
Field.DESTINATION, destination.toMap(),
|
||||||
Field.AMOUNT, amount,
|
Field.AMOUNT, amount,
|
||||||
Field.PURPOSE, purpose
|
Field.PURPOSE, purpose
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ package de.srsoftware.umbrella.core.model;
|
|||||||
import static de.srsoftware.umbrella.core.constants.Field.*;
|
import static de.srsoftware.umbrella.core.constants.Field.*;
|
||||||
|
|
||||||
import de.srsoftware.tools.Mappable;
|
import de.srsoftware.tools.Mappable;
|
||||||
|
import de.srsoftware.umbrella.core.api.NamedThing;
|
||||||
import de.srsoftware.umbrella.core.api.Owner;
|
import de.srsoftware.umbrella.core.api.Owner;
|
||||||
import de.srsoftware.umbrella.core.constants.Module;
|
import de.srsoftware.umbrella.core.constants.Module;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|||||||
@@ -4,18 +4,23 @@
|
|||||||
import { error, yikes } from '../../warn.svelte';
|
import { error, yikes } from '../../warn.svelte';
|
||||||
import { t } from '../../translations.svelte';
|
import { t } from '../../translations.svelte';
|
||||||
|
|
||||||
let { id } = $props();
|
import EntryForm from './add_entry.svelte';
|
||||||
let account = $state(null);
|
|
||||||
|
let { id } = $props();
|
||||||
|
let account = $state(null);
|
||||||
let transactions = [];
|
let transactions = [];
|
||||||
|
let users = {};
|
||||||
|
|
||||||
async function load(){
|
async function load(){
|
||||||
let url = api(`accounting/${id}`);
|
let url = api(`accounting/${id}`);
|
||||||
let res = await get(url);
|
let res = await get(url);
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
yikes();
|
yikes();
|
||||||
let json = await res.json();
|
let json = await res.json();
|
||||||
transactions = json.transactions;
|
transactions = json.transactions;
|
||||||
account = json.account;
|
users = json.user_list;
|
||||||
|
account = json.account;
|
||||||
|
console.log(users);
|
||||||
} else error(res);
|
} else error(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,9 +33,10 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{t('date')}</th>
|
<th>{t('date')}</th>
|
||||||
<th>{t('source')}</th>
|
{#each Object.entries(users) as [id,user]}
|
||||||
<th>{t('destination')}</th>
|
<th>{user.name}</th>
|
||||||
<th>{t('amount')}</th>
|
{/each}
|
||||||
|
<th>{t('other party')}</th>
|
||||||
<th>{t('purpose')}</th>
|
<th>{t('purpose')}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -38,13 +44,30 @@
|
|||||||
{#each transactions as transaction, i}
|
{#each transactions as transaction, i}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{transaction.date}</td>
|
<td>{transaction.date}</td>
|
||||||
<td>{transaction.source}</td>
|
{#each Object.entries(users) as [id,user]}
|
||||||
<td>{transaction.destination}</td>
|
<td>
|
||||||
<td>{transaction.amount} {account.currency}</td>
|
{#if id == transaction.source.id}
|
||||||
|
{-transaction.amount} {account.currency}
|
||||||
|
{/if}
|
||||||
|
{#if id == transaction.destination.id}
|
||||||
|
{transaction.amount} {account.currency}
|
||||||
|
{/if}
|
||||||
|
</td>
|
||||||
|
{/each}
|
||||||
|
<td>
|
||||||
|
{#if !transaction.source.id}
|
||||||
|
{transaction.source.value}
|
||||||
|
{/if}
|
||||||
|
{#if !transaction.destination.id}
|
||||||
|
{transaction.destination.value}
|
||||||
|
{/if}
|
||||||
|
</td>
|
||||||
<td>{transaction.purpose}</td>
|
<td>{transaction.purpose}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{/each}
|
{/each}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
<EntryForm {account} />
|
||||||
{/if}
|
{/if}
|
||||||
@@ -7,18 +7,19 @@
|
|||||||
import { user } from '../../user.svelte';
|
import { user } from '../../user.svelte';
|
||||||
import Autocomplete from '../../Components/Autocomplete.svelte';
|
import Autocomplete from '../../Components/Autocomplete.svelte';
|
||||||
|
|
||||||
let { new_account = false } = $props();
|
let defaultAccount = {
|
||||||
|
id : 0,
|
||||||
|
name : '',
|
||||||
|
currency : ''
|
||||||
|
};
|
||||||
|
let { account = defaultAccount, new_account = false } = $props();
|
||||||
|
|
||||||
let entry = $state({
|
let entry = $state({
|
||||||
account : {
|
account,
|
||||||
id : 0,
|
|
||||||
name : '',
|
|
||||||
currency : ''
|
|
||||||
},
|
|
||||||
date : new Date().toISOString().substring(0, 10),
|
date : new Date().toISOString().substring(0, 10),
|
||||||
source : {
|
source : {
|
||||||
display: user.name,
|
display: user.name,
|
||||||
user_id: user.id
|
id: user.id
|
||||||
},
|
},
|
||||||
destination : {},
|
destination : {},
|
||||||
amount : 0.0,
|
amount : 0.0,
|
||||||
@@ -26,6 +27,19 @@
|
|||||||
});
|
});
|
||||||
let router = useTinyRouter();
|
let router = useTinyRouter();
|
||||||
|
|
||||||
|
async function getUsers(text){
|
||||||
|
var url = api('user/search');
|
||||||
|
var res = await post(url,text);
|
||||||
|
if (res.ok){
|
||||||
|
yikes();
|
||||||
|
const input = await res.json();
|
||||||
|
return Object.values(input).map(user => { return {...user, display: user.name}});
|
||||||
|
} else {
|
||||||
|
error(res);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function save(){
|
async function save(){
|
||||||
let data = {
|
let data = {
|
||||||
...entry,
|
...entry,
|
||||||
@@ -68,10 +82,10 @@
|
|||||||
<input type="date" value={entry.date} />
|
<input type="date" value={entry.date} />
|
||||||
|
|
||||||
<span>{t('source')}</span>
|
<span>{t('source')}</span>
|
||||||
<Autocomplete bind:candidate={entry.source} />
|
<Autocomplete bind:candidate={entry.source} getCandidates={getUsers} />
|
||||||
|
|
||||||
<span>{t('destination')}</span>
|
<span>{t('destination')}</span>
|
||||||
<Autocomplete bind:candidate={entry.destination} />
|
<Autocomplete bind:candidate={entry.destination} getCandidates={getUsers} />
|
||||||
|
|
||||||
<span>{t('amount')}</span>
|
<span>{t('amount')}</span>
|
||||||
<span>
|
<span>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import {api} from '../../urls.svelte'
|
import {api, post} from '../../urls.svelte'
|
||||||
import { error, yikes } from '../../warn.svelte';
|
import { error, yikes } from '../../warn.svelte';
|
||||||
import {t} from '../../translations.svelte';
|
import {t} from '../../translations.svelte';
|
||||||
|
|
||||||
@@ -14,11 +14,7 @@
|
|||||||
|
|
||||||
async function getCandidates(text){
|
async function getCandidates(text){
|
||||||
const url = api('user/search');
|
const url = api('user/search');
|
||||||
const resp = await fetch(url,{
|
const resp = await post(url,text);
|
||||||
credentials : 'include',
|
|
||||||
method : 'POST',
|
|
||||||
body : text
|
|
||||||
});
|
|
||||||
if (resp.ok){
|
if (resp.ok){
|
||||||
yikes();
|
yikes();
|
||||||
const input = await resp.json();
|
const input = await resp.json();
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ export function post(url,data){
|
|||||||
return fetch(url,{
|
return fetch(url,{
|
||||||
credentials : 'include',
|
credentials : 'include',
|
||||||
method : 'POST',
|
method : 'POST',
|
||||||
body : JSON.stringify(data)
|
body : typeof data === 'string' ? data : JSON.stringify(data)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user