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:
@@ -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;
|
||||
|
@@ -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 %}
|
||||
|
||||
|
@@ -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 %}
|
||||
|
||||
|
@@ -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));
|
||||
|
@@ -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 )"
|
||||
|
@@ -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')
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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">
|
||||
|
@@ -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,
|
||||
}
|
||||
},
|
||||
|
@@ -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>
|
||||
|
@@ -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
|
||||
|
@@ -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>
|
||||
|
@@ -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,
|
||||
|
@@ -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">
|
||||
|
@@ -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>
|
||||
|
Reference in New Issue
Block a user