-
Andrej Ramašeuski authoredAndrej Ramašeuski authored
shortcuts.html.ep 10.10 KiB
<div id="App" class="content-block">
<form @submit.prevent="addShortcut" v-cloak>
<div class="card elevation-4 space-y-2 my-4">
<div class="card__body">
<div class="grid grid-cols-12 gap-4 row-gap-6">
<div class="form-field col-span-9">
<label class="form-field__label" for="url">URL</label>
<div class="form-field__wrapper form-field__wrapper--shadowed">
<input type="text" name="url" class="text-input form-field__control" value="" placeholder="https://www.pirati.cz/program/dlouhodoby/psychotropni-latky/" required="required" v-model="shortcut.url" @focus="formError=''"/>
</div>
</div>
<div class="form-field col-span-3">
<label class="form-field__label" for="shortcut">Zkratka</label>
<div class="form-field__wrapper form-field__wrapper--shadowed">
<input type="text" name="shortcut" class="text-input form-field__control w-40" size="8" maxlength="8" value="" placeholder="thc" v-model="shortcut.shortcut" @focus="formError=''"/>
<button class="btn btn--grey-125 btn--hoveractive ml-4">
<div class="btn__body">Zkrátit</div>
</button>
</div>
</div>
</div><%# grid %>
</div><%# card__body %>
</div><%# card %>
<div v-if="formError" class="my-4"><span class="alert alert--red-600 alert--faded">{{ formError }}</span></div>
</form>
<table class="table table--striped table--bordered table-auto w-full" v-cloak>
<thead>
<tr>
<th class="text-left">Zkratka</th>
<th class="text-left">Přidano</th>
<th class="text-left">URL</th>
<th class="text-left">Přesměrování</th>
<th class="text-left">Kliky</th>
<th class="text-left"></th>
</tr>
</thead>
<tbody>
<tr v-for="shortcut in shortcuts" >
<td class="text-bold w-32" @click="showEdit(shortcut)" >{{shortcut.shortcut}}</td>
<td class="text-bold w-32" @click="showEdit(shortcut)" >{{ formatTimestamp(shortcut.created) }}</td>
<td v-bind:title="shortcut.url" @click="showEdit(shortcut)" >{{ stripURL(shortcut.url) }}</td>
<td class="w-24" @click="showEdit(shortcut)">{{ shortcut.code == 301 ? '301 trvalé' : '302 dočasné'}}</td>
<td class="w-16 text-right" @click="showEdit(shortcut)">{{shortcut.counter}}</td>
<td class="w-40">
<i class="ico--link cursor-pointer mx-1" @click="showInfo(shortcut)" title="Zkopirovat odkaz"></i>
<i class="ico--calendar cursor-pointer mx-1" @click="window.location.href ='/shortcut/' + shortcut.id" title="Statistika"></i>
<i class="ico--equalizer cursor-pointer mx-1" @click="showEdit(shortcut)" title="Editovat"></i>
<i class="ico--bin cursor-pointer mx-1" @click="showDelete(shortcut)" title="Smazat"></i>
</td>
</tr>
</tbody>
</table>
<div class="modal__overlay" v-if="shortcutInfoVisible" v-cloak>
<div class="modal__content" role="dialog">
<div class="modal__container" role="dialog">
<div class="modal__container-body elevation-10">
<button class="modal__close" title="Zavřít" @click="shortcutInfoVisible = false"><i class="ico--cross"></i></button>
<div class="card">
<div class="card__body w-80 text-center">
<p class="card-body-text">Zkratka byla zkopírovana do schránky. Pro její sdílení můžete používat i QR kód</p>
<img v-bind:src="'/' + selectedShortcut.shortcut + '/qr.png'" class="mx-auto my-8">
<b>{{ selectedShortcut.full_url }}</b>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal__overlay" v-if="deleteConfirmVisible">
<div class="modal__content" role="dialog">
<div class="modal__container" role="dialog">
<div class="modal__container-body elevation-10">
<button class="modal__close" title="Zavřít" @click.prevent="deleteConfirmVisible = false"><i class="ico--cross"></i></button>
<div class="card">
<div class="card__body">
<h1 class="card-headline mb-2">Smazat zkratku</h1>
<p class="card-body-text my-8">Opravdu chcete smazat zkratku?</p>
<p class="card-body-text">
<button class="btn btn--red-600 btn--hoveractive text-sm" @click.prevent="deleteShortcut(selectedShortcut)">
<div class="btn__body"><i class="btn__inline-icon ico--bin"></i>ANO</div>
</button>
<button class="btn btn--grey-500 btn--hoveractive text-sm" @click.prevent="deleteConfirmVisible = false">
<div class="btn__body"><i class="btn__inline-icon ico--cross"></i>NE</div>
</button>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal__overlay" v-if="shortcutEditVisible">
<div class="modal__content" role="dialog">
<div class="modal__container w-full max-w-2xl" role="dialog">
<div class="modal__container-body elevation-10">
<button class="modal__close" title="Zavřít" @click.prevent="shortcutEditVisible = false"><i class="ico--cross"></i></button>
<div class="card">
<div class="card__body">
<h1 class="card-headline mb-2">Editovat zkratku</h1>
<form class="my-4">
<div class="form-field form-field--error form-field--required mb-4">
<label class="form-field__label" for="url">URL</label>
<div class="form-field__wrapper form-field__wrapper--shadowed">
<input type="text" class="text-input form-field__control form-field--required" value="" v-model="selectedShortcut.url" id="url" />
</div>
<div class="form-field__error" v-if="selectedShortcut.url === ''"></div>
</div>
<div class="form-field form-field--error form-field--required mb-4">
<label class="form-field__label" for="code">Typ přesměrování</label>
<div class="form-field__wrapper form-field__wrapper--shadowed select">
<select v-model="selectedShortcut.code" class="select__control form-field__control ">
<option value="301">301 trvalé</option>
<option value="302">302 dočasné</option>
</select>
</div>
<div class="form-field__error" v-if="shortcut.url === ''"></div>
</div>
<button class="btn btn--grey-500 btn--hoveractive" @click.prevent="updateShortcut">
<div class="btn__body">Uložit změny</div>
</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="module">
const MAX_URL_LENGTH = 50;
const BASE_URL = "/api/shortcuts";
const API_HEADERS = {
"Content-Type": "application/json",
"Accept": "application/json",
"X-Auth-Token": "<%= current_user->token %>",
};
var app = new Vue({
el: '#App',
data: {
shortcuts: [],
deleteConfirmVisible: false,
shortcutInfoVisible: false,
shortcutEditVisible: false,
selectedShortcut: {},
shortcut: {},
formError: '',
},
methods: {
fetchData: function() {
fetch(BASE_URL, {
headers: API_HEADERS,
})
.then((res) => res.json())
.then(res => {
this.shortcuts = res;
})
},
addShortcut: function() {
fetch(BASE_URL, {
method: "POST",
headers: API_HEADERS,
body: JSON.stringify(this.shortcut),
})
.then( response => {
if ( response.status == 201 ) {
this.shortcut = {};
app.fetchData();
response.json().then(json => {
this.showInfo(json)
})
}
else {
response.json().then(json => {
this.formError = json.errors[0]['message']
})
}
})
.catch(() => {
this.formError = "ERROR_SERVERSIDE"
});
},
updateShortcut: function() {
fetch(BASE_URL + '/' + this.selectedShortcut.id, {
method: "PUT",
headers: API_HEADERS,
body: JSON.stringify(this.selectedShortcut),
})
.then( response => {
if ( response.status == 204 ) {
this.shortcutEditVisible = false;
app.fetchData();
}
else {
response.json().then(json => {
this.editError = json.errors[0]['message']
})
}
})
.catch(() => {
this.editError = "ERROR_SERVERSIDE"
});
},
deleteShortcut: function() {
if ( ! this.selectedShortcut ) {
return true;
}
fetch(BASE_URL + '/' + this.selectedShortcut.id, {
method: "DELETE",
headers: API_HEADERS,
})
.then( response => {
this.deleteConfirmVisible = false;
app.fetchData();
})
},
stripURL: function(url) {
if ( url.length > MAX_URL_LENGTH ) {
url = url.substring(0, MAX_URL_LENGTH) + '...';
}
return url;
},
formatTimestamp: function(timestamp) {
timestamp = new Date(timestamp);
return timestamp.toLocaleDateString('cs-CZ');
},
showDelete: function(shortcut) {
this.selectedShortcut = shortcut;
this.deleteConfirmVisible = true;
},
showInfo: function(shortcut) {
this.selectedShortcut.full_url = 'https://<%= config->{domain} %>/'+ shortcut.shortcut ;
this.shortcutInfoVisible = true;
navigator.clipboard.writeText(this.selectedShortcut.full_url);
},
showEdit: function(shortcut) {
this.selectedShortcut = shortcut;
this.shortcutEditVisible = true;
},
}
});
app.fetchData();
</script>