Compare commits

...

21 Commits

Author SHA1 Message Date
8e8f6eb976 mail
All checks were successful
deploy to production / deploy (push) Successful in 30s
2023-11-20 15:05:22 +00:00
b107392907 backups
All checks were successful
deploy to production / deploy (push) Successful in 34s
2023-11-05 09:32:22 +00:00
819452e15e test
All checks were successful
deploy to production / deploy (push) Successful in 29s
2023-10-18 15:16:54 +00:00
7d2e708e65 test
All checks were successful
deploy to production / deploy (push) Successful in 29s
2023-10-18 15:13:46 +00:00
75d4c88d47 test
All checks were successful
deploy to production / deploy (push) Successful in 30s
2023-10-18 15:00:30 +00:00
850fb6ad1e test
All checks were successful
deploy to production / deploy (push) Successful in 31s
2023-10-18 14:55:24 +00:00
2d68e756a7 test
All checks were successful
deploy to production / deploy (push) Successful in 35s
2023-10-18 14:49:29 +00:00
48a5043de1 test 2023-10-18 14:47:27 +00:00
7d77440749 test
All checks were successful
deploy to production / deploy (push) Successful in 28s
2023-10-13 09:39:09 +00:00
46c5b52de1 tel
All checks were successful
deploy to production / deploy (push) Successful in 27s
2023-10-13 09:17:05 +00:00
7dd5e7e99a tel
All checks were successful
deploy to production / deploy (push) Successful in 54s
2023-10-11 08:48:44 +00:00
26fc03cbd0 slider
All checks were successful
deploy to production / deploy (push) Successful in 38s
2023-09-28 15:28:20 +00:00
626cbbabb4 2s more
All checks were successful
deploy to production / deploy (push) Successful in 35s
2023-09-27 19:35:06 +00:00
e6e1baf808 homepage nav
All checks were successful
deploy to production / deploy (push) Successful in 35s
2023-09-16 10:04:38 +00:00
df1e5c03be fix
All checks were successful
deploy to production / deploy (push) Successful in 33s
2023-09-08 15:46:38 +00:00
5b4ea22da0 fix
All checks were successful
deploy to production / deploy (push) Successful in 35s
2023-09-08 15:44:32 +00:00
e7c1de21bb fix
All checks were successful
deploy to production / deploy (push) Successful in 35s
2023-09-08 15:40:58 +00:00
a5e1ede626 fix
All checks were successful
deploy to production / deploy (push) Successful in 35s
2023-09-08 15:34:52 +00:00
605ac82471 fix
All checks were successful
deploy to production / deploy (push) Successful in 35s
2023-09-08 15:29:17 +00:00
6c9fd6f64a fix
All checks were successful
deploy to production / deploy (push) Successful in 35s
2023-09-08 15:25:03 +00:00
18b3db7671 fix 2023-09-08 15:20:49 +00:00
18 changed files with 307 additions and 38 deletions

View File

@@ -0,0 +1,95 @@
name: backups
meta:
isBackupcollection: true
permissions:
public:
methods:
get: false
post: false
put: false
delete: false
user:
methods:
get: true
post: false
put: false
delete: false
# token als Zusatzsicherung gegen Spam, mehr siehe Hook
"token:${PUBLIC_TOKEN}":
methods:
get: false
post: true
put: false
delete: false
hooks:
post:
create:
type: javascript
file: hooks/backups/post_create.js
fields:
- name: collectionName
type: string
meta:
label: Collection Name
- name: entryId
type: string
meta:
label: Entry ID
- name: versionNr
type: number
meta:
label: Version Nr
- name: manipulatedBy
type: string
meta:
label: Manipulated By
- name: eventDescription
type: string
meta:
label: Event Description
widget: select
choices:
- id: create
name: Create
- id: update
name: Update
- id: delete
name: Delete
- id: recreate
name: Recreate
- id: activate
name: Activate
- name: updateLogs
type: object[]
meta:
label: Veränderungen
subFields:
- name: field
type: string
meta:
label: Feldname
- name: previous
type: string
meta:
label: Vorheriger Wert
- name: current
type: string
meta:
label: Aktueller Wert
- name: entry
type: object
meta:
label: Entry

View File

@@ -4,6 +4,9 @@ uploadPath: ../media/page
meta:
label: Inhalt
muiIcon: web
backup:
active: true
collectionName: backups
views:
- type: table
columns:
@@ -90,6 +93,7 @@ fields:
type: object[]
meta:
label: Zeilen
widget: containerLessObjectArray
folding:
force: true
subFields:

View File

@@ -68,6 +68,20 @@ subFields:
label: Zwei zu drei
helperText: "Ist dies aktiviert, so wird die Zeile in zwei zu drei Spalten aufgeteilt."
- name: nextPage
type: string
meta:
label: Nächste Seite
widget: select
choices:
endpoint: page
params:
sort: path
projection: navigation
mapping:
id: path
name: path
- name: columns
type: object[]
meta:

View File

@@ -8,9 +8,26 @@ meta:
- url: https://tibi-admin-server.code.testversion.online/api/v1/_/demo
description: code-server
dashboard:
majorItems:
- collection: navigation
type: reference
style:
upper: rgba(3, 50, 59, 0.7)
lower: rgba(3, 50, 59)
- collection: page
type: reference
style:
upper: rgba(3, 50, 59, 0.7)
lower: rgba(3, 50, 59)
minorItems: []
collections:
- !include collections/navigation.yml
- !include collections/content.yml
- !include collections/backups.yml
assets:
- name: img

View File

@@ -0,0 +1,92 @@
;(function () {
let backup = context.data
const updateLogs = compareAndUpdateEntry(backup?.entry, backup?.collectionName, backup?.versionNr - 1)
backup.updateLogs = updateLogs
return { data: backup }
function compareAndUpdateEntry(entry, collectionName, versionNr) {
let updateLogs
if (versionNr == 0) {
updateLogs = getUpdateLogs({}, entry)
}
delete entry.updateTime
let previousEntry = context.db.find("backups", {
filter: { entryId: context.data.entryId, versionNr, collectionName },
})[0]
if (!previousEntry) {
console.error("No previous entry found")
updateLogs = getUpdateLogs({}, entry)
} else {
delete previousEntry.updateTime
updateLogs = getUpdateLogs(previousEntry.entry, entry)
}
console.log(context.json.stringify(previousEntry?.entry), context.json.stringify(entry))
return updateLogs
}
function filterValidObjects(array) {
return array.filter((object) => {
for (let key in object) {
if (typeof object[key] !== "string" && object[key] !== null) {
return false
}
}
return true
})
}
function getUpdateLogs(oldObj = {}, newObj = {}, path = "") {
let updateLogs = []
const ignoredKeys = ["id", "insertTime", "updateTime"]
const allKeys = new Set([...Object.keys(oldObj), ...Object.keys(newObj)])
allKeys.forEach((key) => {
if (ignoredKeys.includes(key)) return
const newPath = path ? `${path}.${key}` : key
const oldVal = oldObj.hasOwnProperty(key) ? oldObj[key] : ""
const newVal = newObj.hasOwnProperty(key) ? newObj[key] : ""
// Handle Arrays
if (Array.isArray(oldVal) || Array.isArray(newVal)) {
const oldArr = oldVal || []
const newArr = newVal || []
for (let i = 0; i < Math.max(oldArr.length, newArr.length); i++) {
const itemPath = `${newPath}[${i}]`
if (oldArr[i] !== newArr[i]) {
if (typeof oldArr[i] === "object" || typeof newArr[i] === "object") {
const arrUpdates = getUpdateLogs(oldArr[i], newArr[i], itemPath)
updateLogs = updateLogs.concat(arrUpdates)
} else {
updateLogs.push({
field: itemPath,
previous: oldArr[i] === undefined ? "" : oldArr[i].toString(),
current: newArr[i] === undefined ? "" : newArr[i].toString(),
})
}
}
}
}
// Handle nested objects but not arrays
else if (
(typeof oldVal === "object" && oldVal !== null) ||
(typeof newVal === "object" && newVal !== null)
) {
const nestedUpdates = getUpdateLogs(oldVal || {}, newVal || {}, newPath)
updateLogs = updateLogs.concat(nestedUpdates)
}
// Handle primitive types
else if (oldVal !== newVal) {
updateLogs.push({
field: newPath,
previous: oldVal.toString(),
current: newVal.toString(),
})
}
})
return filterValidObjects(updateLogs)
}
})()

View File

@@ -0,0 +1,3 @@
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15.268 4.21a.75.75 0 0 0-1.04 1.08l8.275 7.96H3.75a.75.75 0 1 0 0 1.5h18.752l-8.273 7.959a.75.75 0 0 0 1.04 1.08l9.428-9.069a1 1 0 0 0 0-1.441l-9.428-9.07-.001.001z" fill="#333"/>
</svg>

After

Width:  |  Height:  |  Size: 297 B

View File

@@ -146,7 +146,7 @@ swiper-slide {
background: #000000;
height: 5px;
width: 0;
animation: underlineEffect 4s linear forwards;
animation: underlineEffect 15s linear forwards;
@media @tablet {
height: 10px;
}
@@ -177,3 +177,8 @@ swiper-slide {
scrollbar-width: thin; /* "auto" or "thin" */
scrollbar-color: rgb(255, 255, 255) rgb(0, 0, 0); /* scroll thumb and track */
}
a {
color: black;
text-decoration: underline;
}

View File

@@ -4,6 +4,7 @@
let nextpage = $navigation?.pages[0]
$: nextpage = $navigation?.pages[0]
function getNextPage(pages) {
console.log(pages, "pages")
if (location.pathname == "/" || location.pathname == "") return
let currPage = pages.find(
@@ -26,6 +27,7 @@
} else {
blackBg = false
}
getNextPage($navigation.pages)
if (location.pathname.split("/").filter((s) => s).length >= 2) {
@@ -58,7 +60,7 @@
navigate(Object.values($pages)?.find((o) => o.id == nextpage.page)?.path || '/')
}}"
>
<div class="upper"><img src="/media/arrow-right.svg" alt="arrow" /> nächstes Thema</div>
<div class="upper"><img src="/media/arrow-right.svg" alt="arrow" /> Weiter</div>
<div class="lower">{nextpage?.name}</div>
</button>{/if}
<div class="lower-part">
@@ -78,9 +80,13 @@
>
</div>
<div class="contact">
<button>0711 644 700-0</button>
<button>+49 (0) 711 655 700-0</button>
<button> <a href="mailto:info@fontis.de" class="button"> info@fontis.de</a></button>
<button>
<a href="mailto:info@fontis.de" class="button" style="text-decoration: none;">
info@fontis.de</a
></button
>
</div>
</div>
</div>

View File

@@ -14,16 +14,17 @@
<div class="inner-container">
<div class="pages">
{#each $navigation.pages as page}
<button
class="page underline"
on:click="{() => {
active = false
$rerender = $rerender + 1
navigate(Object.values($pages)?.find((o) => o.id == page.page)?.path || '/')
}}"
>
{page.name}
</button>
{#if Object.values($pages)?.find((o) => o.id == page.page)?.path !== "/"}
<button
class="page underline"
on:click="{() => {
active = false
$rerender = $rerender + 1
navigate(Object.values($pages)?.find((o) => o.id == page.page)?.path || '/')
}}"
>
{page.name}
</button>{/if}
{/each}
</div>
<div class="footer-infos">
@@ -46,9 +47,11 @@
>
</div>
<div class="lower">
<button>0711&nbsp;644&nbsp;700-0</button>
<button>+49 (0) 711 655 700-0</button>
<button>
<a href="mailto:info@fontis.de" class="button"> info@fontis.de </a>
<a href="mailto:info@fontis.de" style="text-decoration: none;" class="button">
info@fontis.de
</a>
</button>
</div>
</div>

View File

@@ -59,7 +59,7 @@
navigation="{true}"
init="{false}"
autoplay="{{
delay: 4000, // 5000ms = 5s
delay: 15000, // 5000ms = 5s
pauseOnMouseEnter: true,
}}"
speed="600"

View File

@@ -33,8 +33,10 @@
return ""
}
$: console.log($pages)
let nestedPath = checkNestedPath()
window.addEventListener("popstate", function (event) {
$rerender = $rerender + 1
})
</script>
{#if Object.keys(row).length}
@@ -44,16 +46,28 @@
</h3>
{/if}
{#if nestedPath}
<h3
style="cursor: pointer; display: flex; align-items: center; gap: 10px; line-height: 1.4;"
on:keydown
on:click="{() => {
$rerender = $rerender + 1
navigate(nestedPath)
}}"
>
<img src="/media/arrow-l.svg" alt="arrow" /> Zurück zur Übersicht
</h3>
<div class="top-header" style="display: flex; width: 100%; justify-content: space-between;">
<h3
style="cursor: pointer; display: flex; align-items: center; gap: 10px; line-height: 1.4;"
on:keydown
on:click="{() => {
$rerender = $rerender + 1
navigate(nestedPath)
}}"
>
<img src="/media/arrow-l.svg" alt="arrow" /> Zurück zur Übersicht
</h3>
<h3
style="cursor: pointer; display: flex; align-items: center; gap: 10px; line-height: 1.4;"
on:keydown
on:click="{() => {
$rerender = $rerender + 1
navigate(row?.nextPage || nestedPath)
}}"
>
Zum nächsten Profil <img src="/media/arrowr.svg" alt="arrow" />
</h3>
</div>
{/if}
{#if row.pageTitle}
<h1>{row.pageTitle}</h1>
@@ -135,6 +149,18 @@
font-weight: 500;
font-size: 2rem;
}
.top-header {
img {
width: 20px;
}
font-size: 0.7rem;
@media @tablet {
font-size: 1.2rem;
img {
width: 48px;
}
}
}
@media @tablet {
h3 {
font-size: 1.3rem;

View File

@@ -39,7 +39,6 @@
initPage()
}
}
$: console.log(page?.rows, "==rows")
</script>
<div class="rows" class:HP="{path == '/'}">

View File

@@ -44,7 +44,7 @@
</div>
<div class="details">
<em>{nE.title}</em>
<a href="{apiBaseURL}page/{pageId}/{nE.file.src}" download="{apiBaseURL}page/{pageId}/{nE.file.src}">
<a href="{apiBaseURL}page/{pageId}/{nE.file.src}" style="text-decoration: none;" download="{apiBaseURL}page/{pageId}/{nE.file.src}">
<button class="more">mehr</button></a
>
</div>

View File

@@ -37,7 +37,11 @@
<div class="content" class:closed="{i !== opened}">
{@html box.text}
{#if box.emailButton}
<a href="mailto:info@fontis.de?subject={box.emailSubject || 'Bewerbung'}" class="button">
<a
href="mailto:bewerbung@fontis.de?subject={box.emailSubject || 'Bewerbung'}"
style="text-decoration: none;"
class="button"
>
<button> bewerben </button>
</a>
{/if}

View File

@@ -6,6 +6,7 @@
</script>
<div class="iconBlock">
{#each col.iconBlocks as icon}
<div class="icon">
<img src="{`${apiBaseURL}page/${pageId}/${icon.icon?.src}`}" alt="img" />
@@ -60,7 +61,7 @@
font-weight: bold;
font-size: 1rem;
@media (max-width: 1050px) {
font-size: 0.9rem;
font-size: 0.7rem;
}
}
}

View File

@@ -99,6 +99,7 @@
}
@media (max-width: 520px) {
transform: scale(0.37);
margin-top: 120px;
height: 370px;
}
.main-circle {
@@ -207,7 +208,6 @@
position: absolute;
width: 10px;
height: 75px;
transform-origin: center;
}
}

View File

@@ -12,7 +12,7 @@
<div class="icons">
{#each col.icons as icon}
<div class="icon">
<a href="{icon.link}" target="_blank">
<a href="{icon.link}" style="text-decoration: none;" target="_blank">
<img src="{`${apiBaseURL}page/${pageId}/${icon.icon?.src}`}" alt="img" />
</a>
</div>

View File

@@ -7,10 +7,10 @@ if [ -z "${RSYNC_USER}" ] || [ -z "${RSYNC_PASS}" ]; then
fi
excludes=""
if [ "${DRONE_BRANCH}" == "master" ]; then
excludes='--exclude=src --exclude=*.map'
echo "master deploy, excluding $excludes"
fi
#if [ "${DRONE_BRANCH}" == "master" ]; then
# excludes='--exclude=src --exclude=*.map'
# echo "master deploy, excluding $excludes"
#fi
# sync frontend
rsync -rlcgD --perms -i -u -v --stats --progress \