mango-cms 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/bin/mango +4 -0
- package/frontend-starter/README.md +8 -0
- package/frontend-starter/dist/_redirects +1 -0
- package/frontend-starter/dist/assets/index.00922bd5.js +99 -0
- package/frontend-starter/dist/assets/index.1781f175.css +1 -0
- package/frontend-starter/dist/favicon.png +0 -0
- package/frontend-starter/dist/index.html +53 -0
- package/frontend-starter/dist/index.js +66 -0
- package/frontend-starter/index.html +25 -0
- package/frontend-starter/index.js +197 -0
- package/frontend-starter/package-lock.json +5454 -0
- package/frontend-starter/package.json +40 -0
- package/frontend-starter/postcss.config.js +6 -0
- package/frontend-starter/public/_redirects +1 -0
- package/frontend-starter/public/favicon.png +0 -0
- package/frontend-starter/public/index.js +66 -0
- package/frontend-starter/src/App.vue +27 -0
- package/frontend-starter/src/components/layout/login.vue +212 -0
- package/frontend-starter/src/components/layout/modal.vue +113 -0
- package/frontend-starter/src/components/layout/spinner.vue +17 -0
- package/frontend-starter/src/components/pages/404.vue +28 -0
- package/frontend-starter/src/components/pages/home.vue +74 -0
- package/frontend-starter/src/components/partials/button.vue +31 -0
- package/frontend-starter/src/helpers/Mango.vue +455 -0
- package/frontend-starter/src/helpers/breakpoints.js +34 -0
- package/frontend-starter/src/helpers/darkMode.js +38 -0
- package/frontend-starter/src/helpers/email.js +32 -0
- package/frontend-starter/src/helpers/formatPhone.js +18 -0
- package/frontend-starter/src/helpers/localDB.js +315 -0
- package/frontend-starter/src/helpers/mango.js +338 -0
- package/frontend-starter/src/helpers/model.js +9 -0
- package/frontend-starter/src/helpers/multiSelect.vue +252 -0
- package/frontend-starter/src/helpers/pills.vue +75 -0
- package/frontend-starter/src/helpers/reconnecting-websocket.js +357 -0
- package/frontend-starter/src/helpers/uploadFile.vue +157 -0
- package/frontend-starter/src/helpers/uploadFiles.vue +100 -0
- package/frontend-starter/src/helpers/uploadImages.vue +89 -0
- package/frontend-starter/src/helpers/user.js +40 -0
- package/frontend-starter/src/index.css +281 -0
- package/frontend-starter/src/main.js +145 -0
- package/frontend-starter/tailwind.config.js +46 -0
- package/frontend-starter/vite.config.js +10 -0
- package/frontend-starter/yarn.lock +3380 -0
- package/mango-cms-0.0.13.tgz +0 -0
- package/package.json +24 -0
- package/src/cli.js +93 -0
- package/src/default-config/automation/index.js +37 -0
- package/src/default-config/collections/examples.js +60 -0
- package/src/default-config/config/.collections.json +1 -0
- package/src/default-config/config/globalFields.js +15 -0
- package/src/default-config/config/settings.json +23 -0
- package/src/default-config/config/statuses.js +0 -0
- package/src/default-config/config/users.js +35 -0
- package/src/default-config/endpoints/index.js +19 -0
- package/src/default-config/fields/vimeo.js +36 -0
- package/src/default-config/hooks/test.js +5 -0
- package/src/default-config/plugins/mango-stand/index.js +206 -0
- package/src/main.js +278 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<label :for="_uid" :uploading="uploading" :error="error" :url="url" :class="{'block relative border-2 border-transparent': showProgress}" ref="container">
|
|
3
|
+
|
|
4
|
+
<svg class="absolute -left-[2px] -top-[2px] z-50 w-[calc(100%+4px)] h-[calc(100%+4px)]" :style="progressRingStyle" v-if="progress">
|
|
5
|
+
<!-- <circle class="progress-ring__circle" stroke="green" stroke-width="4" fill="transparent" r="58" cx="60" cy="60"/> -->
|
|
6
|
+
<circle class="progress-ring__circle" stroke="#22c55e" :stroke-width="progressWidth" fill="transparent" :r="radius" :cx="containerSize/2" :cy="containerSize/2" :style="progressRingStyle"/>
|
|
7
|
+
</svg>
|
|
8
|
+
|
|
9
|
+
<button type="button" v-if="showDelete" @click.stop.prevent="url = null; $emit('url', null)" class="absolute -top-1 -right-1 w-[0.9rem] h-[0.9rem] rounded-full border-2 border-black/50 dark:bg-red-900 bg-red-500 flex items-center justify-center text-4xs font-bold z-50">
|
|
10
|
+
<span class=""><i class="fa fa-times opacity-50"/></span>
|
|
11
|
+
</button>
|
|
12
|
+
|
|
13
|
+
<slot :progress="progress" />
|
|
14
|
+
|
|
15
|
+
<input
|
|
16
|
+
:id="_uid"
|
|
17
|
+
hidden
|
|
18
|
+
type="file"
|
|
19
|
+
:accept="accept"
|
|
20
|
+
@change="upload"
|
|
21
|
+
/>
|
|
22
|
+
</label>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<script>
|
|
26
|
+
import Compress from 'compress.js'
|
|
27
|
+
const compress = new Compress()
|
|
28
|
+
// import Modernizr from 'modernizr'
|
|
29
|
+
|
|
30
|
+
export default {
|
|
31
|
+
props: {
|
|
32
|
+
accept: {type: String, default: 'image/png, image/jpeg, image/heic'},
|
|
33
|
+
showProgress: {type: Boolean, default: true},
|
|
34
|
+
miultiple: {type: Boolean, default: true},
|
|
35
|
+
showDelete: {type: Boolean, default: true},
|
|
36
|
+
},
|
|
37
|
+
data() {
|
|
38
|
+
return {
|
|
39
|
+
_uid: Math.random().toString(36).substr(2, 10),
|
|
40
|
+
uploading: false,
|
|
41
|
+
error: false,
|
|
42
|
+
url: null,
|
|
43
|
+
progress: 0,
|
|
44
|
+
filename: null,
|
|
45
|
+
containerSize: 0,
|
|
46
|
+
progressWidth: 2,
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
watch: {
|
|
50
|
+
uploading() { this.$emit('uploading', this.uploading) },
|
|
51
|
+
error() { this.$emit('error', this.error) },
|
|
52
|
+
url() { this.$emit('url', this.url) },
|
|
53
|
+
filename() { this.$emit('filename', this.filename) },
|
|
54
|
+
// progress() { this.$emit('progress', this.progress) },
|
|
55
|
+
},
|
|
56
|
+
mounted() {
|
|
57
|
+
this.$nextTick(() => {
|
|
58
|
+
this.containerSize = this.$refs.container.offsetWidth;
|
|
59
|
+
})
|
|
60
|
+
},
|
|
61
|
+
computed: {
|
|
62
|
+
radius() {
|
|
63
|
+
return ((this.containerSize / 2)-(this.progressWidth/2)) || 0; // Subtract the stroke width
|
|
64
|
+
},
|
|
65
|
+
progressRingStyle() {
|
|
66
|
+
const circumference = 2 * Math.PI * this.radius;
|
|
67
|
+
const offset = circumference - (this.progress / 100) * circumference;
|
|
68
|
+
return {
|
|
69
|
+
strokeDasharray: `${circumference} ${circumference}`,
|
|
70
|
+
strokeDashoffset: offset,
|
|
71
|
+
};
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
methods: {
|
|
75
|
+
async upload(event) {
|
|
76
|
+
|
|
77
|
+
let file = event.target.files[0]
|
|
78
|
+
const formData = new FormData()
|
|
79
|
+
|
|
80
|
+
this.uploading = true
|
|
81
|
+
this.filename = file.name
|
|
82
|
+
|
|
83
|
+
// // Use Modernizr to detect if exit-orientation is supported.
|
|
84
|
+
// const browserSupportsExifOrientation = () => {
|
|
85
|
+
// return new Promise((resolve) => Modernizr.on("exiforientation", resolve));
|
|
86
|
+
// };
|
|
87
|
+
|
|
88
|
+
// // Only rotate if browser does not support exit orientation.
|
|
89
|
+
// const shouldRotate = async () => {
|
|
90
|
+
// const supported = await browserSupportsExifOrientation();
|
|
91
|
+
// return !supported;
|
|
92
|
+
// };
|
|
93
|
+
|
|
94
|
+
// const rotate = await shouldRotate();
|
|
95
|
+
|
|
96
|
+
// Compress the image
|
|
97
|
+
if (file.type.includes('image')) {
|
|
98
|
+
let results = await compress.compress([file], {
|
|
99
|
+
quality: .75, // the quality of the image, max is 1,
|
|
100
|
+
maxWidth: 1920, // the max width of the output image, defaults to 1920px
|
|
101
|
+
maxHeight: 1920, // the max height of the output image, defaults to 1920px
|
|
102
|
+
resize: true, // defaults to true, set false if you do not want to resize the image width and height
|
|
103
|
+
rotate: false, // See the rotation section below
|
|
104
|
+
})
|
|
105
|
+
const img1 = results[0]
|
|
106
|
+
const base64str = img1.data
|
|
107
|
+
const imgExt = img1.ext
|
|
108
|
+
const filename = file.name
|
|
109
|
+
file = Compress.convertBase64ToFile(base64str, imgExt)
|
|
110
|
+
file = new File([file], filename, { type: file.type });
|
|
111
|
+
console.log('file', file)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
formData.append('file', file)
|
|
115
|
+
|
|
116
|
+
const xhr = new XMLHttpRequest()
|
|
117
|
+
|
|
118
|
+
xhr.open('POST', 'https://api.churchandfamilylife.com/upload', true)
|
|
119
|
+
|
|
120
|
+
xhr.upload.onprogress = (event) => {
|
|
121
|
+
if (event.lengthComputable) {
|
|
122
|
+
this.progress = (event.loaded / event.total) * 100
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
xhr.onload = () => {
|
|
127
|
+
if (xhr.status === 200) {
|
|
128
|
+
const json = JSON.parse(xhr.response)
|
|
129
|
+
const path = json.paths[0]
|
|
130
|
+
const url = `https://api.churchandfamilylife.com` + path
|
|
131
|
+
this.uploading = false
|
|
132
|
+
this.url = url
|
|
133
|
+
this.progress = 0
|
|
134
|
+
} else {
|
|
135
|
+
this.error = 'Error while uploading file'
|
|
136
|
+
this.uploading = false
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
xhr.onerror = () => {
|
|
141
|
+
this.error = 'Error while uploading file'
|
|
142
|
+
this.uploading = false
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
xhr.send(formData)
|
|
146
|
+
},
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
</script>
|
|
150
|
+
|
|
151
|
+
<style scoped>
|
|
152
|
+
.progress-ring__circle {
|
|
153
|
+
transition: stroke-dashoffset 0.35s;
|
|
154
|
+
transform: rotate(-90deg);
|
|
155
|
+
transform-origin: 50% 50%;
|
|
156
|
+
}
|
|
157
|
+
</style>
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
|
|
3
|
+
<div class="p-4 rounded-lg bg-gray-100 dark:bg-gray-800/50 w-full space-y-4">
|
|
4
|
+
<div class="font-semibold uppercase tracking-widest text-gray-500/50 text-sm">Documents</div>
|
|
5
|
+
<div class="w-full grid grid-cols-4 gap-2">
|
|
6
|
+
|
|
7
|
+
<Draggable v-model="sortableDocuments" v-if="sortableDocuments.length" item-key="id" class="w-full grid grid-cols-4 gap-2 col-span-4" >
|
|
8
|
+
<template #item="{element:document}">
|
|
9
|
+
<div class="bg-center bg-cover w-full aspect-square shrink-0 overflow-hidden rounded relative group border-4">
|
|
10
|
+
<div class="absolute inset-0 flex flex-col space-y-4 items-center justify-center">
|
|
11
|
+
<i class="fa fa-file-alt text-xl sm:text-3xl" />
|
|
12
|
+
<div class="text-xs md:text-sm lg:text-base">{{ document.name }}</div>
|
|
13
|
+
</div>
|
|
14
|
+
<div class="bg-black/50 absolute h-full top-0 right-0" :style="`width: ${100-document?.progress}%;`" />
|
|
15
|
+
<button @click="removeDocument(document)" class="w-full h-full hidden group-hover:flex absolute backdrop-blur items-center justify-center">
|
|
16
|
+
<i class="fa fa-trash-alt text-3xl text-red-800" />
|
|
17
|
+
</button>
|
|
18
|
+
</div>
|
|
19
|
+
</template>
|
|
20
|
+
</Draggable>
|
|
21
|
+
|
|
22
|
+
<FileUpload
|
|
23
|
+
ref="upload"
|
|
24
|
+
v-model="documents"
|
|
25
|
+
key="documents"
|
|
26
|
+
input-id="documents"
|
|
27
|
+
:post-action="`${api}/upload`"
|
|
28
|
+
:drop="true"
|
|
29
|
+
:multiple="true"
|
|
30
|
+
:drop-directory="true"
|
|
31
|
+
class="w-full aspect-square border-2 dark:border-gray-600 bg-gray-300 dark:bg-gray-800 block cursor-pointer relative rounded"
|
|
32
|
+
>
|
|
33
|
+
<div class="w-full h-full flex items-center justify-center">
|
|
34
|
+
<i class="fad fa-file-alt text-3xl dark:text-gray-700" />
|
|
35
|
+
</div>
|
|
36
|
+
<div class="w-full h-full hidden group-hover:flex absolute backdrop-blur items-center justify-center">
|
|
37
|
+
<i class="fa fa-pencil text-3xl text-gray-800" />
|
|
38
|
+
</div>
|
|
39
|
+
</FileUpload>
|
|
40
|
+
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
</template>
|
|
45
|
+
|
|
46
|
+
<script>
|
|
47
|
+
import FileUpload from 'vue-upload-component'
|
|
48
|
+
import Draggable from 'vuedraggable'
|
|
49
|
+
import { useModel } from './model'
|
|
50
|
+
|
|
51
|
+
export default {
|
|
52
|
+
components: {FileUpload, Draggable},
|
|
53
|
+
inject: ['axios','api'],
|
|
54
|
+
props: ['modelValue'],
|
|
55
|
+
data() {
|
|
56
|
+
return {
|
|
57
|
+
// documents: [],
|
|
58
|
+
sortableDocuments: [],
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
setup(props, { emit }) {
|
|
62
|
+
return {
|
|
63
|
+
documents: useModel(props, emit, 'modelValue')
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
watch: {
|
|
67
|
+
documents: {
|
|
68
|
+
handler() {
|
|
69
|
+
this.sortableDocuments = this.documents?.map(i => ({id:i?.id, url:i?.url, name: i.name})) || []
|
|
70
|
+
|
|
71
|
+
let documentsToUpload = this.documents?.filter(i => i.file) || []
|
|
72
|
+
if (this.$refs.upload) this.$refs.upload.active = true
|
|
73
|
+
documentsToUpload.forEach(i => i.blob = i.blob ? i.blob : URL.createObjectURL(i.file))
|
|
74
|
+
},
|
|
75
|
+
deep: true,
|
|
76
|
+
immediate: true
|
|
77
|
+
},
|
|
78
|
+
urls() {
|
|
79
|
+
this.$emit('urls', this.urls)
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
computed: {
|
|
83
|
+
done() {
|
|
84
|
+
return this.documents.every(i => i.progress == 100)
|
|
85
|
+
},
|
|
86
|
+
urls() {
|
|
87
|
+
return this.sortableDocuments.map(document => document.url ? document : this.documents?.find(i => i.id == document.id)?.response?.paths?.[0])
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
methods: {
|
|
91
|
+
removeDocument(document) {
|
|
92
|
+
let id = document?.id
|
|
93
|
+
let index = id ? this.documents?.findIndex(i => i.id == id) : this.documents?.findIndex(i => i.url == document.url)
|
|
94
|
+
console.log('index', index)
|
|
95
|
+
if (isNaN(index)) return
|
|
96
|
+
this.documents.splice(index,1)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
</script>
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
|
|
3
|
+
<div class="p-4 rounded-lg bg-gray-100 dark:bg-gray-800/50 w-full space-y-4">
|
|
4
|
+
<div class="font-semibold uppercase tracking-widest text-gray-500/50 text-sm">Images</div>
|
|
5
|
+
<div class="w-full grid grid-cols-4 gap-2">
|
|
6
|
+
|
|
7
|
+
<Draggable v-model="sortableImages" v-if="sortableImages.length" item-key="id" class="w-full grid grid-cols-4 gap-2 col-span-4" >
|
|
8
|
+
<template #item="{element:id}">
|
|
9
|
+
<div class="bg-center bg-cover w-full aspect-square shrink-0 overflow-hidden rounded relative group" :style="`background-image: url(${images.find(i => i.id == id)?.blob || images.find(i => i.id == id)?.url || `https://api.churchandfamilylife.com/${images.find(i => i.id == id)?.response?.paths?.[0]}`})`">
|
|
10
|
+
<div class="bg-black/50 absolute h-full top-0 right-0" :style="`width: ${100-images.find(i => i.id == id)?.progress}%;`" />
|
|
11
|
+
<button @click="removeImage(id)" class="w-full h-full hidden group-hover:flex absolute backdrop-blur items-center justify-center">
|
|
12
|
+
<i class="fa fa-trash-alt text-3xl text-red-800" />
|
|
13
|
+
</button>
|
|
14
|
+
</div>
|
|
15
|
+
</template>
|
|
16
|
+
</Draggable>
|
|
17
|
+
|
|
18
|
+
<FileUpload
|
|
19
|
+
ref="upload"
|
|
20
|
+
v-model="images"
|
|
21
|
+
post-action="https://api.churchandfamilylife.com/upload"
|
|
22
|
+
:drop="true"
|
|
23
|
+
:multiple="true"
|
|
24
|
+
:drop-directory="true"
|
|
25
|
+
:extensions="['png','jpg','jpeg','heic']"
|
|
26
|
+
class="w-full aspect-square border-2 dark:border-gray-600 bg-gray-300 dark:bg-gray-800 block cursor-pointer relative rounded"
|
|
27
|
+
>
|
|
28
|
+
<div class="w-full h-full flex items-center justify-center">
|
|
29
|
+
<i class="fa fa-image text-3xl dark:text-gray-700" />
|
|
30
|
+
</div>
|
|
31
|
+
<div class="w-full h-full hidden group-hover:flex absolute backdrop-blur items-center justify-center">
|
|
32
|
+
<i class="fa fa-pencil text-3xl text-gray-800" />
|
|
33
|
+
</div>
|
|
34
|
+
</FileUpload>
|
|
35
|
+
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
</template>
|
|
40
|
+
|
|
41
|
+
<script>
|
|
42
|
+
import FileUpload from 'vue-upload-component'
|
|
43
|
+
import Draggable from 'vuedraggable'
|
|
44
|
+
|
|
45
|
+
export default {
|
|
46
|
+
components: {FileUpload, Draggable},
|
|
47
|
+
inject: ['axios'],
|
|
48
|
+
data() {
|
|
49
|
+
return {
|
|
50
|
+
images: [],
|
|
51
|
+
sortableImages: [],
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
watch: {
|
|
55
|
+
images: {
|
|
56
|
+
handler() {
|
|
57
|
+
// this.updateImages()
|
|
58
|
+
console.log('image watcher')
|
|
59
|
+
console.log('this', this.$refs.upload)
|
|
60
|
+
this.$refs.upload.active = true
|
|
61
|
+
this.sortableImages = this.images.map(i => i.id)
|
|
62
|
+
this.images.forEach(i => i.blob = i.blob ? i.blob : URL.createObjectURL(i.file))
|
|
63
|
+
},
|
|
64
|
+
deep: true
|
|
65
|
+
},
|
|
66
|
+
urls() {
|
|
67
|
+
this.$emit('urls', this.urls)
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
},
|
|
71
|
+
computed: {
|
|
72
|
+
done() {
|
|
73
|
+
return this.images.every(i => i.progress == 100)
|
|
74
|
+
},
|
|
75
|
+
urls() {
|
|
76
|
+
return this.sortableImages.map(id => this.images?.find(i => i.id == id)?.response?.paths?.[0])
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
methods: {
|
|
80
|
+
removeImage(id) {
|
|
81
|
+
console.log('removing')
|
|
82
|
+
let index = this.images?.findIndex(i => i.id == id)
|
|
83
|
+
console.log('index', index)
|
|
84
|
+
if (isNaN(index)) return
|
|
85
|
+
this.images.splice(index,1)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
</script>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ref } from 'vue'
|
|
2
|
+
import Mango from './mango'
|
|
3
|
+
|
|
4
|
+
const getUser = async (user) => {
|
|
5
|
+
|
|
6
|
+
user = user || { value: {} }
|
|
7
|
+
|
|
8
|
+
if (window.user?.id) {
|
|
9
|
+
|
|
10
|
+
console.log('got it!')
|
|
11
|
+
user.value = window.user
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
Gotta clear this out so next time
|
|
15
|
+
we try to call getUser we don't get
|
|
16
|
+
stale data. ;)
|
|
17
|
+
*/
|
|
18
|
+
window.user = null
|
|
19
|
+
return user.value
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let userId = window.localStorage.getItem('user')
|
|
23
|
+
|
|
24
|
+
if (!userId) return {}
|
|
25
|
+
|
|
26
|
+
user.value = await Mango.member(userId, { depthLimit: 0 }).then(r => user.value = r)
|
|
27
|
+
|
|
28
|
+
return user.value
|
|
29
|
+
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const initUser = () => {
|
|
33
|
+
|
|
34
|
+
const user = ref({})
|
|
35
|
+
getUser(user)
|
|
36
|
+
return user
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { initUser, getUser }
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
@tailwind base;
|
|
2
|
+
@tailwind components;
|
|
3
|
+
@tailwind utilities;
|
|
4
|
+
|
|
5
|
+
.article a {
|
|
6
|
+
@apply font-semibold cursor-pointer
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.article a:hover {
|
|
10
|
+
@apply underline
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.article p,
|
|
14
|
+
.article div,
|
|
15
|
+
.article ul,
|
|
16
|
+
.article ol,
|
|
17
|
+
.article h2,
|
|
18
|
+
.article h3,
|
|
19
|
+
.article h4,
|
|
20
|
+
.article blockquote {
|
|
21
|
+
@apply mt-4 text-sm leading-relaxed break-words
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.article li {
|
|
25
|
+
@apply mt-2
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.article h2 {
|
|
29
|
+
@apply text-base font-semibold
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.article > :first-child,
|
|
33
|
+
.article > :first-child > :first-child,
|
|
34
|
+
.article > :first-child > :first-child > :first-child {
|
|
35
|
+
margin-top: 0px!important;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.article > .ql-container > .ql-editor > :first-child,
|
|
39
|
+
.article > .ql-container > .ql-editor > :first-child > :first-child,
|
|
40
|
+
.article > .ql-container > .ql-editor > :first-child > :first-child > :first-child {
|
|
41
|
+
margin-top: 0px!important;
|
|
42
|
+
}
|
|
43
|
+
/*.article > :first-child > :first-of-type {
|
|
44
|
+
margin-top: 0px
|
|
45
|
+
}*/
|
|
46
|
+
|
|
47
|
+
/*.ql-editor > :first-child {
|
|
48
|
+
margin-top: 0px
|
|
49
|
+
}*/
|
|
50
|
+
|
|
51
|
+
.article blockquote {
|
|
52
|
+
@apply
|
|
53
|
+
px-8
|
|
54
|
+
italic
|
|
55
|
+
text-gray-600
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@screen md {
|
|
59
|
+
.article p,
|
|
60
|
+
.article div,
|
|
61
|
+
.article ul,
|
|
62
|
+
.article ol,
|
|
63
|
+
.article h2,
|
|
64
|
+
.article h3,
|
|
65
|
+
.article h4,
|
|
66
|
+
.article blockquote {
|
|
67
|
+
@apply mt-8 text-base leading-relaxed
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.article li {
|
|
71
|
+
@apply mt-4
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.article h2 {
|
|
75
|
+
@apply text-2xl font-semibold
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
.space-1 {
|
|
81
|
+
@apply p-4
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@screen md {
|
|
85
|
+
.space-1 {
|
|
86
|
+
@apply p-6
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@screen xl {
|
|
91
|
+
.space-1 {
|
|
92
|
+
@apply p-8
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
.book-article a {
|
|
99
|
+
@apply font-semibold cursor-pointer
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.book-article a:hover {
|
|
103
|
+
@apply underline
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@screen md {
|
|
107
|
+
|
|
108
|
+
.book-article p,
|
|
109
|
+
.book-article div,
|
|
110
|
+
.book-article ul,
|
|
111
|
+
.book-article ol,
|
|
112
|
+
.book-article h2,
|
|
113
|
+
.book-article h3,
|
|
114
|
+
.book-article h4,
|
|
115
|
+
.book-article blockquote {
|
|
116
|
+
@apply mt-16
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.book-article li {
|
|
120
|
+
@apply mt-8
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.book-article h2 {
|
|
124
|
+
@apply text-5xl font-semibold
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.book-article p,
|
|
129
|
+
.book-article div,
|
|
130
|
+
.book-article ul,
|
|
131
|
+
.book-article ol,
|
|
132
|
+
.book-article h2,
|
|
133
|
+
.book-article h3,
|
|
134
|
+
.book-article h4,
|
|
135
|
+
.book-article blockquote {
|
|
136
|
+
@apply mt-8
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.book-article ul {
|
|
140
|
+
@apply list-disc
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.book-article li {
|
|
144
|
+
@apply mt-4
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.book-article h2 {
|
|
148
|
+
@apply text-2xl font-bold
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.book-article > :first-child,
|
|
152
|
+
.book-article > :first-child > :first-child,
|
|
153
|
+
.book-article > :first-child > :first-child > :first-child {
|
|
154
|
+
margin-top: 0px!important;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.book-article > .ql-container > .ql-editor > :first-child,
|
|
158
|
+
.book-article > .ql-container > .ql-editor > :first-child > :first-child,
|
|
159
|
+
.book-article > .ql-container > .ql-editor > :first-child > :first-child > :first-child {
|
|
160
|
+
margin-top: 0px!important;
|
|
161
|
+
}
|
|
162
|
+
/*.book-article > :first-child > :first-of-type {
|
|
163
|
+
margin-top: 0px
|
|
164
|
+
}*/
|
|
165
|
+
|
|
166
|
+
/*.ql-editor > :first-child {
|
|
167
|
+
margin-top: 0px
|
|
168
|
+
}*/
|
|
169
|
+
|
|
170
|
+
.book-article blockquote {
|
|
171
|
+
@apply
|
|
172
|
+
px-8
|
|
173
|
+
italic
|
|
174
|
+
text-gray-500
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
.ql-clipboard,
|
|
179
|
+
.ql-tooltip {
|
|
180
|
+
display: none!important;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.ql-editor {
|
|
184
|
+
outline: none!important;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
table.schedule {
|
|
188
|
+
@apply
|
|
189
|
+
my-4
|
|
190
|
+
w-full
|
|
191
|
+
text-xs
|
|
192
|
+
border-y
|
|
193
|
+
table-auto
|
|
194
|
+
border-collapse
|
|
195
|
+
dark:text-gray-500
|
|
196
|
+
dark:border-gray-800
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
table.schedule tr:nth-child(odd) {
|
|
200
|
+
@apply bg-gray-100 dark:bg-gray-800
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
table.schedule td {
|
|
204
|
+
@apply m-0 p-2
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
@screen md {
|
|
209
|
+
table.schedule {
|
|
210
|
+
@apply
|
|
211
|
+
my-8
|
|
212
|
+
text-sm
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
table.schedule td {
|
|
216
|
+
@apply m-0 p-4
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
.article-xs p,
|
|
222
|
+
.article-xs div,
|
|
223
|
+
.article-xs ul,
|
|
224
|
+
.article-xs ol,
|
|
225
|
+
.article-xs h2,
|
|
226
|
+
.article-xs h3,
|
|
227
|
+
.article-xs h4,
|
|
228
|
+
.article-xs blockquote {
|
|
229
|
+
@apply mt-2 text-xs leading-relaxed
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.article-xs li {
|
|
233
|
+
@apply mt-1
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.article-xs h2 {
|
|
237
|
+
@apply text-sm
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.article-sm p,
|
|
241
|
+
.article-sm div,
|
|
242
|
+
.article-sm ul,
|
|
243
|
+
.article-sm ol,
|
|
244
|
+
.article-sm h2,
|
|
245
|
+
.article-sm h3,
|
|
246
|
+
.article-sm h4,
|
|
247
|
+
.article-sm blockquote {
|
|
248
|
+
@apply mt-4 text-sm leading-relaxed
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.article-sm li {
|
|
252
|
+
@apply mt-2
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.article-sm h2 {
|
|
256
|
+
@apply text-base
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.article-md p,
|
|
260
|
+
.article-md div,
|
|
261
|
+
.article-md ul,
|
|
262
|
+
.article-md ol,
|
|
263
|
+
.article-md h2,
|
|
264
|
+
.article-md h3,
|
|
265
|
+
.article-md h4,
|
|
266
|
+
.article-md blockquote {
|
|
267
|
+
@apply mt-4 text-base leading-relaxed
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.article-md li {
|
|
271
|
+
@apply mt-2
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.article-md h2 {
|
|
275
|
+
@apply text-2xl
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.video-container,
|
|
279
|
+
.video-container iframe {
|
|
280
|
+
@apply aspect-video w-full !h-auto
|
|
281
|
+
}
|