preparing storing of new contact
This commit is contained in:
@@ -9,7 +9,9 @@
|
||||
import ExtraField from './ExtraField.svelte';
|
||||
import FN from './FN.svelte';
|
||||
import Name from './Name.svelte';
|
||||
import Number from './Number.svelte';
|
||||
import Org from './Org.svelte';
|
||||
import URL from './URL.svelte';
|
||||
|
||||
let { contact } = $props();
|
||||
|
||||
@@ -18,7 +20,9 @@
|
||||
let emails = $derived(contact.vcard.match(/^EMAIL.*:.+$/gm));
|
||||
let extra_fields = $derived(contact.vcard.match(/^X-.*:.+/gm));
|
||||
let fns = $derived(contact.vcard.match(/^FN.*:.+$/gm));
|
||||
let numbers = $derived(contact.vcard.match(/^TEL.*:.+$/gm));
|
||||
let orgs = $derived(contact.vcard.match(/^ORG.*:.+$/gm));
|
||||
let urls = $derived(contact.vcard.match(/^URL.*:.+$/gm));
|
||||
|
||||
async function patch(from,to){
|
||||
if (from == to) return;
|
||||
@@ -44,7 +48,11 @@
|
||||
|
||||
<fieldset class="vcard">
|
||||
<legend>
|
||||
{#if contact.id}
|
||||
{t('contact_number',{number:contact.id})}
|
||||
{:else}
|
||||
{t('new_contact')}
|
||||
{/if}
|
||||
<button class="symbol" onclick={toggleCode}></button>
|
||||
</legend>
|
||||
<table>
|
||||
@@ -81,6 +89,13 @@
|
||||
{/each}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{#each numbers as code}
|
||||
<Number {code} {patch} />
|
||||
{/each}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{#each emails as code}
|
||||
@@ -95,6 +110,13 @@
|
||||
{/each}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{#each urls as code}
|
||||
<URL {code} {patch} />
|
||||
{/each}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</fieldset>
|
||||
@@ -15,6 +15,27 @@
|
||||
yikes();
|
||||
var data = await res.json();
|
||||
contacts = Object.values(data).sort(byName);
|
||||
contacts.unshift({
|
||||
id: 0,
|
||||
vcard: `BEGIN:VCARD
|
||||
VERSION:3.0
|
||||
PRODID:Umbrella Contact manager by SRSoftware
|
||||
FN:${t('formatted_name')}
|
||||
N:${t('family_name')};${t('given_name')};;;
|
||||
ORG:${t('organization')}
|
||||
EMAIL;TYPE=HOME:${t('email')}
|
||||
EMAIL;TYPE=WORK:${t('email')}
|
||||
ADR;TYPE=HOME:;;${t('street')};${t('locality')};${t('region')};${t('post_code')};${t('country')}
|
||||
ADR;TYPE=WORK:;;${t('street')};${t('locality')};${t('region')};${t('post_code')};${t('country')}
|
||||
TEL;TYPE=CELL;:${t('phone_cell')}
|
||||
TEL;TYPE=HOME;:${t('phone_home')}
|
||||
TEL;TYPE=WORK;:${t('phone_work')}
|
||||
X-TAX-NUMBER:${t('tax_id')}
|
||||
X-BANK-ACCOUNT:${t('bank_account')}\\nIBAN:XXXX\\nBIC:XXXX
|
||||
X-COURT:${t('local_court')}
|
||||
URL:https://example.com
|
||||
END:VCARD`
|
||||
});
|
||||
} else {
|
||||
error(res);
|
||||
}
|
||||
|
||||
43
frontend/src/routes/contact/Number.svelte
Normal file
43
frontend/src/routes/contact/Number.svelte
Normal file
@@ -0,0 +1,43 @@
|
||||
<script>
|
||||
import LineEditor from '../../Components/LineEditor.svelte';
|
||||
import { number } from '../../vcard.js';
|
||||
|
||||
let { code, patch = (from, to) => true } = $props();
|
||||
|
||||
let cell = $derived(code.toLowerCase().includes('type=cell'));
|
||||
let home = $derived(code.toLowerCase().includes('type=home'));
|
||||
let work = $derived(code.toLowerCase().includes('type=work'));
|
||||
let value = $derived(number(code));
|
||||
|
||||
function onSet(newVal){
|
||||
const newCode = code.replace(value,newVal);
|
||||
return patch(code,newCode);
|
||||
}
|
||||
|
||||
function toggleCell(){
|
||||
toggleType('CELL');
|
||||
}
|
||||
|
||||
function toggleHome(){
|
||||
toggleType('HOME');
|
||||
}
|
||||
|
||||
function toggleType(key){
|
||||
key = key.toUpperCase();
|
||||
if (code.toUpperCase().includes(';TYPE='+key)) {
|
||||
const regex = new RegExp(';TYPE='+key, "ig");
|
||||
patch(code,code.replace(regex,''));
|
||||
} else patch(code,code.replace('TEL','TEL;TYPE='+key));
|
||||
}
|
||||
|
||||
function toggleWork(){
|
||||
toggleType('WORK');
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if value}
|
||||
<span class="symbol {cell?'':'inactive'}" onclick={toggleCell} ></span>
|
||||
<span class="symbol {home?'':'inactive'}" onclick={toggleHome}></span>
|
||||
<span class="symbol {work?'':'inactive'}" onclick={toggleWork} ></span>
|
||||
<LineEditor type="span" editable={true} {value} {onSet} /><br/>
|
||||
{/if}
|
||||
18
frontend/src/routes/contact/URL.svelte
Normal file
18
frontend/src/routes/contact/URL.svelte
Normal file
@@ -0,0 +1,18 @@
|
||||
<script>
|
||||
import LineEditor from '../../Components/LineEditor.svelte';
|
||||
import { url } from '../../vcard.js';
|
||||
import { t } from '../../translations.svelte';
|
||||
|
||||
let { code, patch = (from, to) => true } = $props();
|
||||
|
||||
let value = $derived(url(code));
|
||||
|
||||
function onSet(newVal){
|
||||
const newCode = code.replace(value,newVal);
|
||||
return patch(code,newCode);
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if value}
|
||||
<LineEditor type="span" editable={true} {value} {onSet} title={t('url')}/>
|
||||
{/if}
|
||||
@@ -37,11 +37,22 @@ export function fn(vcard){
|
||||
return match ? match[1].trim() : '';
|
||||
}
|
||||
|
||||
export function number(vcard){
|
||||
const match = vcard.match(/^TEL.*:(.+)$/m);
|
||||
return match ? match[1].trim() : '';
|
||||
}
|
||||
|
||||
|
||||
export function org(vcard){
|
||||
const match = vcard.match(/^ORG:(.+)$/m);
|
||||
return match ? match[1].trim() : '';
|
||||
}
|
||||
|
||||
export function url(vcard){
|
||||
const match = vcard.match(/^URL:(.+)$/m);
|
||||
return match ? match[1].trim() : '';
|
||||
}
|
||||
|
||||
export function name(vcard){
|
||||
const match = vcard.match(/^N:(.+)$/m);
|
||||
let name = {
|
||||
|
||||
Reference in New Issue
Block a user