1
0
mirror of https://github.com/typemill/typemill.git synced 2025-07-25 00:02:28 +02:00

v2.13 improve responsive author interface

This commit is contained in:
trendschau
2025-01-17 22:49:55 +01:00
parent 5cc3d7f8ff
commit 4f8bb09d26
16 changed files with 215 additions and 122 deletions

View File

@@ -55,9 +55,10 @@ class SimpleMail
$send = mail($to, $subject, $message, $headers);
if($send !== true)
if ($send !== true)
{
$this->error = error_get_last()['message'];
$lastError = error_get_last();
$this->error = $lastError ? $lastError['message'] : 'Unknown error occurred while sending mail.';
}
return $send;

View File

@@ -12,7 +12,7 @@
<div class="px-12 py-8 bg-stone-50 dark:bg-stone-700 dark:text-stone-200">
{% for block in content %}
<div class="blox-preview px-6 py-3 mb-1">{{ block.html|raw }}</div>
<div class="blox-preview px-6 py-3 mb-1">{{ block.html|raw }}</div>
{% endfor %}
</div>
@@ -30,7 +30,7 @@
<div id="posts"></div>
<div id="publisher" class="fixed bottom-0 w-54rem bg-stone-100 border-t border-stone-200 shadow-md z-10" v-cloak></div>
<div id="publisher" class="fixed bottom-0 w-full lg:w-54rem bg-stone-100 border-t border-stone-200 shadow-md z-10" v-cloak></div>
{% endblock %}

View File

@@ -9,7 +9,7 @@
<div id="posts"></div>
<div id="publisher" class="fixed bottom-0 w-54rem bg-stone-100 border-t border-stone-200 shadow-md" v-cloak></div>
<div id="publisher" class="fixed bottom-0 w-full lg:w-54rem bg-stone-100 border-t border-stone-200 shadow-md" v-cloak></div>
{% endblock %}

View File

@@ -730,10 +730,6 @@ video {
float: right;
}
.float-left {
float: left;
}
.m-0 {
margin: 0px;
}
@@ -1086,6 +1082,10 @@ video {
width: 100%;
}
.w-48 {
width: 12rem;
}
.max-w-4xl {
max-width: 56rem;
}
@@ -1408,11 +1408,6 @@ video {
background-color: rgb(254 226 226 / var(--tw-bg-opacity));
}
.bg-rose-400 {
--tw-bg-opacity: 1;
background-color: rgb(251 113 133 / var(--tw-bg-opacity));
}
.bg-rose-500 {
--tw-bg-opacity: 1;
background-color: rgb(244 63 94 / var(--tw-bg-opacity));
@@ -1433,11 +1428,6 @@ video {
background-color: rgb(250 250 249 / var(--tw-bg-opacity));
}
.bg-stone-500 {
--tw-bg-opacity: 1;
background-color: rgb(120 113 108 / var(--tw-bg-opacity));
}
.bg-stone-600 {
--tw-bg-opacity: 1;
background-color: rgb(87 83 78 / var(--tw-bg-opacity));
@@ -2003,16 +1993,16 @@ video {
background-color: rgb(250 250 249 / var(--tw-bg-opacity));
}
.hover\:bg-stone-600:hover {
--tw-bg-opacity: 1;
background-color: rgb(87 83 78 / var(--tw-bg-opacity));
}
.hover\:bg-stone-700:hover {
--tw-bg-opacity: 1;
background-color: rgb(68 64 60 / var(--tw-bg-opacity));
}
.hover\:bg-stone-800:hover {
--tw-bg-opacity: 1;
background-color: rgb(41 37 36 / var(--tw-bg-opacity));
}
.hover\:bg-stone-900:hover {
--tw-bg-opacity: 1;
background-color: rgb(28 25 23 / var(--tw-bg-opacity));
@@ -2038,11 +2028,6 @@ video {
background-color: rgb(202 138 4 / var(--tw-bg-opacity));
}
.hover\:bg-stone-800:hover {
--tw-bg-opacity: 1;
background-color: rgb(41 37 36 / var(--tw-bg-opacity));
}
.hover\:text-stone-100:hover {
--tw-text-opacity: 1;
color: rgb(245 245 244 / var(--tw-text-opacity));
@@ -2321,6 +2306,19 @@ video {
}
@media (min-width: 1024px) {
.lg\:absolute {
position: absolute;
}
.lg\:right-0 {
right: 0px;
}
.lg\:my-8 {
margin-top: 2rem;
margin-bottom: 2rem;
}
.lg\:mr-2 {
margin-right: 0.5rem;
}
@@ -2329,6 +2327,14 @@ video {
margin-top: 0px;
}
.lg\:ml-2 {
margin-left: 0.5rem;
}
.lg\:mr-3 {
margin-right: 0.75rem;
}
.lg\:block {
display: block;
}
@@ -2341,6 +2347,10 @@ video {
display: flex;
}
.lg\:table-cell {
display: table-cell;
}
.lg\:hidden {
display: none;
}
@@ -2357,10 +2367,42 @@ video {
width: 75%;
}
.lg\:w-80 {
width: 20rem;
}
.lg\:w-half {
width: 48%;
}
.lg\:w-48 {
width: 12rem;
}
.lg\:w-2\/5 {
width: 40%;
}
.lg\:w-3\/5 {
width: 60%;
}
.lg\:w-1\/3 {
width: 33.333333%;
}
.lg\:w-24 {
width: 6rem;
}
.lg\:w-32 {
width: 8rem;
}
.lg\:w-54rem {
width: 54rem;
}
.lg\:flex-row {
flex-direction: row;
}
@@ -2383,6 +2425,26 @@ video {
padding-right: 1rem;
}
.lg\:px-12 {
padding-left: 3rem;
padding-right: 3rem;
}
.lg\:px-16 {
padding-left: 4rem;
padding-right: 4rem;
}
.lg\:py-16 {
padding-top: 4rem;
padding-bottom: 4rem;
}
.lg\:px-6 {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
.lg\:pb-3 {
padding-bottom: 0.75rem;
}
@@ -2391,6 +2453,14 @@ video {
padding-top: 1rem;
}
.lg\:pb-0 {
padding-bottom: 0px;
}
.lg\:pr-3 {
padding-right: 0.75rem;
}
.lg\:text-black {
--tw-text-opacity: 1;
color: rgb(0 0 0 / var(--tw-text-opacity));

View File

@@ -1,5 +1,5 @@
const bloxeditor = Vue.createApp({
template: `<div v-if="editorVisible" class="px-12 py-8 bg-stone-50 dark:bg-stone-700 dark:text-stone-200 shadow-md mb-16">
template: `<div v-if="editorVisible" class="px-2 lg:px-12 py-8 bg-stone-50 dark:bg-stone-700 dark:text-stone-200 shadow-md mb-16">
<draggable
v-model="content"
@start="onStart"
@@ -413,7 +413,7 @@ bloxeditor.component('new-block',{
props: ['markdown', 'index'],
template: `
<div class="w-full mb-4">
<div v-if="!componentType" class="w-full flex p-4 dark:bg-stone-900">
<div v-if="!componentType" class="w-full flex flex-wrap p-4 dark:bg-stone-900">
<button v-for="button in formats"
class="p-2 m-1 border border-stone-300 bg-stone-100 dark:border-stone-700 dark:bg-stone-700 hover:bg-stone-700 hover:dark:bg-stone-600 hover:text-stone-50 transition-1"
@click.prevent="setComponentType( $event, button.component )"

View File

@@ -1,18 +1,24 @@
const navigation = Vue.createApp({
template: `
<div class="mr-3 dark:text-stone-200">
<div class="flex w-100 mb-8">
<div class="lg:mr-3 dark:text-stone-200">
<div class="flex w-100 mb-8 hidden lg:block">
<button class="w-1/2 hover:bg-stone-700 hover:border-stone-700 hover:text-stone-50 border-b-2 border-stone-200 dark:border-stone-600 px-2 py-2 transition duration-100" @click.prevent="collapseNavigation()">{{ $filters.translate('collapse all') }}</button>
<button class="w-1/2 hover:bg-stone-700 hover:border-stone-700 hover:text-stone-50 border-b-2 border-stone-200 dark:border-stone-600 px-2 py-2 transition duration-100" @click.prevent="expandNavigation()">{{ $filters.translate('expand all') }}</button>
</div>
<div class="flex w-full my-px border-y border-stone-200 dark:border-stone-900 font-bold">
<div class="border-l-4" :class="getStatusClass(home.status)"></div>
<a :href="getUrl(home.urlRelWoF)" class="flex-grow p-1 pl-3 border-stone-50 hover:bg-teal-500 hover:text-stone-50 dark:hover:bg-stone-200 hover:dark:text-stone-900" :class="home.active ? 'text-stone-50 bg-teal-500 dark:bg-stone-200 dark:text-stone-900' : 'dark:bg-stone-700'">
{{ $filters.translate(home.name) }}
</a>
<button @click="togglemenue" class="lg:hidden w-full flex-1 flex items-center justify-center space-x-4 p-2 mb-2 bg-stone-700 hover:bg-stone-900 text-white cursor-pointer transition duration-100">
<span>{{ $filters.translate('Menu') }}</span>
<span :class="menuvisible ? 'border-b-8 border-b-white' : 'border-t-8 border-t-white'" class="h-0 w-0 border-x-8 border-x-transparent"></span>
</button>
<div class="lg:block" :class="menuvisible ? '' : 'hidden'">
<div class="flex w-full my-px border-y border-stone-200 dark:border-stone-900 font-bold">
<div class="border-l-4" :class="getStatusClass(home.status)"></div>
<a :href="getUrl(home.urlRelWoF)" class="flex-grow p-1 pl-3 border-stone-50 hover:bg-teal-500 hover:text-stone-50 dark:hover:bg-stone-200 hover:dark:text-stone-900" :class="home.active ? 'text-stone-50 bg-teal-500 dark:bg-stone-200 dark:text-stone-900' : 'dark:bg-stone-700'">
{{ $filters.translate(home.name) }}
</a>
</div>
<div class="pl-2 pl-3 pl-4 pl-6 pl-8 pl-9 pl-10 pl-12 pl-15 pl-18 pl-21 pl-24 text-stone-50"></div>
<navilevel :navigation="navigation" :expanded="expanded" />
</div>
<div class="pl-2 pl-3 pl-4 pl-6 pl-8 pl-9 pl-10 pl-12 pl-15 pl-18 pl-21 pl-24 text-stone-50"></div>
<navilevel :navigation="navigation" :expanded="expanded" />
</div>`,
data: function () {
return {
@@ -21,6 +27,7 @@ const navigation = Vue.createApp({
backup: false,
isExpended: false,
expanded: [],
menuvisible: false,
}
},
mounted: function(){
@@ -55,6 +62,17 @@ const navigation = Vue.createApp({
});
},
methods: {
togglemenue()
{
if(this.menuvisible)
{
this.menuvisible = false;
}
else
{
this.menuvisible = true;
}
},
getStatusClass(status)
{
if(status == 'published')

View File

@@ -303,7 +303,7 @@ app.component('component-date', {
template: `<div :class="css ? css : ''" class="w-full mt-5 mb-5">
<label :for="name" class="block mb-1 font-medium">{{ $filters.translate(label) }}</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<div class="absolute h-12 inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<svg aria-hidden="true" focusable="false" class="w-5 h-5 text-gray-500 dark:text-gray-400" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z" clip-rule="evenodd"></path>
</svg>
@@ -335,7 +335,7 @@ app.component('component-email', {
template: `<div :class="css ? css : ''" class="w-full mt-5 mb-5">
<label :for="name" class="block mb-1 font-medium">{{ $filters.translate(label) }}</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<div class="absolute h-12 inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<svg aria-hidden="true" focusable="false" class="w-5 h-5 text-gray-500 dark:text-gray-400" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884z"></path>
<path d="M18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z"></path>
@@ -369,7 +369,7 @@ app.component('component-tel', {
template: `<div :class="css ? css : ''" class="w-full mt-5 mb-5">
<label :for="name" class="block mb-1 font-medium">{{ $filters.translate(label) }}</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<div class="absolute h-12 inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<svg aria-hidden="true" focusable="false" class="w-5 h-5 text-gray-500 dark:text-gray-400" fill="currentColor" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<path d="M22 20c-2 2-2 4-4 4s-4-2-6-4-4-4-4-6 2-2 4-4-4-8-6-8-6 6-6 6c0 4 4.109 12.109 8 16s12 8 16 8c0 0 6-4 6-6s-6-8-8-6z"></path>
</svg>
@@ -402,7 +402,7 @@ app.component('component-url', {
template: `<div :class="css ? css : ''" class="w-full mt-5 mb-5">
<label :for="name" class="block mb-1 font-medium">{{ $filters.translate(label) }}</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<div class="absolute h-12 inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<svg aria-hidden="true" focusable="false" class="w-5 h-5 text-gray-500 dark:text-gray-400" fill="currentColor" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<path d="M13.757 19.868c-0.416 0-0.832-0.159-1.149-0.476-2.973-2.973-2.973-7.81 0-10.783l6-6c1.44-1.44 3.355-2.233 5.392-2.233s3.951 0.793 5.392 2.233c2.973 2.973 2.973 7.81 0 10.783l-2.743 2.743c-0.635 0.635-1.663 0.635-2.298 0s-0.635-1.663 0-2.298l2.743-2.743c1.706-1.706 1.706-4.481 0-6.187-0.826-0.826-1.925-1.281-3.094-1.281s-2.267 0.455-3.094 1.281l-6 6c-1.706 1.706-1.706 4.481 0 6.187 0.635 0.635 0.635 1.663 0 2.298-0.317 0.317-0.733 0.476-1.149 0.476z"></path>
<path d="M8 31.625c-2.037 0-3.952-0.793-5.392-2.233-2.973-2.973-2.973-7.81 0-10.783l2.743-2.743c0.635-0.635 1.664-0.635 2.298 0s0.635 1.663 0 2.298l-2.743 2.743c-1.706 1.706-1.706 4.481 0 6.187 0.826 0.826 1.925 1.281 3.094 1.281s2.267-0.455 3.094-1.281l6-6c1.706-1.706 1.706-4.481 0-6.187-0.635-0.635-0.635-1.663 0-2.298s1.663-0.635 2.298 0c2.973 2.973 2.973 7.81 0 10.783l-6 6c-1.44 1.44-3.355 2.233-5.392 2.233z"></path>
@@ -474,7 +474,7 @@ app.component('component-password', {
template: `<div :class="css ? css : ''" class="w-full mt-5 mb-5">
<label :for="name" class="block mb-1 font-medium">{{ $filters.translate(label) }}</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<div class="absolute h-12 inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<svg aria-hidden="true" focusable="false" class="w-5 h-5 text-gray-500 dark:text-gray-400" fill="currentColor" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<path d="M18.5 14h-0.5v-6c0-3.308-2.692-6-6-6h-4c-3.308 0-6 2.692-6 6v6h-0.5c-0.825 0-1.5 0.675-1.5 1.5v15c0 0.825 0.675 1.5 1.5 1.5h17c0.825 0 1.5-0.675 1.5-1.5v-15c0-0.825-0.675-1.5-1.5-1.5zM6 8c0-1.103 0.897-2 2-2h4c1.103 0 2 0.897 2 2v6h-8v-6z"></path>
</svg>
@@ -758,7 +758,7 @@ app.component('component-image', {
<label :for="name" class="block mb-1 font-medium">{{ $filters.translate(label) }}</label>
<div class="flex flex-wrap items-start">
<div class="lg:w-half w-full">
<div class="w-80 h-80 table-cell align-middle bg-chess">
<div class="w-full lg:w-80 h-80 mb-3 lg:table-cell align-middle bg-chess">
<img :src="imagepreview" class="max-w-xs max-h-80 table mx-auto">
</div>
</div>

View File

@@ -176,7 +176,7 @@ const kixoteCommands = [
const kixote = Vue.createApp({
template: `<div class="m-1 ml-2">
<button @click="startKixote" class="p-1 bg-stone-700 text-white text-xs">+ Kixote</button>
<button @click="startKixote" class="p-1 bg-stone-700 text-white text-xs">Kixote</button>
<div v-if="showKixote" ref="kdisplay" class="fixed z-50 mx-auto inset-x-0 w-full max-w-4xl bottom-3 top-3 overflow-y-auto bg-stone-700 text-stone-50 py-10">
<div class="px-8 pb-4">
<h1 class="mb-d3">Hello, I am <span class="text-teal-300">Kixote</span> from Typemill. How can I help?</h1>

View File

@@ -1,12 +1,12 @@
const app = Vue.createApp({
template: `<Transition name="initial" appear>
<div v-if="licenseData">
<div>
<div class="mb-8">
<p v-if="licensemessage" class="bg-rose-500 text-white p-2 text-center">{{ licensemessage }}</p>
<p v-else>Congratulations! Your license is active and you can enjoy all features until you cancel your subscription. To manage your subscription, visit the <a class="text-teal-500" href="https://customer-portal.paddle.com/cpl_01hp3wph3gzps14ae3qcfypnyp">Paddle Customer Portal</a>. Simply enter the email associated with your license to receive a temporary login link.</p>
</div>
<div class="flex flex-wrap justify-between">
<div class="w-2/5 text-white bg-teal-500 border-2 border-stone-200 my-8 flex flex-col">
<div class="lg:flex flex-wrap justify-between">
<div class="lg:w-2/5 w-full text-white bg-teal-500 border-2 border-stone-200 flex flex-col">
<div v-if="licenseData.plan == 'MAKER'" class="p-8">
<h2 class="text-2xl font-bold mb-3">MAKER License</h2>
<p class="py-2 text-lg"><strong>22 €</strong> + VAT/Year. Ideal for personal projects and side hustles.</p>
@@ -26,7 +26,7 @@ const app = Vue.createApp({
</ul>
</div>
</div>
<div class="w-3/5 border-2 border-stone-200 p-8 my-8">
<div class="lg:w-3/5 w-full border-2 border-stone-200 p-8">
<p class="mb-1 font-medium">License-key:</p>
<p class="w-full border p-2 bg-stone-100">{{ licenseData.license }}</p>
<p class="mb-1 mt-3 font-medium">Domain:</p>
@@ -37,13 +37,12 @@ const app = Vue.createApp({
<p class="w-full border p-2 bg-stone-100">{{ licenseData.payed_until }}</p>
</div>
</div>
<p class="py-2 text-lg">The subscription extends automatically for 12 month every time until you cancel your subscription. For testing, you can also use the domains 'localhost', '127.0.0.1', and the subdomain 'typemilltest.'.</p>
<p class="py-2 text-lg mt-8">The subscription extends automatically for 12 month every time until you cancel your subscription. For testing, you can also use the domains 'localhost', '127.0.0.1', and the subdomain 'typemilltest.'.</p>
</div>
<form v-else class="inline-block w-full">
<div>
<p>Activate your Typemill-License below and enjoy a flatrate-subscription for plugins, themes, and services.</p>
<p>You do not have a License yet? Read all about it on the <a class="text-teal-500" href="https://typemill.net/license">Typemill website</a>.</p>
<p>Activate your Typemill-License below and enjoy a flatrate-subscription for plugins, themes, and services. You do not have a License yet? Read all about it on the <a class="text-teal-500" href="https://typemill.net/license">Typemill website</a>.</p>
</div>
<div v-for="(fieldDefinition, fieldname) in formDefinitions">

View File

@@ -36,7 +36,7 @@ const app = Vue.createApp({
formErrorsReset: {},
message: false,
messageClass: false,
css: "px-16 py-16 bg-stone-50 shadow-md mb-16",
css: "lg:px-16 px-8 lg:py-16 py-8 bg-stone-50 shadow-md mb-16",
saved: false,
}
},

View File

@@ -2,16 +2,16 @@ const publisher = Vue.createApp({
template: `
<div id="publishController" class="text-sm" v-cloak>
<div v-if="message" :class="messageClass" class="block w-full px-3 py-1 text-white transition duration-100">{{ message }}</div>
<div class="flex justify-between px-6 py-3 dark:bg-stone-900">
<div class="flex justify-between lg:px-6 px-3 py-3 dark:bg-stone-900">
<div class="flex">
<div class="border-l-4 w-32 px-2 py-2 dark:text-stone-200" :class="getStatusClass(item.status)">
{{ $filters.translate(item.status) }}
<div class="border-l-4 lg:w-32 px-2 py-2 dark:text-stone-200" :class="getStatusClass(item.status)">
<span class="hidden lg:block">{{ $filters.translate(item.status) }}</span>
</div>
<button
v-if="raw"
@click.prevent="saveDraft"
:disabled="nochanges"
class="cursor-pointer ml-1 w-24 px-4 py-2 border dark:border-0 border-stone-200 text-white disabled:bg-stone-200 disabled:text-stone-900 disabled:dark:bg-stone-600 disabled:dark:text-stone-200 disabled:cursor-not-allowed transition"
class="cursor-pointer ml-1 lg:w-24 lg:px-4 px-2 py-2 border dark:border-0 border-stone-200 text-white disabled:bg-stone-200 disabled:text-stone-900 disabled:dark:bg-stone-600 disabled:dark:text-stone-200 disabled:cursor-not-allowed transition"
:class="publishClass"
>
{{ $filters.translate('draft') }}
@@ -20,7 +20,7 @@ const publisher = Vue.createApp({
v-if="raw"
@click.prevent="publishDraft"
:disabled="nopublish"
class="cursor-pointer ml-1 w-24 px-4 py-2 border dark:border-0 border-stone-200 text-white disabled:bg-stone-200 disabled:text-stone-900 disabled:dark:bg-stone-600 disabled:dark:text-stone-200 disabled:cursor-not-allowed transition"
class="cursor-pointer ml-1 lg:w-24 lg:px-4 px-2 py-2 border dark:border-0 border-stone-200 text-white disabled:bg-stone-200 disabled:text-stone-900 disabled:dark:bg-stone-600 disabled:dark:text-stone-200 disabled:cursor-not-allowed transition"
:class="publishClass"
>
{{ $filters.translate('publish') }}
@@ -29,7 +29,7 @@ const publisher = Vue.createApp({
v-if="visual"
@click.prevent="publishArticle"
:disabled="isPublished"
class="cursor-pointer ml-1 w-24 px-4 py-2 border dark:border-0 border-stone-200 text-white disabled:bg-stone-200 disabled:text-stone-900 disabled:dark:bg-stone-600 disabled:dark:text-stone-200 disabled:cursor-not-allowed transition"
class="cursor-pointer ml-1 lg:w-24 lg:px-4 px-2 py-2 border dark:border-0 border-stone-200 text-white disabled:bg-stone-200 disabled:text-stone-900 disabled:dark:bg-stone-600 disabled:dark:text-stone-200 disabled:cursor-not-allowed transition"
:class="publishClass"
>
{{ $filters.translate('publish') }}
@@ -37,7 +37,7 @@ const publisher = Vue.createApp({
<button
@click.prevent="showModal = 'discard'"
:disabled="!isModified"
class="cursor-pointer ml-1 w-24 px-4 py-2 border dark:border-0 border-stone-200 text-white bg-yellow-500 hover:bg-yellow-600 disabled:bg-stone-200 disabled:text-stone-900 disabled:dark:bg-stone-600 disabled:dark:text-stone-200 disabled:cursor-not-allowed transition"
class="cursor-pointer ml-1 lg:w-24 lg:px-4 px-2 py-2 border dark:border-0 border-stone-200 text-white bg-yellow-500 hover:bg-yellow-600 disabled:bg-stone-200 disabled:text-stone-900 disabled:dark:bg-stone-600 disabled:dark:text-stone-200 disabled:cursor-not-allowed transition"
>
{{ $filters.translate('discard') }}
</button>
@@ -45,14 +45,14 @@ const publisher = Vue.createApp({
v-if="item.originalName != 'home'"
@click.prevent="checkUnpublish"
:disabled="isUnpublished"
class="cursor-pointer ml-1 w-24 px-4 py-2 border dark:border-0 border-stone-200 text-white bg-teal-500 hover:bg-teal-600 disabled:bg-stone-200 disabled:text-stone-900 disabled:dark:bg-stone-600 disabled:dark:text-stone-200 disabled:cursor-not-allowed transition"
class="cursor-pointer ml-1 lg:w-24 lg:px-4 px-2 py-2 border dark:border-0 border-stone-200 text-white bg-teal-500 hover:bg-teal-600 disabled:bg-stone-200 disabled:text-stone-900 disabled:dark:bg-stone-600 disabled:dark:text-stone-200 disabled:cursor-not-allowed transition"
>
{{ $filters.translate('unpublish') }}
</button>
<button
v-if="item.originalName != 'home'"
@click.prevent="showModal = 'delete'"
class="cursor-pointer ml-1 w-24 px-4 py-2 border dark:border-0 border-stone-200 bg-stone-50 hover:bg-rose-500 hover:text-white transition"
class="cursor-pointer ml-1 lg:w-24 lg:px-4 px-2 py-2 border dark:border-0 border-stone-200 bg-stone-50 hover:bg-rose-500 hover:text-white transition"
>
{{ $filters.translate('delete') }}
</button>
@@ -77,7 +77,7 @@ const publisher = Vue.createApp({
<a
:href="item.urlAbs"
target="_blank"
class="px-4 py-2 border border-stone-200 bg-stone-50 hover:bg-stone-700 hover:text-white transition ml-1"
class="lg:px-4 px-2 py-2 border border-stone-200 bg-stone-50 hover:bg-stone-700 hover:text-white transition ml-1"
>
<svg class="icon baseline icon-external-link">
<use xlink:href="#icon-external-link"></use>

View File

@@ -1,6 +1,6 @@
const raweditor = Vue.createApp({
template: `
<fieldset v-if="showraw" class="px-12 py-8 bg-stone-50 dark:bg-stone-700 dark:text-stone-200 shadow-md mb-16">
<fieldset v-if="showraw" class="lg:px-12 py-8 bg-stone-50 dark:bg-stone-700 dark:text-stone-200 shadow-md mb-16">
<div class="w-full px-6 py-3" :class="{'error' : errors.title}">
<label class="block mb-1 font-medium" for="title">{{ $filters.translate('Title') }}*</label>
<input

View File

@@ -19,8 +19,7 @@ const app = Vue.createApp({
v-bind="subfieldDefinition">
<slot v-if="fieldname == 'mailfrom'">
<button
class = "absolute px-2 py-3 ml-2 text-stone-50 bg-stone-700 hover:bg-stone-900 hover:text-white transition duration-100 cursor-pointer"
style = "right:0px; width:200px;"
class = "lg:absolute lg:right-0 lg:w-48 lg:ml-2 lg:mt-0 w-full px-2 py-3 mt-2 text-stone-50 bg-stone-700 hover:bg-stone-900 hover:text-white transition duration-100 cursor-pointer"
@click.prevent = "testmail()"
>send testmail</button>
</slot>

View File

@@ -1,6 +1,5 @@
const systemnavi = Vue.createApp({
template: `
<ul class="lg:mr-2">
template: `<ul class="lg:mr-2">
<button @click="toggle" class="lg:hidden w-full flex-1 flex items-center justify-center space-x-4 p-2 mb-2 bg-stone-700 hover:bg-stone-900 text-white cursor-pointer transition duration-100">
<span>{{ $filters.translate('Menu') }}</span>
<span :class="expanded ? 'border-b-8 border-b-white' : 'border-t-8 border-t-white'" class="h-0 w-0 border-x-8 border-x-transparent"></span>
@@ -12,8 +11,7 @@ const systemnavi = Vue.createApp({
</a>
</li>
</div>
</ul>
`,
</ul>`,
data() {
return {
systemnavi: data.systemnavi,

View File

@@ -16,7 +16,7 @@ const app = Vue.createApp({
</div>
<div class="w-full p-8">
<div class="lg:flex pb-4">
<div class="lg:w-1/2 w-full">
<div class="lg:w-1/2 w-full lg:pr-3 lg:pb-0 pb-3">
<h2 class="text-xl font-bold mb-3">{{theme.name}}</h2>
<div class="text-xs my-3">author: <a :href="theme.homepage" class="hover:underline text-teal-500">{{theme.author}}</a> | version: {{theme.version}}</div>
<p>{{theme.description}}</p>
@@ -37,52 +37,60 @@ const app = Vue.createApp({
<form class="w-full p-8" v-if="current == themename">
<div v-if="theme.readymades">
<fieldset class="block border-2 border-stone-200 p-4 my-8">
<legend class="text-lg font-medium">Readymades</legend>
<p class="w-full mb p-2">Readymades are predefined settings. Store your own readymades or load readymades to quickly setup your theme.</p>
<ul>
<transition-group name="fade" tag="ul" class="flex flex-wrap">
<li class="w-1/3 p-2 fade-item" v-for="(readysetup,readyname) in theme.readymades" :key="readyname">
<div class="border-2 border-stone-200 hover:shadow-lg transition duration-100 ease-in-out">
<div class="w-full font-medium p-2 text-center bg-stone-200" :class="{ 'bg-teal-500 text-stone-50': readyname === readymadeCurrent }">{{ readysetup.name }}</div>
<div class="p-3 h-40">
<p>{{ readysetup.description }}</p>
</div>
<div v-if="readysetup.delete" class="mt-auto w-full flex">
<button v-if="readysetup.delete" class="w-1/2 p-2 text-center bg-rose-500 text-stone-50 hover:bg-rose-600"
@click.prevent="deleteReadymade(readyname)"
>delete</button>
<button class="w-1/2 p-2 bg-stone-700 text-white text-center hover:bg-stone-900"
@click.prevent="loadReadymade(readyname)"
>load</button>
</div>
<div v-else class="mt-auto w-full">
<button class="p-2 w-full bg-stone-700 text-white text-center hover:bg-stone-900"
@click.prevent="loadReadymade(readyname)"
>load</button>
</div>
</div>
</li>
<li class="w-1/3 p-2" :key="'addnewreadymade'">
<div class="flex flex-col border-2 border-stone-200 hover:shadow-lg transition duration-100 ease-in-out">
<input
type = "text"
v-model = "readymadeTitle"
@input = "checkTitle()"
placeholder = "Add a title"
class = "w-full font-medium p-2 text-center bg-stone-200">
<textarea
v-model = "readymadeDescription"
class = "p-3 h-40"
@input = "checkDescription()"
placeholder = "Add a description and store the current settings as a new readymade."></textarea>
<button class="p-2 w-full bg-stone-700 text-white text-center hover:bg-stone-900"
@click.prevent="storeReadymade()"
>store as readymade</button>
</div>
</li>
</transition-group>
</ul>
<div v-if="readymadeError" class="w-100 p-2 m-2 text-stone-50 text-center bg-rose-500">{{ readymadeError }}</div>
<div @click="toggleAccordion('readymades')" class="flex justify-between w-full py-2 text-lg font-medium cursor-pointer">
<h3>Readymades</h3>
<span class="mt-2 h-0 w-0 border-x-8 border-x-transparent" :class="isOpen(fieldname) ? 'border-b-8 border-b-black' : 'border-t-8 border-t-black'"></span>
</div>
<transition name="accordion">
<div v-if="isOpen('readymades')" class="w-full accordion-content flex flex-wrap justify-between">
<p class="w-full mb p-2">Readymades are predefined settings. Store your own readymades or load readymades to quickly setup your theme.</p>
<ul>
<transition-group name="fade" tag="ul" class="lg:flex flex-wrap">
<li class="w-full lg:w-1/3 p-2 fade-item" v-for="(readysetup,readyname) in theme.readymades" :key="readyname">
<div class="border-2 border-stone-200 hover:shadow-lg transition duration-100 ease-in-out">
<div class="w-full font-medium p-2 text-center bg-stone-200" :class="{ 'bg-teal-500 text-stone-50': readyname === readymadeCurrent }">{{ readysetup.name }}</div>
<div class="p-3 h-40">
<p>{{ readysetup.description }}</p>
</div>
<div v-if="readysetup.delete" class="mt-auto w-full flex">
<button v-if="readysetup.delete" class="w-1/2 p-2 text-center bg-rose-500 text-stone-50 hover:bg-rose-600"
@click.prevent="deleteReadymade(readyname)"
>delete</button>
<button class="w-1/2 p-2 bg-stone-700 text-white text-center hover:bg-stone-900"
@click.prevent="loadReadymade(readyname)"
>load</button>
</div>
<div v-else class="mt-auto w-full">
<button class="p-2 w-full bg-stone-700 text-white text-center hover:bg-stone-900"
@click.prevent="loadReadymade(readyname)"
>load</button>
</div>
</div>
</li>
<li class="w-full lg:w-1/3 p-2" :key="'addnewreadymade'">
<div class="flex flex-col border-2 border-stone-200 hover:shadow-lg transition duration-100 ease-in-out">
<input
type = "text"
v-model = "readymadeTitle"
@input = "checkTitle()"
placeholder = "Add a title"
class = "w-full font-medium p-2 text-center bg-stone-200">
<textarea
v-model = "readymadeDescription"
class = "p-3 h-40"
@input = "checkDescription()"
placeholder = "Add a description and store the current settings as a new readymade."></textarea>
<button class="p-2 w-full bg-stone-700 text-white text-center hover:bg-stone-900"
@click.prevent="storeReadymade()"
>store as readymade</button>
</div>
</li>
</transition-group>
</ul>
<div v-if="readymadeError" class="w-100 p-2 m-2 text-stone-50 text-center bg-rose-500">{{ readymadeError }}</div>
</div>
</transition>
</fieldset>
</div>
<div v-for="(fieldDefinition, fieldname) in theme.forms.fields">

View File

@@ -34,11 +34,11 @@
{% include 'partials/flash.twig' %}
<div class="max-w-6xl m-auto mt-7 flex justify-between items-start" id="main" data-url="{{ base_url() }}">
<aside class="w-1/4">
<div class="max-w-6xl m-auto mt-7 lg:flex justify-between items-start" id="main" data-url="{{ base_url() }}">
<aside class="lg:w-1/4 w-full">
<div id="contentNavigation" v-cloak></div>
</aside>
<article class="relative w-3/4">
<article class="relative lg:w-3/4 w-full">
{% block content %}{% endblock %}
</article>
</div>