Compare commits

...

83 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
fa1485d6ac fix
All checks were successful
deploy to production / deploy (push) Successful in 38s
2023-09-08 15:19:50 +00:00
a91eb90c41 test
All checks were successful
deploy to production / deploy (push) Successful in 38s
2023-09-08 15:07:07 +00:00
f2c9b2bc40 test
All checks were successful
deploy to production / deploy (push) Successful in 42s
2023-09-08 15:06:41 +00:00
3e01920db4 test
All checks were successful
deploy to production / deploy (push) Successful in 37s
2023-09-08 15:04:56 +00:00
df22a0da08 fix
All checks were successful
deploy to production / deploy (push) Successful in 34s
2023-09-08 14:41:20 +00:00
ac526612df fix
All checks were successful
deploy to production / deploy (push) Successful in 38s
2023-09-08 14:24:35 +00:00
6aeb2c8778 fix
All checks were successful
deploy to production / deploy (push) Successful in 35s
2023-09-08 14:21:49 +00:00
fa80939f6b fix
All checks were successful
deploy to production / deploy (push) Successful in 38s
2023-09-08 14:16:30 +00:00
e976c694b8 fix 2023-09-08 14:14:03 +00:00
0938113f88 fix
All checks were successful
deploy to production / deploy (push) Successful in 31s
2023-09-08 14:01:41 +00:00
1b8e5fed12 fix
All checks were successful
deploy to production / deploy (push) Successful in 35s
2023-09-08 14:00:13 +00:00
11062fc0fb fixes
All checks were successful
deploy to production / deploy (push) Successful in 34s
2023-09-08 13:49:47 +00:00
5504c5595a fixes
Some checks failed
deploy to production / deploy (push) Failing after 23s
2023-09-08 13:47:19 +00:00
61af2e2c8e fixes
All checks were successful
deploy to production / deploy (push) Successful in 36s
2023-09-08 13:42:48 +00:00
6b735fed07 ttt
All checks were successful
deploy to production / deploy (push) Successful in 40s
2023-09-05 13:56:20 +00:00
960625a018 ttt
All checks were successful
deploy to production / deploy (push) Successful in 36s
2023-09-05 13:55:16 +00:00
1b54cf507e ttt
All checks were successful
deploy to production / deploy (push) Successful in 43s
2023-09-05 13:51:08 +00:00
8e3abd56c1 ttt
All checks were successful
deploy to production / deploy (push) Successful in 37s
2023-09-05 13:40:05 +00:00
e4b6334d85 fix
All checks were successful
deploy to production / deploy (push) Successful in 40s
2023-09-05 13:00:45 +00:00
8d626450f6 push
All checks were successful
deploy to production / deploy (push) Successful in 40s
2023-09-05 12:35:51 +00:00
4e283573bd fixes
All checks were successful
deploy to production / deploy (push) Successful in 38s
2023-09-01 16:25:18 +00:00
223bbf0699 fixes
All checks were successful
deploy to production / deploy (push) Successful in 36s
2023-09-01 16:24:20 +00:00
24144c692e fixes
All checks were successful
deploy to production / deploy (push) Successful in 34s
2023-09-01 16:16:55 +00:00
35c1ed0dec fixes
All checks were successful
deploy to production / deploy (push) Successful in 34s
2023-09-01 16:16:19 +00:00
b6a4df9c37 fixes
All checks were successful
deploy to production / deploy (push) Successful in 35s
2023-09-01 16:14:41 +00:00
536902cbbb fixes
All checks were successful
deploy to production / deploy (push) Successful in 34s
2023-09-01 15:55:01 +00:00
97e67e0b58 fixes
All checks were successful
deploy to production / deploy (push) Successful in 37s
2023-09-01 15:45:15 +00:00
0a200ad3c6 fixes
All checks were successful
deploy to production / deploy (push) Successful in 35s
2023-09-01 15:42:28 +00:00
d0c81857d4 fixes
All checks were successful
deploy to production / deploy (push) Successful in 34s
2023-09-01 15:35:51 +00:00
fb497d0e6f fixes
All checks were successful
deploy to production / deploy (push) Successful in 34s
2023-09-01 15:28:45 +00:00
77affb9705 fixes
All checks were successful
deploy to production / deploy (push) Successful in 34s
2023-09-01 15:15:41 +00:00
f3a22c7543 fixes
All checks were successful
deploy to production / deploy (push) Successful in 32s
2023-09-01 15:09:15 +00:00
9a4270e4dd fixes
All checks were successful
deploy to production / deploy (push) Successful in 35s
2023-09-01 14:50:43 +00:00
8b955bdae6 fixes
All checks were successful
deploy to production / deploy (push) Successful in 35s
2023-09-01 14:27:11 +00:00
af8850dede fixes
All checks were successful
deploy to production / deploy (push) Successful in 35s
2023-09-01 14:22:27 +00:00
d44cbc1757 fixes
All checks were successful
deploy to production / deploy (push) Successful in 34s
2023-09-01 14:15:06 +00:00
2a894d6645 fixes
All checks were successful
deploy to production / deploy (push) Successful in 33s
2023-09-01 14:10:51 +00:00
ce132cb146 fixes
All checks were successful
deploy to production / deploy (push) Successful in 35s
2023-09-01 14:08:21 +00:00
1b44964f9c fixes
All checks were successful
deploy to production / deploy (push) Successful in 35s
2023-09-01 14:05:36 +00:00
10eade80ae fixes
All checks were successful
deploy to production / deploy (push) Successful in 34s
2023-09-01 13:52:29 +00:00
e02ac8e1f7 fixes
All checks were successful
deploy to production / deploy (push) Successful in 35s
2023-09-01 13:46:53 +00:00
190c83f4b0 test
All checks were successful
deploy to production / deploy (push) Successful in 33s
2023-09-01 13:17:45 +00:00
2aaa02329f test
All checks were successful
deploy to production / deploy (push) Successful in 35s
2023-09-01 13:14:58 +00:00
4e5a921711 test
All checks were successful
deploy to production / deploy (push) Successful in 32s
2023-09-01 13:08:06 +00:00
f2ddcb410b test
All checks were successful
deploy to production / deploy (push) Successful in 34s
2023-09-01 12:57:53 +00:00
75269a3a30 test
All checks were successful
deploy to production / deploy (push) Successful in 34s
2023-09-01 12:55:40 +00:00
82b9b6ec36 fixes
All checks were successful
deploy to production / deploy (push) Successful in 35s
2023-09-01 12:11:46 +00:00
157e667227 fixes
All checks were successful
deploy to production / deploy (push) Successful in 36s
2023-09-01 12:09:35 +00:00
769fd1296c fix
All checks were successful
deploy to production / deploy (push) Successful in 30s
2023-08-17 09:15:33 +00:00
8a6c025040 fix
All checks were successful
deploy to production / deploy (push) Successful in 30s
2023-08-17 09:13:08 +00:00
4d31133d99 fix
All checks were successful
deploy to production / deploy (push) Successful in 30s
2023-08-17 09:11:50 +00:00
e51a485ebc fix
All checks were successful
deploy to production / deploy (push) Successful in 30s
2023-08-17 09:11:09 +00:00
948808ec4f fix
All checks were successful
deploy to production / deploy (push) Successful in 31s
2023-08-17 09:09:34 +00:00
c8314798e5 fix
All checks were successful
deploy to production / deploy (push) Successful in 31s
2023-08-17 08:51:33 +00:00
19d7c231ae impressumt datenschutz
All checks were successful
deploy to production / deploy (push) Successful in 31s
2023-08-17 08:49:24 +00:00
32295fecfa fix
All checks were successful
deploy to production / deploy (push) Successful in 31s
2023-08-17 08:46:02 +00:00
d6e253d77e fix
All checks were successful
deploy to production / deploy (push) Successful in 31s
2023-08-17 08:27:00 +00:00
04595d7094 fix
All checks were successful
deploy to production / deploy (push) Successful in 31s
2023-08-17 08:01:56 +00:00
068c6f0ca1 tst
All checks were successful
deploy to production / deploy (push) Successful in 31s
2023-08-16 10:59:08 +00:00
c8f8f8ca4d tst
Some checks failed
deploy to production / deploy (push) Failing after 32s
2023-08-16 10:56:43 +00:00
66314fcb92 tst
Some checks failed
deploy to production / deploy (push) Failing after 55s
2023-08-16 10:53:05 +00:00
44f7934217 tst
Some checks failed
deploy to production / deploy (push) Failing after 31s
2023-08-16 10:46:33 +00:00
33 changed files with 838 additions and 251 deletions

View File

@@ -1,10 +1,6 @@
name: deploy to production name: deploy to production
on: "push" on: "push"
# push:
# branches:
# - master
jobs: jobs:
deploy: deploy:
name: deploy name: deploy
@@ -17,40 +13,81 @@ jobs:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
with: with:
fetch-depth: 0 fetch-depth: 0
lfs: true
submodules: true
- run: |
git fetch --force --tags
# setup node 18
- name: setup node 18 - name: setup node 18
uses: actions/setup-node@v3 uses: actions/setup-node@v3
with: # with:
node-version: 18 # node-version: 18
# cache: yarn
- name: build docs - name: install dependencies
env: env:
FORCE_COLOR: "true" FORCE_COLOR: "true"
run: | run: |
node --version npm install -g yarn
cd docs
yarn install yarn install
yarn docpress:build
- name: deploy docs - name: modify config
# only if branch is master run: |
sed -i 's#\(sentryEnvironment.*\)".*"#\1"${GITHUB_REF_NAME}"#g' frontend/src/config.ts
sed -i 's#//\( sentry\\.init.*\)#\1#g' frontend/src/config.ts
export $(cat .env | xargs)
echo "PROJECT_RELEASE=${RELEASE_PROJECT_SLUG}.r`git rev-list HEAD --count`-`git describe --all --long | sed 's+/+-+'`" >> .env
export $(cat .env | xargs)
echo ______ .env ______
cat .env
echo
sed -i 's#\(const release = \).*#\1"'${PROJECT_RELEASE}'"#g' api/hooks/config-client.js
# bash scripts/preload-meta.sh frontend/spa.html
# bash scripts/preload-meta.sh frontend/spa.html > frontend/_spa.html
# cp frontend/_spa.html frontend/spa.html
export stamp=`date +%s`
sed -i s/__TIMESTAMP__/$stamp/g frontend/spa.html
# sed -i s/__TIMESTAMP__/$stamp/g frontend/serviceworker.js
# cat frontend/serviceworker.js
# rm api/templates/spa.html
# cp frontend/spa.html api/templates/spa.html
echo ______ frontend/spa.html ______
cat frontend/spa.html
- name: build
env:
FORCE_COLOR: "true"
run: |
yarn build
#- name: build ssr
# env:
# FORCE_COLOR: "true"
# run: |
# yarn build:server
- name: build legacy
env:
FORCE_COLOR: "true"
run: |
yarn build:legacy
#- name: staging api test
# if: github.ref == 'refs/heads/dev'
# run: |
# targetDir=/data/${GITHUB_REPOSITORY}/${GITHUB_REF_NAME}
# mkdir -p targetDir
# rsync -av api $targetDir/
# mkdir -p $targetDir/frontend/dist
# rsync -av frontend/dist/ $targetDir/frontend/dist/
#- name: staging frontend te
# if: github.ref == 'refs/heads/dev'
# run: |
# docker compose -p ${GITHUB_REF_NAME}-${GITHUB_REPOSITORY_NAME}-${GITHUB_REPOSITORY_OWNER} up -d --build --remove-orphans
- name: deploy
if: github.ref == 'refs/heads/master' if: github.ref == 'refs/heads/master'
env: env:
RSYNC_HOST: ftp1.webmakers.de RSYNC_USER: "fontis_rsync_master"
RSYNC_PORT: 22222
RSYNC_USER: webmakers_tibi_docs_rsync_master
RSYNC_PASS: ${{ secrets.rsync_master }} RSYNC_PASS: ${{ secrets.rsync_master }}
run: | run: |
cd docs scripts/deploy.sh ftp1.webmakers.de $RSYNC_USER $RSYNC_PASS
ls -la
rsync -rlcgD --perms -i -u -v --stats --progress \
--delete \
-e "sshpass -p ${RSYNC_PASS} ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p ${RSYNC_PORT}" \
_docpress/ \
${RSYNC_USER}@${RSYNC_HOST}:./ \

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: meta:
label: Inhalt label: Inhalt
muiIcon: web muiIcon: web
backup:
active: true
collectionName: backups
views: views:
- type: table - type: table
columns: columns:
@@ -90,6 +93,7 @@ fields:
type: object[] type: object[]
meta: meta:
label: Zeilen label: Zeilen
widget: containerLessObjectArray
folding: folding:
force: true force: true
subFields: subFields:

View File

@@ -61,3 +61,15 @@
id: 8 id: 8
- name: Immobilienbestand - name: Immobilienbestand
id: 9 id: 9
- name: verticalShift
type: number
meta:
label: Vertikale Verschiebung
helperText: "Die Karte wird um die angegebene Anzahl in Prozent nach oben verschoben."
- name: horizontalShift
type: number
meta:
label: Horizontale Verschiebung
helperText: "Die Karte wird um die angegebene Anzahl in Prozent nach rechts verschoben."

View File

@@ -15,6 +15,12 @@ subFields:
label: Oberer Titel label: Oberer Titel
helperText: "Dieser Titel wird in der Zeile oben angezeigt." helperText: "Dieser Titel wird in der Zeile oben angezeigt."
- name: topTitleUpperCase
type: boolean
meta:
label: Oberer Titel in Großbuchstaben
helperText: "Ist dies aktiviert, so wird der obere Titel in Großbuchstaben angezeigt."
- name: title - name: title
type: string type: string
meta: meta:
@@ -39,12 +45,43 @@ subFields:
label: Hintergrundbild label: Hintergrundbild
helperText: "Dieses Bild wird als Hintergrundbild der Zeile angezeigt." helperText: "Dieses Bild wird als Hintergrundbild der Zeile angezeigt."
- name: noBottomMargin
type: boolean
meta:
label: Kein unterer Abstand
helperText: "Ist dies aktiviert, so wird kein Abstand unter der Zeile angezeigt."
- name: noTopMargin
type: boolean
meta:
label: Kein oberer Abstand
helperText: "Ist dies aktiviert, so wird kein Abstand über der Zeile angezeigt."
- name: flexWrapNormal - name: flexWrapNormal
type: boolean type: boolean
meta: meta:
label: Zeile normal umbrechen label: Zeile normal umbrechen
helperText: "Ist dies aktiviert, so wird die Zeile normal und nicht reverse umgebrochen." helperText: "Ist dies aktiviert, so wird die Zeile normal und nicht reverse umgebrochen."
- name: twoToThree
type: boolean
meta:
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 - name: columns
type: object[] type: object[]
meta: meta:

View File

@@ -8,9 +8,26 @@ meta:
- url: https://tibi-admin-server.code.testversion.online/api/v1/_/demo - url: https://tibi-admin-server.code.testversion.online/api/v1/_/demo
description: code-server 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: collections:
- !include collections/navigation.yml - !include collections/navigation.yml
- !include collections/content.yml - !include collections/content.yml
- !include collections/backups.yml
assets: assets:
- name: img - 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

@@ -1,7 +1,7 @@
AddType application/javascript .mjs AddType application/javascript .mjs
#DirectoryIndex index.html spa.html #DirectoryIndex index.html spa.html
DirectoryIndex noindex DirectoryIndex spa.html
<ifModule mod_rewrite.c> <ifModule mod_rewrite.c>
RewriteEngine On RewriteEngine On
@@ -11,6 +11,6 @@ DirectoryIndex noindex
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-d
#RewriteRule ^/?(.*)$ http://tibi-server:8080/api/v1/_/demo/ssr?token=owshwerNwoa&url=/$1 [P,QSA,L]
RewriteRule (.*) /spa.html [QSA,L] RewriteRule (.*) /spa.html [QSA,L]
</ifModule> </ifModule>

View File

@@ -1,3 +1,3 @@
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg"> <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.96a.75.75 0 0 0 1.04 1.08l9.428-9.07a1 1 0 0 0 0-1.44l-9.428-9.07h-.001z" fill="#000"/> <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.96a.75.75 0 0 0 1.04 1.08l9.428-9.07a1 1 0 0 0 0-1.44l-9.428-9.07h-.001z" />
</svg> </svg>

Before

Width:  |  Height:  |  Size: 291 B

After

Width:  |  Height:  |  Size: 280 B

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

@@ -71,7 +71,9 @@
</Route> </Route>
</Router> </Router>
</div> </div>
{#key $rerender}
<Footer /> <Footer />
{/key}
</main> </main>
<ScrollTop /> <ScrollTop />
@@ -166,6 +168,10 @@
html, html,
body { body {
font-family: "Libre Franklin", sans-serif;
button {
font-family: "Libre Franklin", sans-serif;
}
@media @mobile { @media @mobile {
font-size: @bodyfontsize; font-size: @bodyfontsize;
line-height: 1.4; line-height: 1.4;

View File

@@ -2,6 +2,7 @@
margin: 0; margin: 0;
padding: 0; padding: 0;
box-sizing: border-box; box-sizing: border-box;
overflow-wrap: break-word;
} }
html { html {
background-color: black; background-color: black;
@@ -24,6 +25,8 @@ ol {
a { a {
text-decoration: none; text-decoration: none;
font-weight: 700; font-weight: 700;
color: inherit;
font-weight: normal;
} }
/* Tabellen */ /* Tabellen */
@@ -143,7 +146,7 @@ swiper-slide {
background: #000000; background: #000000;
height: 5px; height: 5px;
width: 0; width: 0;
animation: underlineEffect 4s linear forwards; animation: underlineEffect 15s linear forwards;
@media @tablet { @media @tablet {
height: 10px; height: 10px;
} }
@@ -174,3 +177,8 @@ swiper-slide {
scrollbar-width: thin; /* "auto" or "thin" */ scrollbar-width: thin; /* "auto" or "thin" */
scrollbar-color: rgb(255, 255, 255) rgb(0, 0, 0); /* scroll thumb and track */ 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] let nextpage = $navigation?.pages[0]
$: nextpage = $navigation?.pages[0] $: nextpage = $navigation?.pages[0]
function getNextPage(pages) { function getNextPage(pages) {
console.log(pages, "pages")
if (location.pathname == "/" || location.pathname == "") return if (location.pathname == "/" || location.pathname == "") return
let currPage = pages.find( let currPage = pages.find(
@@ -19,7 +20,14 @@
} }
nextpage = pages[nextIndex] nextpage = pages[nextIndex]
} }
let blackBg = false
setInterval(() => { setInterval(() => {
if (location.pathname == "/") {
blackBg = true
} else {
blackBg = false
}
getNextPage($navigation.pages) getNextPage($navigation.pages)
if (location.pathname.split("/").filter((s) => s).length >= 2) { if (location.pathname.split("/").filter((s) => s).length >= 2) {
@@ -43,7 +51,7 @@
} }
</script> </script>
<div class="footer"> <div class="footer" class:black-bg="{blackBg}">
{#if showNext} {#if showNext}
<button <button
class="upper-part" class="upper-part"
@@ -52,19 +60,33 @@
navigate(Object.values($pages)?.find((o) => o.id == nextpage.page)?.path || '/') 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> <div class="lower">{nextpage?.name}</div>
</button>{/if} </button>{/if}
<div class="lower-part"> <div class="lower-part">
<div class="container"> <div class="container" style="">
<div class="links"> <div class="links">
<button>Datenschutz</button> <button
<button>Impressum</button> on:click="{() => {
$rerender = $rerender + 1
navigate('/datenschutz')
}}">Datenschutz</button
>
<button
on:click="{() => {
$rerender = $rerender + 1
navigate('/impressum')
}}">Impressum</button
>
</div> </div>
<div class="contact"> <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> </div>
</div> </div>
@@ -73,13 +95,17 @@
<style lang="less"> <style lang="less">
@import "../assets/css/main.less"; @import "../assets/css/main.less";
.footer { .footer {
margin-top: 80px; padding-top: 80px;
display: flex; display: flex;
position: relative; position: relative;
z-index: 1000; z-index: 1000;
flex-direction: column; flex-direction: column;
align-items: flex-end; align-items: flex-end;
color: @font-color-secondary; color: @font-color-secondary;
&.black-bg {
margin-top: -10px;
background-color: @bg-color-secondary;
}
.upper-part { .upper-part {
background-color: @bg-color-secondary; background-color: @bg-color-secondary;
padding: 10px 40px; padding: 10px 40px;
@@ -98,6 +124,7 @@
.lower { .lower {
color: @font-color-secondary; color: @font-color-secondary;
font-size: 22px; font-size: 22px;
font-family: "Libre Caslon Text", serif;
@media @tablet { @media @tablet {
font-size: 24px; font-size: 24px;
} }
@@ -111,11 +138,17 @@
display: flex; display: flex;
justify-content: center; justify-content: center;
.container { .container {
max-width: 1800px; max-width: 1400px;
width: 100%; width: 100%;
display: flex; display: flex;
padding: 0px 2.5vw;
flex-direction: column; flex-direction: column;
margin: 15px 0px;
padding: 15px 10px;
@media @tablet {
margin: 40px 0px;
padding: 30px 10px;
}
.links, .links,
.contact { .contact {
display: flex; display: flex;
@@ -130,7 +163,6 @@
} }
} }
@media @tablet { @media @tablet {
padding: 80px 2.5vw;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
.links, .links,

View File

@@ -1,12 +1,21 @@
<script lang="ts"> <script lang="ts">
import { navigate } from "svelte-routing/src/history" import { navigate } from "svelte-routing/src/history"
import { rerender } from "../../store"
export let active = false export let active = false
export let opened = false export let opened = false
</script> </script>
<div class="header" class:sticky="{!opened}"> <div class="header" class:sticky="{!opened}">
<div class="logo" on:keydown on:click="{() => navigate('/')}"> <div
class="logo"
on:keydown
on:click="{() => {
active = false
$rerender = $rerender + 1
navigate('/')
}}"
>
<img src="/media/Logo Quer.svg" alt="Logo Quer" /> <img src="/media/Logo Quer.svg" alt="Logo Quer" />
</div> </div>
<button class="menu" on:click="{() => (active = !active)}"> <button class="menu" on:click="{() => (active = !active)}">
@@ -29,8 +38,10 @@
.header { .header {
background-color: @bg-color; background-color: @bg-color;
width: 100%; width: 100%;
padding: 10px calc(2.5vw + 10px);
@media @tablet {
padding: 25.4px calc(2.5vw + 10px); padding: 25.4px calc(2.5vw + 10px);
}
display: flex; display: flex;
align-items: center; align-items: center;
@@ -41,7 +52,9 @@
cursor: pointer; cursor: pointer;
flex-grow: 0; flex-grow: 0;
flex-shrink: 1; flex-shrink: 1;
@media (max-height: 500px) {
max-width: 50%;
}
img { img {
width: 100%; width: 100%;
} }

View File

@@ -14,6 +14,7 @@
<div class="inner-container"> <div class="inner-container">
<div class="pages"> <div class="pages">
{#each $navigation.pages as page} {#each $navigation.pages as page}
{#if Object.values($pages)?.find((o) => o.id == page.page)?.path !== "/"}
<button <button
class="page underline" class="page underline"
on:click="{() => { on:click="{() => {
@@ -23,18 +24,34 @@
}}" }}"
> >
{page.name} {page.name}
</button> </button>{/if}
{/each} {/each}
</div> </div>
<div class="footer-infos"> <div class="footer-infos">
<div class="upper"> <div class="upper">
<button class="underline">Datenschutz</button> <button
<button class="underline">Impressum</button> class="underline"
on:click="{() => {
active = false
$rerender = $rerender + 1
navigate('/datenschutz')
}}">Datenschutz</button
>
<button
class="underline"
on:click="{() => {
active = false
$rerender = $rerender + 1
navigate('/impressum')
}}">Impressum</button
>
</div> </div>
<div class="lower"> <div class="lower">
<button>0711&nbsp;644&nbsp;700-0</button> <button>+49 (0) 711 655 700-0</button>
<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> </button>
</div> </div>
</div> </div>
@@ -54,7 +71,8 @@
top: 110vh; top: 110vh;
left: 0px; left: 0px;
right: 0px; right: 0px;
height: 100vh; height: 100%;
overflow-y: auto;
&.active { &.active {
top: 0px; top: 0px;
} }
@@ -160,6 +178,7 @@
.page { .page {
font-size: 1.6rem; font-size: 1.6rem;
color: @font-color-secondary; color: @font-color-secondary;
font-family: "Libre Caslon Text", serif;
} }
} }
@media @tablet { @media @tablet {

View File

@@ -59,7 +59,7 @@
navigation="{true}" navigation="{true}"
init="{false}" init="{false}"
autoplay="{{ autoplay="{{
delay: 4000, // 5000ms = 5s delay: 15000, // 5000ms = 5s
pauseOnMouseEnter: true, pauseOnMouseEnter: true,
}}" }}"
speed="600" speed="600"
@@ -105,33 +105,44 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
swiper-container { swiper-container {
max-width: 1800px; max-width: 1400px;
} }
.inner-container { .inner-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: flex-start; align-items: flex-start;
gap: 20px;
@media @tablet { @media @tablet {
align-items: center; align-items: center;
gap: initial;
} }
width: 100%; width: 100%;
height: fit-content; height: fit-content;
.titles { .titles {
padding: 0 5%; padding: 0 5%;
font-weight: normal; font-weight: 500;
h1 { h1 {
font-size: 2rem; font-size: 2rem;
padding: 10px 0px 0px 0px;
@media @tablet {
padding: 20px 0px; padding: 20px 0px;
}
margin: 10px 0px 20px 0px; margin: 10px 0px 20px 0px;
line-height: 1; line-height: 1;
font-weight: 500;
position: relative; position: relative;
} }
h2 { h2 {
font-size: 1.2rem !important; font-size: 0.9rem !important;
@media @tablet {
font-size: 1.6rem !important;
}
line-height: 1; line-height: 1;
font-family: "Libre Franklin", sans-serif;
font-weight: 500;
} }
} }
.description { .description {
@@ -149,15 +160,17 @@
@media @tablet { @media @tablet {
.titles { .titles {
font-weight: normal; font-weight: 500;
h1 { h1 {
font-size: 3.4rem; font-size: 3.5rem;
padding: 20px 20px; padding: 20px 20px;
margin: 20px 0px 40px 0px; margin: 20px 0px 40px 0px;
font-weight: 500;
} }
h2 { h2 {
font-size: 1.5rem; font-size: 1.3rem;
} }
font-weight: 500;
} }
.description { .description {
display: flex; display: flex;
@@ -175,14 +188,16 @@
@media @desktop { @media @desktop {
.titles { .titles {
font-weight: normal; font-weight: 500;
h1 { h1 {
font-size: 5rem; font-size: 5rem;
padding: 20px 0px; padding: 20px 0px;
margin: 20px 0px 40px 0px; margin: 20px 0px 40px 0px;
font-weight: 500;
} }
h2 { h2 {
font-size: 1.6rem; font-size: 1.6rem;
font-weight: 500;
} }
} }

View File

@@ -21,6 +21,7 @@
export let row: Row export let row: Row
export let pageId: string export let pageId: string
export let bright: boolean export let bright: boolean
export let isHP: boolean
function checkNestedPath() { function checkNestedPath() {
const pathSegments = location.pathname.split("/").filter((segment) => segment.length) const pathSegments = location.pathname.split("/").filter((segment) => segment.length)
@@ -32,15 +33,20 @@
return "" return ""
} }
$: console.log($pages)
let nestedPath = checkNestedPath() let nestedPath = checkNestedPath()
window.addEventListener("popstate", function (event) {
$rerender = $rerender + 1
})
</script> </script>
{#if Object.keys(row).length} {#if Object.keys(row).length}
{#if row.topTitle} {#if row.topTitle}
<h3 class:red="{row.topTitleRed}">{row.topTitle}</h3> <h3 class="{row.topTitleUpperCase ? 'hph3' : 'nmh3'}" class:red="{row.topTitleRed}">
{row.topTitle}
</h3>
{/if} {/if}
{#if nestedPath} {#if nestedPath}
<div class="top-header" style="display: flex; width: 100%; justify-content: space-between;">
<h3 <h3
style="cursor: pointer; display: flex; align-items: center; gap: 10px; line-height: 1.4;" style="cursor: pointer; display: flex; align-items: center; gap: 10px; line-height: 1.4;"
on:keydown on:keydown
@@ -51,6 +57,17 @@
> >
<img src="/media/arrow-l.svg" alt="arrow" /> Zurück zur Übersicht <img src="/media/arrow-l.svg" alt="arrow" /> Zurück zur Übersicht
</h3> </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}
{#if row.pageTitle} {#if row.pageTitle}
<h1>{row.pageTitle}</h1> <h1>{row.pageTitle}</h1>
@@ -59,10 +76,12 @@
<h2 class="">{row.title}</h2> <h2 class="">{row.title}</h2>
{/if} {/if}
{#if row.subTitle} {#if row.subTitle}
<h3>{row.subTitle}</h3> <h3 class="subheading">{row.subTitle}</h3>
{/if} {/if}
{#if row?.columns?.length}
<div <div
class="row" class="row"
class:twoToThree="{row.twoToThree}"
class:normalWrap="{row.flexWrapNormal}" class:normalWrap="{row.flexWrapNormal}"
class:dominant="{row.columns.some((col) => col.contentType == 'iconCycleCircle')}" class:dominant="{row.columns.some((col) => col.contentType == 'iconCycleCircle')}"
> >
@@ -107,7 +126,7 @@
{/if} {/if}
</div> </div>
{/each} {/each}
</div> </div>{/if}
{/if} {/if}
<style lang="less"> <style lang="less">
@@ -116,12 +135,35 @@
color: #fa00ff !important; color: #fa00ff !important;
} }
h3 { h3 {
font-weight: normal; font-weight: 500;
margin-bottom: 15px;
@media @tablet {
margin-bottom: 0px;
}
}
h2 {
font-weight: 500;
font-size: 1.7rem !important;
}
h1 {
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 { @media @tablet {
h3 { h3 {
font-size: 1.2rem; font-size: 1.3rem;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 10px; gap: 10px;
@@ -129,12 +171,25 @@
width: 40px; width: 40px;
margin-right: 10px; margin-right: 10px;
} }
&.subheading {
font-size: 1.8rem;
}
} }
h2 { h2 {
font-size: 2.3rem; font-size: 2rem !important;
font-weight: 500;
} }
h1 { h1 {
font-size: 4rem; font-size: 3.5rem;
font-weight: 500;
}
}
@media @desktop {
h2 {
font-size: 2.3rem !important;
}
h1 {
font-size: 5rem;
} }
} }
@@ -143,6 +198,8 @@
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
flex-wrap: wrap; flex-wrap: wrap;
gap: 20px;
&.dominant { &.dominant {
@media (max-width: 1024px) { @media (max-width: 1024px) {
flex-direction: row-reverse; flex-direction: row-reverse;
@@ -155,6 +212,7 @@
} }
} }
& > .col { & > .col {
max-width: 100%;
&.dominant { &.dominant {
@media (max-width: 1024px) { @media (max-width: 1024px) {
min-width: 80% !important; min-width: 80% !important;
@@ -167,9 +225,28 @@
@media @desktop { @media @desktop {
min-width: 30% !important; min-width: 30% !important;
} }
padding: 10px;
flex: 1; flex: 1;
min-width: 0; min-width: 0;
} }
&.twoToThree {
& > .col:nth-child(1) {
flex: 2 !important;
}
& > .col:nth-child(2) {
flex: 3 !important;
}
}
}
.hph3 {
text-transform: uppercase;
font-size: 0.7rem;
}
.nmh3 {
font-size: 0.9rem;
@media @tablet {
font-size: 1.6rem;
}
} }
</style> </style>

View File

@@ -45,14 +45,28 @@
{#if page} {#if page}
{#if path == "/"}<Homepage />{/if} {#if path == "/"}<Homepage />{/if}
{#each page.rows as row, i} {#each page.rows as row, i}
<div class="row" id="row-{i}"> <div
class="row"
id="row-{i}"
style="{path == '/' && i == page.rows.length - 1
? 'padding-bottom: 300px; margin-bottom: -40px;'
: ''} {row.row.noBottomMargin ? 'margin-bottom: 0px; padding-bottom: 0px;' : ''} {row.row
.noTopMargin
? 'margin-top: 0px; padding-top: 0px;'
: ''}"
>
{#if row.row.backgroundImage} {#if row.row.backgroundImage}
<div class="background-image"> <div class="background-image">
<img src="{`${apiBaseURL}page/${page.id}/${row.row.backgroundImage?.src}`}" alt="img" /> <img src="{`${apiBaseURL}page/${page.id}/${row.row.backgroundImage?.src}`}" alt="img" />
</div> </div>
{/if} {/if}
<div class="content" class:bright="{row.row.backgroundImage}"> <div class="content" class:bright="{row.row.backgroundImage}">
<Pagebuilder row="{row.row}" pageId="{page.id}" bright="{!!row.row.backgroundImage}" /> <Pagebuilder
isHP="{path == '/'}"
row="{row.row}"
pageId="{page.id}"
bright="{!!row.row.backgroundImage}"
/>
</div> </div>
</div> </div>
{/each} {/each}
@@ -68,15 +82,16 @@
justify-content: flex-start; justify-content: flex-start;
width: 100%; width: 100%;
position: relative; position: relative;
max-width: 100vw;
overflow-x: hidden; overflow: hidden;
gap: 10px; gap: 10px;
& > .row { & > .row {
padding: 10px; margin: 15px 0px;
padding-top: 30px; padding: 15px 10px;
@media @tablet { @media @tablet {
padding-top: 80px; margin: 40px 0px;
padding: 30px 10px;
} }
width: 100%; width: 100%;
position: relative; position: relative;
@@ -100,8 +115,8 @@
& > .content { & > .content {
width: 100%; width: 100%;
max-width: 1800px; max-width: 1400px;
padding: 0px 2.5vw; margin: 0px 2.5vw;
position: relative; position: relative;
&.bright { &.bright {
color: @font-color-secondary !important; color: @font-color-secondary !important;

View File

@@ -7,7 +7,7 @@
export let selected: boolean[] export let selected: boolean[]
let props let props
$: { $: {
props = chunkArray([...card.properties], 5) props = chunkArray([...card.properties], card.properties.length > 8 ? 5 : 4)
} }
function chunkArray(myArray, chunk_size): number[][] { function chunkArray(myArray, chunk_size): number[][] {
@@ -19,6 +19,7 @@
return results return results
} }
let hovered = "-1"
</script> </script>
<div class="card"> <div class="card">
@@ -31,16 +32,33 @@
'center'};" 'center'};"
> >
<div class="inner-container"> <div class="inner-container">
<div class="title" class:active="{card.properties.some((v, i) => selected[v])}"> <div
class="title"
class:active="{card.properties.some((v, i) => selected[v])}"
style="top: {card.verticalShift || 0}%; left: {card.horizontalShift || 0}%;"
>
{card.title} {card.title}
</div> </div>
<div class="properties"> <div class="properties" style="top: {card.verticalShift || 0}%; left: {card.horizontalShift || 0}%;">
{#each props as propertyRow, i (i)} {#each props as propertyRow, i (i)}
<div class="property-row"> <div
class="property-row"
style="grid-template-columns: repeat({propertyRow.length}, min(25px, 1.8vw));"
>
{#each propertyRow as property, j (j)} {#each propertyRow as property, j (j)}
<div class="collapsible-wrapper"> <div class="collapsible-wrapper">
<div class="property collapsible" class:selected="{selected[property]}"> <div
class="property collapsible"
class:hovered="{hovered == j + ' ' + i}"
class:selected="{selected[property]}"
on:mouseenter="{() => {
hovered = j + ' ' + i
}}"
on:mouseleave="{() => {
hovered = '-1'
}}"
>
<div class="short"> <div class="short">
{properties[property][0]} {properties[property][0]}
</div> </div>
@@ -61,15 +79,16 @@
.card { .card {
position: relative; position: relative;
height: fit-content; height: fit-content;
img { img {
display: block; display: block;
width: 100%; width: 100%;
} }
.short {
font-weight: 700;
}
.content { .content {
position: absolute; position: absolute;
&:hover {
z-index: 10000;
}
padding: 10px; padding: 10px;
top: 0px; top: 0px;
left: 0px; left: 0px;
@@ -80,21 +99,26 @@
height: 100%; height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.inner-container { .inner-container {
max-width: 170px; max-width: 200px;
&:hover { &:hover {
max-width: fit-content; max-width: fit-content;
} }
display: flex; display: flex;
width: fit-content; width: fit-content;
flex-direction: column; flex-direction: column;
gap: 20px; gap: 10px;
align-items: center; align-items: center;
.title { .title {
font-size: min(0.9vw, 14px); font-size: min(1.6vw, 14px);
position: relative;
z-index: 200;
padding: 2px 5px; padding: 2px 5px;
text-transform: uppercase;
@media @tablet { @media @tablet {
padding: 5px 10px; padding: 5px 10px;
font-size: min(1vw, 18px);
} }
font-weight: bold; font-weight: bold;
color: @font-color-secondary; color: @font-color-secondary;
@@ -107,23 +131,33 @@
.properties { .properties {
display: none; display: none;
position: relative;
@media @desktop { @media @desktop {
display: flex; display: flex;
} }
flex-direction: column; flex-direction: column;
gap: 5px; gap: 5px;
.property-row { .property-row {
display: flex; display: grid;
gap: 5px; grid-gap: 5px;
@media (max-width: 1000px) {
grid-gap: 2px;
}
.property { .property {
z-index: 99;
&:hover {
z-index: 9999;
}
position: relative;
left: 0px;
cursor: pointer; cursor: pointer;
overflow: hidden; overflow: hidden;
width: 2vw; width: 1.8vw;
max-width: 30px; max-width: 25px;
font-size: min(0.7vw, 14px); font-size: min(0.5vw, 11px);
height: 2vw; height: 1.8vw;
max-height: 30px; max-height: 25px;
border-radius: 15px; border-radius: 15px;
border: 2px solid #4f4f4f; border: 2px solid #4f4f4f;
color: #4f4f4f; color: #4f4f4f;
@@ -133,6 +167,8 @@
align-items: center; align-items: center;
transition: 0.5s width ease-in, 0.5s max-width ease-in, 0.5s background-color ease-in, transition: 0.5s width ease-in, 0.5s max-width ease-in, 0.5s background-color ease-in,
0.5s color ease-in; 0.5s color ease-in;
display: flex;
&.selected { &.selected {
background-color: @bg-color !important; background-color: @bg-color !important;
color: @font-color !important; color: @font-color !important;
@@ -142,17 +178,21 @@
overflow: hidden; overflow: hidden;
background-color: @bg-color-secondary; background-color: @bg-color-secondary;
color: @font-color-secondary; color: @font-color-secondary;
transition: 0.5s width ease-in, 0.5s background-color ease-in, 0.5s color ease-in; transition: 0.5s width ease-in, 0.5s background-color ease-in, 0.5s color ease-in,
0.5s padding ease-in;
white-space: nowrap; white-space: nowrap;
} }
&:hover { &.hovered {
width: fit-content; width: fit-content;
z-index: 9999;
max-width: 1000px; max-width: 1000px;
padding: 5px; padding: 5px;
background-color: white; background-color: white;
.short {
padding-left: 8px;
}
.long { .long {
padding-left: 15px; padding: 0px 10px;
max-width: fit-content; max-width: fit-content;
background-color: @bg-color; background-color: @bg-color;
color: @font-color; color: @font-color;

View File

@@ -34,6 +34,8 @@
border: 2px solid @bg-color; border: 2px solid @bg-color;
.abbriviation { .abbriviation {
padding-right: 10px; padding-right: 10px;
padding-left: 8px;
font-weight: 700;
} }
.name { .name {
padding-right: 10px; padding-right: 10px;

View File

@@ -11,7 +11,6 @@
["IN", "Infrastruktur"], ["IN", "Infrastruktur"],
["W", "Waldwirtschaft"], ["W", "Waldwirtschaft"],
["IE", "Immobilien-Entwicklung"], ["IE", "Immobilien-Entwicklung"],
["R", "Renten"], ["R", "Renten"],
["VC", "Venture Capital"], ["VC", "Venture Capital"],
["PD", "Private Debt"], ["PD", "Private Debt"],
@@ -36,12 +35,18 @@
} }
</script> </script>
<div class="worldcard"> <div style="display: flex; flex-direction: column; width: 100%; align-items: center;">
<div class="worldcard">
<div class="worldcard"> <div class="worldcard">
{#each col.worldCard.row as row} {#each col.worldCard.row as row}
<div class="wc-row"> <div class="wc-row">
{#each row.cards as card} {#each row.cards as card}
<Card card="{card}" properties="{availableProperties}" pageId="{pageId}" selected="{selected}" /> <Card
card="{card}"
properties="{availableProperties}"
pageId="{pageId}"
selected="{selected}"
/>
{/each} {/each}
</div> </div>
{/each} {/each}
@@ -63,6 +68,7 @@
</div> </div>
{/each} {/each}
</div> </div>
</div>
</div> </div>
<style lang="less"> <style lang="less">
@@ -70,11 +76,11 @@
.worldcard { .worldcard {
line-height: 1 !important; line-height: 1 !important;
font-size: 0.7rem; font-size: 0.8rem;
display: flex; display: flex;
align-items: flex-start; align-items: center;
flex-direction: column; flex-direction: column;
width: 100%; width: 1170px;
max-width: 95vw; max-width: 95vw;
& > .worldcard { & > .worldcard {

View File

@@ -1,5 +1,14 @@
<script lang="ts"> <script lang="ts">
export let col: Column export let col: Column
// A function to compare first names and sort the array
const sortByFirstName = (a, b) => {
const nameA = a.name.split(" ")[0] // Extracts the first name from "First Last"
const nameB = b.name.split(" ")[0]
return nameA.localeCompare(nameB)
}
col.boxList.boxes.sort(sortByFirstName) // Sorts the array in place
</script> </script>
<div class="boxList"> <div class="boxList">
@@ -14,7 +23,6 @@
@import "../../assets/css/main.less"; @import "../../assets/css/main.less";
.boxList { .boxList {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 20px; gap: 20px;
@@ -24,6 +32,5 @@
color: @font-color-secondary; color: @font-color-secondary;
font-weight: bold; font-weight: bold;
} }
} }
</style> </style>

View File

@@ -44,7 +44,7 @@
</div> </div>
<div class="details"> <div class="details">
<em>{nE.title}</em> <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 <button class="more">mehr</button></a
> >
</div> </div>
@@ -94,7 +94,7 @@
border: none; border: none;
height: 36px; height: 36px;
padding: 2px 15px; padding: 2px 15px;
font-size: 14px; font-size: 20px;
font-weight: bold; font-weight: bold;
cursor: pointer; cursor: pointer;
} }

View File

@@ -37,7 +37,11 @@
<div class="content" class:closed="{i !== opened}"> <div class="content" class:closed="{i !== opened}">
{@html box.text} {@html box.text}
{#if box.emailButton} {#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> <button> bewerben </button>
</a> </a>
{/if} {/if}

View File

@@ -6,6 +6,7 @@
</script> </script>
<div class="iconBlock"> <div class="iconBlock">
{#each col.iconBlocks as icon} {#each col.iconBlocks as icon}
<div class="icon"> <div class="icon">
<img src="{`${apiBaseURL}page/${pageId}/${icon.icon?.src}`}" alt="img" /> <img src="{`${apiBaseURL}page/${pageId}/${icon.icon?.src}`}" alt="img" />
@@ -24,37 +25,44 @@
justify-content: start; justify-content: start;
flex-wrap: wrap; flex-wrap: wrap;
.icon { .icon {
margin: 30px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
width: 150px;
width: 80px; gap: 10px;
gap: 8px;
max-width: 45%; max-width: 45%;
flex-grow: 1; flex-grow: 1;
font-size: 0.9rem;
margin: 20px 0px;
@media @tablet { @media @tablet {
max-width: initial; max-width: initial;
flex-grow: initial; flex-grow: initial;
width: 107px; width: 160px;
gap: 20px; }
@media @desktop {
width: 213px;
} }
img { img {
width: 100%; width: 75%;
height: auto; height: auto;
} }
.text { .text {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 10px;
em { em {
text-align: center; text-align: center;
font-size: 2.2rem; font-size: 2.2rem;
font-family: "Libre Caslon Text", serif; font-family: "Libre Caslon Text", serif;
font-style: normal;
} }
p { p {
text-align: center; text-align: center;
font-weight: bold; font-weight: bold;
font-size: 1rem;
@media (max-width: 1050px) {
font-size: 0.7rem;
}
} }
} }
} }

View File

@@ -7,7 +7,7 @@
setInterval(() => { setInterval(() => {
active += 1 active += 1
if (active == col.iconCycleSquare.boxes.length) active = 0 if (active == col.iconCycleSquare.boxes.length) active = 0
}, 1000) }, 1250)
</script> </script>
<div class="iconCycleSquares"> <div class="iconCycleSquares">
@@ -15,8 +15,10 @@
<div class="box" id="box{i}" class:active="{i == active}"> <div class="box" id="box{i}" class:active="{i == active}">
<div class="content"> <div class="content">
<div class="icon"> <div class="icon">
<svg stroke="{i == active ? 'black' : 'white'}" data-src="{apiBaseURL}page/{pageId}/{box.icon?.src}" <svg
></svg> stroke="{i == active ? 'black' : 'white'}"
fill="{i == active ? 'black' : 'white'}"
data-src="{apiBaseURL}page/{pageId}/{box.icon?.src}"></svg>
</div> </div>
<div class="text"> <div class="text">
{box.text} {box.text}
@@ -31,10 +33,12 @@
.iconCycleSquares { .iconCycleSquares {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: flex-start;
gap: 10px; gap: 10px;
font-size: 0.8rem; font-size: 0.8rem;
transition: background-color 600ms;
@media @tablet { @media @tablet {
gap: 20px;
font-size: 1rem; font-size: 1rem;
} }
.box { .box {
@@ -44,27 +48,34 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
color: @font-color-secondary; color: @font-color-secondary;
padding: 10px;
&.active { &.active {
background-color: @bg-color; background-color: @bg-color;
color: @font-color; color: @font-color;
} }
width: 140px; aspect-ratio: 1/1;
height: 150px; width: calc((100% / 2) - 10px);
@media (min-width: 950px) and (max-width: 1450px) {
width: calc((100% / 4) - 10px);
}
@media (min-width: 1450px) {
width: calc((100% / 5) - 10px);
}
.content { .content {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
@media @tablet {
gap: 20px;
}
.text { .text {
width: 100%; width: 100%;
display: flex; display: flex;
justify-content: center; justify-content: center;
text-align: center; text-align: center;
font-family: "Libre Caslon Text", serif;
} }
} }
@media @tablet {
width: 260px;
height: 260px;
}
} }
} }
</style> </style>

View File

@@ -7,18 +7,18 @@
let count = col.iconCycleCircle.boxes.length // The number of surrounding circles. let count = col.iconCycleCircle.boxes.length // The number of surrounding circles.
let angleStep = 360 / count let angleStep = 360 / count
let radius = 360 let radius = 310
let circles = [] let circles = []
onMount(() => { onMount(() => {
for (let i = 0; i < count; i++) { for (let i = 0; i < count; i++) {
let angle = angleStep * i * (Math.PI / 180) // Convert to radians let angle = (angleStep * i - 90) * (Math.PI / 180) // Convert to radians
circles.push({ circles.push({
x: radius * Math.cos(angle), x: radius * Math.cos(angle),
y: radius * Math.sin(angle), y: radius * Math.sin(angle),
rotation: angleStep * i - 90, // subtract 90 to point towards the circle rotation: angleStep * i + 180, // subtract 90 to point towards the circle
}) })
} }
circles = circles circles = circles
@@ -46,22 +46,23 @@
<div class="number" style="transform: rotate(calc( -1 * {rotation}deg - 90deg ))">{i + 1}</div> <div class="number" style="transform: rotate(calc( -1 * {rotation}deg - 90deg ))">{i + 1}</div>
</div> </div>
<div class="content" style="transform: translate(calc({x}px / 15) , calc({y}px / 15))"> <div class="content" style="transform: translate(calc({x}px / 25) , calc({y}px / 25))">
<div class="icon"> <div class="icon">
<svg <svg
id="mySvgObject{i}" id="mySvgObject{i}"
stroke="{i == focused ? 'white' : 'black'}" stroke="{i == focused ? 'white' : 'black'}"
fill="{i == focused ? 'white' : 'black'}"
data-src="{apiBaseURL}page/{pageId}/{col.iconCycleCircle?.boxes[i]?.icon?.src}"></svg> data-src="{apiBaseURL}page/{pageId}/{col.iconCycleCircle?.boxes[i]?.icon?.src}"></svg>
</div> </div>
<div class="text"> <div class="text" style="text-align: center;">
{col.iconCycleCircle?.boxes[i]?.text} {@html col.iconCycleCircle?.boxes[i]?.text}
</div> </div>
</div> </div>
</div> </div>
<div <div
class="arrow" class="arrow"
style="transform: translate(calc(90px + {(x * 0.8) / 2}px - 10px ), calc(90px + {(y * 0.8) / style="transform-origin: center; transform: translate(calc(90px + {(x * 0.9) /
2}px - 37.5px)) rotate(calc({rotation}deg - 90deg))" 2}px - 5px ), calc(90px + {(y * 0.9) / 2}px - 37.5px)) rotate(calc({rotation}deg - 90deg))"
> >
<img src="/media/arrow-l-fat.svg" alt="arrow" /> <img src="/media/arrow-l-fat.svg" alt="arrow" />
</div> </div>
@@ -77,6 +78,8 @@
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
justify-content: center; justify-content: center;
transform-origin: top;
margin-top: -60px;
@media (max-width: 1430px) { @media (max-width: 1430px) {
transform: scale(0.9); transform: scale(0.9);
@@ -86,14 +89,17 @@
@media (max-width: 1290px) { @media (max-width: 1290px) {
transform: scale(0.7); transform: scale(0.7);
height: 700px; height: 700px;
margin-top: 40px;
} }
@media (max-width: 680px) { @media (max-width: 680px) {
transform: scale(0.5); transform: scale(0.5);
height: 500px; height: 500px;
margin-top: 80px;
} }
@media (max-width: 520px) { @media (max-width: 520px) {
transform: scale(0.37); transform: scale(0.37);
margin-top: 120px;
height: 370px; height: 370px;
} }
.main-circle { .main-circle {
@@ -113,11 +119,12 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
z-index: 120; z-index: 120;
font-size: 1.2rem; font-size: 0.8rem;
} }
.circle { .circle {
position: absolute; position: absolute;
width: 180px; width: 180px;
overflow: hidden;
height: 180px; height: 180px;
background: rgba(255, 255, 255, 0); background: rgba(255, 255, 255, 0);
border: 4px solid @bg-color-secondary; border: 4px solid @bg-color-secondary;
@@ -130,14 +137,17 @@
display: flex; display: flex;
line-height: 1; line-height: 1;
flex-direction: column; flex-direction: column;
width: 100%; transform-origin: center;
height: 100%; width: 95%;
border-radius: 50%;
height: 95%;
align-items: center; align-items: center;
font-size: 1.2rem; font-size: 0.8rem;
justify-content: center; justify-content: center;
padding: 15px;
svg { svg {
width: 100%; width: 80%;
height: 100%; height: 80%;
} }
} }
@@ -161,7 +171,8 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 30px; /* oder eine passende Größe */ font-size: 26px; /* oder eine passende Größe */
font-weight: 700;
color: white; color: white;
} }
&::before { &::before {
@@ -197,7 +208,6 @@
position: absolute; position: absolute;
width: 10px; width: 10px;
height: 75px; height: 75px;
transform-origin: center; transform-origin: center;
} }
} }

View File

@@ -12,7 +12,7 @@
<div class="icons"> <div class="icons">
{#each col.icons as icon} {#each col.icons as icon}
<div class="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" /> <img src="{`${apiBaseURL}page/${pageId}/${icon.icon?.src}`}" alt="img" />
</a> </a>
</div> </div>

View File

@@ -15,7 +15,7 @@
border: none; border: none;
height: 36px; height: 36px;
padding: 2px 15px; padding: 2px 15px;
font-size: 14px; font-size: 20px;
font-weight: bold; font-weight: bold;
} }
.bright { .bright {

View File

@@ -48,11 +48,11 @@
left: 0px; left: 0px;
padding: 7px 10px; padding: 7px 10px;
color: @font-color-secondary; color: @font-color-secondary;
font-family: "LibreCaslonText"; font-family: "Libre Caslon Text", sans-serif;
font-size: 1.2rem; font-size: 1.15rem;
top: 0px; top: 0px;
height: 100px; height: 100px;
width: 320px; width: 365px;
z-index: 9; z-index: 9;
background-color: @bg-color-secondary; background-color: @bg-color-secondary;
} }

View File

@@ -2,10 +2,11 @@
import { navigate } from "svelte-routing/src/history" import { navigate } from "svelte-routing/src/history"
import { openExtendableNr, pages, rerender, scrollToRowNr } from "../../store" import { openExtendableNr, pages, rerender, scrollToRowNr } from "../../store"
export let col: Column export let col: Column
let focused = -1
</script> </script>
<div class="link-container"> <div class="link-container">
{#each col.pageLinkBlocks as link} {#each col.pageLinkBlocks as link, i}
{#if isNaN(link.extendableRowNr)} {#if isNaN(link.extendableRowNr)}
<button <button
class="page-ref" class="page-ref"
@@ -19,6 +20,12 @@
</button> </button>
{:else} {:else}
<button <button
on:mouseenter="{() => {
focused = i
}}"
on:mouseleave="{() => {
focused = -1
}}"
class="row-ref fill" class="row-ref fill"
on:click="{() => { on:click="{() => {
$rerender = $rerender + 1 $rerender = $rerender + 1
@@ -30,7 +37,11 @@
<div> <div>
{link.name} {link.name}
</div> </div>
<img src="/media/arrow-r.svg" alt="arrow" /> <svg
data-src="/media/arrow-r.svg"
stroke="{i == focused ? '#fff' : 'black'}"
fill="{i == focused ? '#fff' : 'black'}"
style="z-index: 9999; position: relative;"></svg>
</button> </button>
{/if} {/if}
{/each} {/each}
@@ -43,13 +54,19 @@
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: flex-start;
gap: 20px; gap: 20px;
button { button {
background-color: @bg-color; background-color: @bg-color;
color: @font-color; color: @font-color;
padding: 2px 15px; padding: 2px 15px;
font-size: 14px; font-size: 20px;
font-weight: bold; font-weight: bold;
cursor: pointer; cursor: pointer;
font-size: 0.7rem;
@media @tablet {
font-size: initial;
}
} }
.row-ref { .row-ref {

View File

@@ -34,7 +34,7 @@
/* Place your styles here */ /* Place your styles here */
position: fixed; position: fixed;
bottom: 5px; bottom: 5px;
z-index: 100; z-index: 9999;
transform: scale(0.5); transform: scale(0.5);
right: 5px; right: 5px;
@media @tablet { @media @tablet {

View File

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