Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c52a132d62 | |||
| 11f735bbdf | |||
| c81dae0b7b | |||
| 716ece1c6c | |||
| e0ccf1cdfb | |||
| 6a6fbb6f19 | |||
| 6b6b2b8ece | |||
| 9f412d81a8 | |||
| 9c401f13de | |||
| 5857404ac1 | |||
| 34a96f8aef | |||
| 4e6f3f29cf | |||
| 1bd516fbe4 | |||
| 4d0e3433a6 | |||
| ee9cde1ed0 | |||
| 33cf701034 | |||
| 1fae5edee3 |
@@ -1,9 +1,13 @@
|
|||||||
node_modules
|
# Exclude all binary/dependency folders recursively
|
||||||
.next
|
**/node_modules
|
||||||
out
|
**/.pnpm-store
|
||||||
dist
|
**/.git
|
||||||
*.log
|
**/.next
|
||||||
.git
|
**/dist
|
||||||
|
**/out
|
||||||
|
**/*.log
|
||||||
|
|
||||||
|
# Specific exclusions for this project
|
||||||
.DS_Store
|
.DS_Store
|
||||||
cloned-websites
|
cloned-websites
|
||||||
storage
|
storage
|
||||||
@@ -11,3 +15,11 @@ storage
|
|||||||
verify_ci
|
verify_ci
|
||||||
pnpm_install_log.txt
|
pnpm_install_log.txt
|
||||||
full_tree.json
|
full_tree.json
|
||||||
|
backups
|
||||||
|
data
|
||||||
|
|
||||||
|
# Ensure we don't copy the sibling's build artifacts either
|
||||||
|
_at-mintel/**/node_modules
|
||||||
|
_at-mintel/**/dist
|
||||||
|
_at-mintel/**/.next
|
||||||
|
_at-mintel/.git
|
||||||
|
|||||||
@@ -113,21 +113,7 @@ jobs:
|
|||||||
echo "short_sha=$SHORT_SHA"
|
echo "short_sha=$SHORT_SHA"
|
||||||
} >> "$GITHUB_OUTPUT"
|
} >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
# ⏳ Wait for Upstream Packages/Images if Tagged
|
|
||||||
if [[ "${{ github.ref_type }}" == "tag" ]]; then
|
|
||||||
echo "🔎 Checking for @mintel dependencies in package.json..."
|
|
||||||
UPSTREAM_VERSION=$(grep -o '"@mintel/.*": "[^"]*"' package.json | head -1 | cut -d'"' -f4 | sed 's/\^//; s/\~//')
|
|
||||||
TAG_TO_WAIT="v$UPSTREAM_VERSION"
|
|
||||||
|
|
||||||
if [[ -n "$UPSTREAM_VERSION" && "$UPSTREAM_VERSION" != "workspace:"* ]]; then
|
|
||||||
echo "⏳ This release depends on @mintel v$UPSTREAM_VERSION. Waiting for upstream build..."
|
|
||||||
curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
|
|
||||||
"https://git.infra.mintel.me/mmintel/at-mintel/raw/branch/main/packages/infra/scripts/wait-for-upstream.sh" > wait-for-upstream.sh
|
|
||||||
chmod +x wait-for-upstream.sh
|
|
||||||
|
|
||||||
GITEA_TOKEN=${{ secrets.GITHUB_TOKEN }} ./wait-for-upstream.sh "mmintel/at-mintel" "$TAG_TO_WAIT"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
else
|
||||||
echo "target=skip" >> "$GITHUB_OUTPUT"
|
echo "target=skip" >> "$GITHUB_OUTPUT"
|
||||||
fi
|
fi
|
||||||
@@ -299,8 +285,15 @@ jobs:
|
|||||||
perl -pi -e 's/link:\.\/_at-mintel\/packages\/pdf"/link:.\/_at-mintel\/packages\/pdf-library"/g' package.json
|
perl -pi -e 's/link:\.\/_at-mintel\/packages\/pdf"/link:.\/_at-mintel\/packages\/pdf-library"/g' package.json
|
||||||
perl -pi -e 's/"\@mintel\/([^"]+)"\s*:\s*"[^"]+"/"\@mintel\/$1": "link:..\/\.\.\/_at-mintel\/packages\/$1"/g' apps/web/package.json
|
perl -pi -e 's/"\@mintel\/([^"]+)"\s*:\s*"[^"]+"/"\@mintel\/$1": "link:..\/\.\.\/_at-mintel\/packages\/$1"/g' apps/web/package.json
|
||||||
perl -pi -e 's/link:\.\.\/\.\.\/_at-mintel\/packages\/pdf"/link:..\/\.\.\/_at-mintel\/packages\/pdf-library"/g' apps/web/package.json
|
perl -pi -e 's/link:\.\.\/\.\.\/_at-mintel\/packages\/pdf"/link:..\/\.\.\/_at-mintel\/packages\/pdf-library"/g' apps/web/package.json
|
||||||
|
|
||||||
|
- name: 🧹 Free Disk Space
|
||||||
|
run: |
|
||||||
|
docker builder prune -af || true
|
||||||
|
docker image prune -af || true
|
||||||
|
|
||||||
- name: 🐳 Set up Docker Buildx
|
- name: 🐳 Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
- name: 🔐 Registry Login
|
- name: 🔐 Registry Login
|
||||||
run: |
|
run: |
|
||||||
echo "${{ secrets.REGISTRY_PASS }}" | docker login registry.infra.mintel.me -u "${{ secrets.REGISTRY_USER }}" --password-stdin
|
echo "${{ secrets.REGISTRY_PASS }}" | docker login registry.infra.mintel.me -u "${{ secrets.REGISTRY_USER }}" --password-stdin
|
||||||
@@ -318,8 +311,8 @@ jobs:
|
|||||||
DIRECTUS_URL=${{ needs.prepare.outputs.directus_url }}
|
DIRECTUS_URL=${{ needs.prepare.outputs.directus_url }}
|
||||||
NPM_TOKEN=${{ secrets.NPM_TOKEN }}
|
NPM_TOKEN=${{ secrets.NPM_TOKEN }}
|
||||||
tags: registry.infra.mintel.me/mintel/mintel.me:${{ needs.prepare.outputs.image_tag }}
|
tags: registry.infra.mintel.me/mintel/mintel.me:${{ needs.prepare.outputs.image_tag }}
|
||||||
cache-from: type=registry,ref=registry.infra.mintel.me/mintel/mintel.me:buildcache
|
cache-from: type=registry,ref=registry.infra.mintel.me/mintel/mintel.me:buildcache-${{ needs.prepare.outputs.target }}
|
||||||
cache-to: type=registry,ref=registry.infra.mintel.me/mintel/mintel.me:buildcache,mode=max
|
cache-to: type=registry,ref=registry.infra.mintel.me/mintel/mintel.me:buildcache-${{ needs.prepare.outputs.target }},mode=max
|
||||||
secrets: |
|
secrets: |
|
||||||
NPM_TOKEN=${{ secrets.NPM_TOKEN }}
|
NPM_TOKEN=${{ secrets.NPM_TOKEN }}
|
||||||
|
|
||||||
@@ -332,17 +325,16 @@ jobs:
|
|||||||
chmod 600 ~/.ssh/id_ed25519
|
chmod 600 ~/.ssh/id_ed25519
|
||||||
ssh-keyscan -H alpha.mintel.me >> ~/.ssh/known_hosts 2>/dev/null
|
ssh-keyscan -H alpha.mintel.me >> ~/.ssh/known_hosts 2>/dev/null
|
||||||
echo "Re-running docker build with plain progress to capture exact logs..."
|
echo "Re-running docker build with plain progress to capture exact logs..."
|
||||||
echo "${{ steps.discover_token.outputs.token }}" | docker login git.infra.mintel.me -u "${{ steps.discover_token.outputs.user }}" --password-stdin > login.log 2>&1
|
echo "${{ secrets.NPM_TOKEN }}" > /tmp/npm_token.txt
|
||||||
echo "${{ steps.discover_token.outputs.token }}" > /tmp/npm_token.txt
|
|
||||||
docker build \
|
docker build \
|
||||||
--build-arg NEXT_PUBLIC_BASE_URL=${{ needs.prepare.outputs.next_public_url }} \
|
--build-arg NEXT_PUBLIC_BASE_URL=${{ needs.prepare.outputs.next_public_url }} \
|
||||||
--build-arg NEXT_PUBLIC_TARGET=${{ needs.prepare.outputs.target }} \
|
--build-arg NEXT_PUBLIC_TARGET=${{ needs.prepare.outputs.target }} \
|
||||||
--build-arg DIRECTUS_URL=${{ needs.prepare.outputs.directus_url }} \
|
--build-arg DIRECTUS_URL=${{ needs.prepare.outputs.directus_url }} \
|
||||||
--build-arg NPM_TOKEN=${{ steps.discover_token.outputs.token }} \
|
--build-arg NPM_TOKEN=${{ secrets.NPM_TOKEN }} \
|
||||||
--secret id=NPM_TOKEN,src=/tmp/npm_token.txt \
|
--secret id=NPM_TOKEN,src=/tmp/npm_token.txt \
|
||||||
--progress plain \
|
--progress plain \
|
||||||
-t temp-image . > docker_build_failed.log 2>&1
|
-t temp-image . > docker_build_failed.log 2>&1
|
||||||
cat login.log >> docker_build_failed.log
|
cat login.log >> docker_build_failed.log || true
|
||||||
scp docker_build_failed.log root@alpha.mintel.me:/root/docker_build_failed.log
|
scp docker_build_failed.log root@alpha.mintel.me:/root/docker_build_failed.log
|
||||||
# JOB 4: Deploy
|
# JOB 4: Deploy
|
||||||
# ──────────────────────────────────────────────────────────────────────────────
|
# ──────────────────────────────────────────────────────────────────────────────
|
||||||
|
|||||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -56,4 +56,8 @@ apps/web/out/estimations/
|
|||||||
# Backups
|
# Backups
|
||||||
backups/
|
backups/
|
||||||
|
|
||||||
.turbo
|
.turbo
|
||||||
|
# Manual build artifacts
|
||||||
|
_at-mintel/
|
||||||
|
local_build_*.log
|
||||||
|
*.tar
|
||||||
|
|||||||
13
Dockerfile
13
Dockerfile
@@ -19,16 +19,18 @@ ENV CI=true
|
|||||||
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json .npmrc* ./
|
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json .npmrc* ./
|
||||||
COPY apps/web/package.json ./apps/web/package.json
|
COPY apps/web/package.json ./apps/web/package.json
|
||||||
# Copy sibling monorepo for linked dependencies (cloned during CI)
|
# Copy sibling monorepo for linked dependencies (cloned during CI)
|
||||||
COPY _at-mintel* ./_at-mintel/
|
# Placing it at root to match the ../../../at-mintel/ links in package.json
|
||||||
|
COPY _at-mintel* /at-mintel/
|
||||||
|
|
||||||
|
|
||||||
# Install dependencies with cache mount and dynamic .npmrc (High Fidelity pattern)
|
# Install dependencies with cache mount and dynamic .npmrc (High Fidelity pattern)
|
||||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
|
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
|
||||||
--mount=type=secret,id=NPM_TOKEN \
|
--mount=type=secret,id=NPM_TOKEN \
|
||||||
export NPM_TOKEN=$(cat /run/secrets/NPM_TOKEN 2>/dev/null || echo $NPM_TOKEN) && \
|
export NPM_TOKEN=$(cat /run/secrets/NPM_TOKEN 2>/dev/null || echo $NPM_TOKEN) && \
|
||||||
echo "@mintel:registry=https://git.infra.mintel.me/api/packages/mmintel/npm/" > .npmrc && \
|
echo "@mintel:registry=https://npm.infra.mintel.me" > .npmrc && \
|
||||||
echo "//git.infra.mintel.me/api/packages/mmintel/npm/:_authToken=\${NPM_TOKEN}" >> .npmrc && \
|
echo "//npm.infra.mintel.me/:_authToken=\"\${NPM_TOKEN}\"" >> .npmrc && \
|
||||||
echo "always-auth=true" >> .npmrc && \
|
echo "always-auth=true" >> .npmrc && \
|
||||||
cd _at-mintel && pnpm install --no-frozen-lockfile && pnpm build && \
|
cd /at-mintel && pnpm install --no-frozen-lockfile && pnpm build && \
|
||||||
cd /app && pnpm install --no-frozen-lockfile && \
|
cd /app && pnpm install --no-frozen-lockfile && \
|
||||||
rm .npmrc
|
rm .npmrc
|
||||||
|
|
||||||
@@ -48,8 +50,9 @@ WORKDIR /app
|
|||||||
COPY --from=builder /app/apps/web/public ./apps/web/public
|
COPY --from=builder /app/apps/web/public ./apps/web/public
|
||||||
COPY --from=builder /app/apps/web/.next/standalone ./
|
COPY --from=builder /app/apps/web/.next/standalone ./
|
||||||
COPY --from=builder /app/apps/web/.next/static ./apps/web/.next/static
|
COPY --from=builder /app/apps/web/.next/static ./apps/web/.next/static
|
||||||
COPY --from=builder /app/apps/web/.next/cache ./apps/web/.next/cache
|
|
||||||
|
|
||||||
|
# Explicitly copy Payload dynamically generated importMap.js excluded by Standalone tracing
|
||||||
|
COPY --from=builder /app/apps/web/app/(payload)/admin/importMap.js ./apps/web/app/(payload)/admin/importMap.js
|
||||||
# Start from the app directory to ensure references solve correctly
|
# Start from the app directory to ensure references solve correctly
|
||||||
WORKDIR /app/apps/web
|
WORKDIR /app/apps/web
|
||||||
CMD ["node", "server.js"]
|
CMD ["node", "server.js"]
|
||||||
|
|||||||
@@ -1 +1,117 @@
|
|||||||
export const importMap = {};
|
import { AiMediaButtons as AiMediaButtons_1d402a78164f07306f77dce953e62e11 } from "@mintel/payload-ai/components/AiMediaButtons";
|
||||||
|
import { OptimizeButton as OptimizeButton_338ff118e214cff355f6d710d1a381fb } from "@mintel/payload-ai/components/OptimizeButton";
|
||||||
|
import { GenerateSlugButton as GenerateSlugButton_5baeea8510d263708dd253e86d55e0b4 } from "@mintel/payload-ai/components/FieldGenerators/GenerateSlugButton";
|
||||||
|
import { default as default_76cec558bd86098fa1dab70b12eb818f } from "@/src/payload/components/TagSelector";
|
||||||
|
import { GenerateThumbnailButton as GenerateThumbnailButton_e5e8c00f1c031f15175fef0ff67513dc } from "@mintel/payload-ai/components/FieldGenerators/GenerateThumbnailButton";
|
||||||
|
import { RscEntryLexicalCell as RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e } from "@payloadcms/richtext-lexical/rsc";
|
||||||
|
import { RscEntryLexicalField as RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e } from "@payloadcms/richtext-lexical/rsc";
|
||||||
|
import { LexicalDiffComponent as LexicalDiffComponent_44fe37237e0ebf4470c9990d8cb7b07e } from "@payloadcms/richtext-lexical/rsc";
|
||||||
|
import { BlocksFeatureClient as BlocksFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from "@payloadcms/richtext-lexical/client";
|
||||||
|
import { AiFieldButton as AiFieldButton_9125bc0af442fbb1889d8de3dff98501 } from "@mintel/payload-ai/components/FieldGenerators/AiFieldButton";
|
||||||
|
import { InlineToolbarFeatureClient as InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from "@payloadcms/richtext-lexical/client";
|
||||||
|
import { HorizontalRuleFeatureClient as HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from "@payloadcms/richtext-lexical/client";
|
||||||
|
import { UploadFeatureClient as UploadFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from "@payloadcms/richtext-lexical/client";
|
||||||
|
import { BlockquoteFeatureClient as BlockquoteFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from "@payloadcms/richtext-lexical/client";
|
||||||
|
import { RelationshipFeatureClient as RelationshipFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from "@payloadcms/richtext-lexical/client";
|
||||||
|
import { LinkFeatureClient as LinkFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from "@payloadcms/richtext-lexical/client";
|
||||||
|
import { ChecklistFeatureClient as ChecklistFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from "@payloadcms/richtext-lexical/client";
|
||||||
|
import { OrderedListFeatureClient as OrderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from "@payloadcms/richtext-lexical/client";
|
||||||
|
import { UnorderedListFeatureClient as UnorderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from "@payloadcms/richtext-lexical/client";
|
||||||
|
import { IndentFeatureClient as IndentFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from "@payloadcms/richtext-lexical/client";
|
||||||
|
import { AlignFeatureClient as AlignFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from "@payloadcms/richtext-lexical/client";
|
||||||
|
import { HeadingFeatureClient as HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from "@payloadcms/richtext-lexical/client";
|
||||||
|
import { ParagraphFeatureClient as ParagraphFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from "@payloadcms/richtext-lexical/client";
|
||||||
|
import { InlineCodeFeatureClient as InlineCodeFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from "@payloadcms/richtext-lexical/client";
|
||||||
|
import { SuperscriptFeatureClient as SuperscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from "@payloadcms/richtext-lexical/client";
|
||||||
|
import { SubscriptFeatureClient as SubscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from "@payloadcms/richtext-lexical/client";
|
||||||
|
import { StrikethroughFeatureClient as StrikethroughFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from "@payloadcms/richtext-lexical/client";
|
||||||
|
import { UnderlineFeatureClient as UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from "@payloadcms/richtext-lexical/client";
|
||||||
|
import { BoldFeatureClient as BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from "@payloadcms/richtext-lexical/client";
|
||||||
|
import { ItalicFeatureClient as ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from "@payloadcms/richtext-lexical/client";
|
||||||
|
import { default as default_2ebf44fdf8ebc607cf0de30cff485248 } from "@/src/payload/components/ColorPicker";
|
||||||
|
import { default as default_a1c6da8fb7dd9846a8b07123ff256d09 } from "@/src/payload/components/IconSelector";
|
||||||
|
import { ConvertInquiryButton as ConvertInquiryButton_09fd670bce023a947ab66e4eebea5168 } from "@/src/payload/components/ConvertInquiryButton";
|
||||||
|
import { AiAnalyzeButton as AiAnalyzeButton_51a6009c2b12d068d736ffd2b8182c71 } from "@/src/payload/components/AiAnalyzeButton";
|
||||||
|
import { GanttChartView as GanttChartView_0162b82db971e8f1e27fbdd0aaa2f1f4 } from "@/src/payload/views/GanttChart";
|
||||||
|
import { ChatWindowProvider as ChatWindowProvider_258e2d0901cb901e46c3eeed91676211 } from "@mintel/payload-ai/components/ChatWindow/index";
|
||||||
|
import { S3ClientUploadHandler as S3ClientUploadHandler_f97aa6c64367fa259c5bc0567239ef24 } from "@payloadcms/storage-s3/client";
|
||||||
|
import { CollectionCards as CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1 } from "@payloadcms/next/rsc";
|
||||||
|
|
||||||
|
export const importMap = {
|
||||||
|
"@mintel/payload-ai/components/AiMediaButtons#AiMediaButtons":
|
||||||
|
AiMediaButtons_1d402a78164f07306f77dce953e62e11,
|
||||||
|
"@mintel/payload-ai/components/OptimizeButton#OptimizeButton":
|
||||||
|
OptimizeButton_338ff118e214cff355f6d710d1a381fb,
|
||||||
|
"@mintel/payload-ai/components/FieldGenerators/GenerateSlugButton#GenerateSlugButton":
|
||||||
|
GenerateSlugButton_5baeea8510d263708dd253e86d55e0b4,
|
||||||
|
"@/src/payload/components/TagSelector#default":
|
||||||
|
default_76cec558bd86098fa1dab70b12eb818f,
|
||||||
|
"@mintel/payload-ai/components/FieldGenerators/GenerateThumbnailButton#GenerateThumbnailButton":
|
||||||
|
GenerateThumbnailButton_e5e8c00f1c031f15175fef0ff67513dc,
|
||||||
|
"@payloadcms/richtext-lexical/rsc#RscEntryLexicalCell":
|
||||||
|
RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e,
|
||||||
|
"@payloadcms/richtext-lexical/rsc#RscEntryLexicalField":
|
||||||
|
RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e,
|
||||||
|
"@payloadcms/richtext-lexical/rsc#LexicalDiffComponent":
|
||||||
|
LexicalDiffComponent_44fe37237e0ebf4470c9990d8cb7b07e,
|
||||||
|
"@payloadcms/richtext-lexical/client#BlocksFeatureClient":
|
||||||
|
BlocksFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton":
|
||||||
|
AiFieldButton_9125bc0af442fbb1889d8de3dff98501,
|
||||||
|
"@payloadcms/richtext-lexical/client#InlineToolbarFeatureClient":
|
||||||
|
InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#HorizontalRuleFeatureClient":
|
||||||
|
HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#UploadFeatureClient":
|
||||||
|
UploadFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#BlockquoteFeatureClient":
|
||||||
|
BlockquoteFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#RelationshipFeatureClient":
|
||||||
|
RelationshipFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#LinkFeatureClient":
|
||||||
|
LinkFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#ChecklistFeatureClient":
|
||||||
|
ChecklistFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#OrderedListFeatureClient":
|
||||||
|
OrderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#UnorderedListFeatureClient":
|
||||||
|
UnorderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#IndentFeatureClient":
|
||||||
|
IndentFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#AlignFeatureClient":
|
||||||
|
AlignFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#HeadingFeatureClient":
|
||||||
|
HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#ParagraphFeatureClient":
|
||||||
|
ParagraphFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#InlineCodeFeatureClient":
|
||||||
|
InlineCodeFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#SuperscriptFeatureClient":
|
||||||
|
SuperscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#SubscriptFeatureClient":
|
||||||
|
SubscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#StrikethroughFeatureClient":
|
||||||
|
StrikethroughFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#UnderlineFeatureClient":
|
||||||
|
UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#BoldFeatureClient":
|
||||||
|
BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#ItalicFeatureClient":
|
||||||
|
ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@/src/payload/components/ColorPicker#default":
|
||||||
|
default_2ebf44fdf8ebc607cf0de30cff485248,
|
||||||
|
"@/src/payload/components/IconSelector#default":
|
||||||
|
default_a1c6da8fb7dd9846a8b07123ff256d09,
|
||||||
|
"@/src/payload/components/ConvertInquiryButton#ConvertInquiryButton":
|
||||||
|
ConvertInquiryButton_09fd670bce023a947ab66e4eebea5168,
|
||||||
|
"@/src/payload/components/AiAnalyzeButton#AiAnalyzeButton":
|
||||||
|
AiAnalyzeButton_51a6009c2b12d068d736ffd2b8182c71,
|
||||||
|
"@/src/payload/views/GanttChart#GanttChartView":
|
||||||
|
GanttChartView_0162b82db971e8f1e27fbdd0aaa2f1f4,
|
||||||
|
"@mintel/payload-ai/components/ChatWindow/index#ChatWindowProvider":
|
||||||
|
ChatWindowProvider_258e2d0901cb901e46c3eeed91676211,
|
||||||
|
"@payloadcms/storage-s3/client#S3ClientUploadHandler":
|
||||||
|
S3ClientUploadHandler_f97aa6c64367fa259c5bc0567239ef24,
|
||||||
|
"@payloadcms/next/rsc#CollectionCards":
|
||||||
|
CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1,
|
||||||
|
};
|
||||||
|
|||||||
@@ -10,17 +10,21 @@ const dirname = path.dirname(filename);
|
|||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {
|
const nextConfig = {
|
||||||
serverExternalPackages: [
|
serverExternalPackages: [
|
||||||
'@mintel/content-engine',
|
|
||||||
'@mintel/concept-engine',
|
|
||||||
'@mintel/estimation-engine',
|
|
||||||
'@mintel/payload-ai',
|
|
||||||
'@mintel/pdf',
|
|
||||||
'canvas',
|
'canvas',
|
||||||
'sharp',
|
'sharp',
|
||||||
'puppeteer',
|
'puppeteer',
|
||||||
'require-in-the-middle',
|
'require-in-the-middle',
|
||||||
'import-in-the-middle' // Sentry 10+ instrumentation dependencies
|
'import-in-the-middle' // Sentry 10+ instrumentation dependencies
|
||||||
],
|
],
|
||||||
|
transpilePackages: [
|
||||||
|
'@mintel/content-engine',
|
||||||
|
'@mintel/concept-engine',
|
||||||
|
'@mintel/estimation-engine',
|
||||||
|
'@mintel/meme-generator',
|
||||||
|
'@mintel/payload-ai',
|
||||||
|
'@mintel/pdf',
|
||||||
|
'@mintel/thumbnail-generator'
|
||||||
|
],
|
||||||
images: {
|
images: {
|
||||||
remotePatterns: [
|
remotePatterns: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"dev": "pnpm run seed:context && next dev --webpack --hostname 0.0.0.0",
|
"dev": "pnpm run seed:context && next dev --webpack --hostname 0.0.0.0",
|
||||||
"dev:native": "DATABASE_URI=postgres://payload:payload@127.0.0.1:54321/payload PAYLOAD_SECRET=dev-secret pnpm run seed:context && DATABASE_URI=postgres://payload:payload@127.0.0.1:54321/payload PAYLOAD_SECRET=dev-secret next dev --webpack",
|
"dev:native": "DATABASE_URI=postgres://payload:payload@127.0.0.1:54321/payload PAYLOAD_SECRET=dev-secret pnpm run seed:context && DATABASE_URI=postgres://payload:payload@127.0.0.1:54321/payload PAYLOAD_SECRET=dev-secret next dev --webpack",
|
||||||
"seed:context": "node --import tsx --experimental-loader ./ignore-css.mjs ./seed-context.ts",
|
"seed:context": "node --import tsx --experimental-loader ./ignore-css.mjs ./seed-context.ts",
|
||||||
"build": "next build --webpack",
|
"build": "payload generate:importmap && next build --webpack",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "eslint app src scripts video",
|
"lint": "eslint app src scripts video",
|
||||||
"test": "echo \"No tests configured\"",
|
"test": "echo \"No tests configured\"",
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
"@mintel/content-engine": "link:../../../at-mintel/packages/content-engine",
|
"@mintel/content-engine": "link:../../../at-mintel/packages/content-engine",
|
||||||
"@mintel/estimation-engine": "link:../../../at-mintel/packages/estimation-engine",
|
"@mintel/estimation-engine": "link:../../../at-mintel/packages/estimation-engine",
|
||||||
"@mintel/meme-generator": "link:../../../at-mintel/packages/meme-generator",
|
"@mintel/meme-generator": "link:../../../at-mintel/packages/meme-generator",
|
||||||
"@mintel/payload-ai": "^1.9.15",
|
"@mintel/payload-ai": "link:../../../at-mintel/packages/payload-ai",
|
||||||
"@mintel/pdf": "link:../../../at-mintel/packages/pdf-library",
|
"@mintel/pdf": "link:../../../at-mintel/packages/pdf-library",
|
||||||
"@mintel/thumbnail-generator": "link:../../../at-mintel/packages/thumbnail-generator",
|
"@mintel/thumbnail-generator": "link:../../../at-mintel/packages/thumbnail-generator",
|
||||||
"@next/mdx": "^16.1.6",
|
"@next/mdx": "^16.1.6",
|
||||||
|
|||||||
@@ -26,12 +26,30 @@ import { Projects } from "./src/payload/collections/Projects";
|
|||||||
const filename = fileURLToPath(import.meta.url);
|
const filename = fileURLToPath(import.meta.url);
|
||||||
const dirname = path.dirname(filename);
|
const dirname = path.dirname(filename);
|
||||||
|
|
||||||
|
const isCLI =
|
||||||
|
process.argv.includes("migrate") ||
|
||||||
|
process.argv.includes("generate:importmap");
|
||||||
|
let aiPlugin: any;
|
||||||
|
if (!isCLI) {
|
||||||
|
const { payloadChatPlugin } = await import("@mintel/payload-ai");
|
||||||
|
aiPlugin = payloadChatPlugin({
|
||||||
|
enabled: true,
|
||||||
|
mcpServers: [],
|
||||||
|
renderChatBubble: false, // disable dynamic injection since it's added statically below
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export default buildConfig({
|
export default buildConfig({
|
||||||
admin: {
|
admin: {
|
||||||
user: Users.slug,
|
user: Users.slug,
|
||||||
importMap: {
|
importMap: {
|
||||||
baseDir: path.resolve(dirname),
|
baseDir: path.resolve(dirname),
|
||||||
},
|
},
|
||||||
|
components: {
|
||||||
|
providers: [
|
||||||
|
"@mintel/payload-ai/components/ChatWindow/index#ChatWindowProvider",
|
||||||
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
collections: [
|
collections: [
|
||||||
Users,
|
Users,
|
||||||
@@ -103,6 +121,7 @@ export default buildConfig({
|
|||||||
}),
|
}),
|
||||||
]
|
]
|
||||||
: []),
|
: []),
|
||||||
|
...(aiPlugin ? [aiPlugin] : []),
|
||||||
],
|
],
|
||||||
endpoints: [
|
endpoints: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -89,14 +89,14 @@ resolve_target() {
|
|||||||
prod|production)
|
prod|production)
|
||||||
REMOTE_PROJECT="mintel-me-production"
|
REMOTE_PROJECT="mintel-me-production"
|
||||||
REMOTE_DB_CONTAINER="mintel-me-production-postgres-db-1"
|
REMOTE_DB_CONTAINER="mintel-me-production-postgres-db-1"
|
||||||
REMOTE_APP_CONTAINER="mintel-me-production-app-1"
|
REMOTE_APP_CONTAINER="mintel-me-production-mintel-me-app-1"
|
||||||
REMOTE_SITE_DIR="/home/deploy/sites/mintel.me"
|
REMOTE_SITE_DIR="/home/deploy/sites/mintel.me"
|
||||||
;;
|
;;
|
||||||
branch-*)
|
branch-*)
|
||||||
local SLUG=${TARGET#branch-}
|
local SLUG=${TARGET#branch-}
|
||||||
REMOTE_PROJECT="mintel-me-branch-$SLUG"
|
REMOTE_PROJECT="mintel-me-branch-$SLUG"
|
||||||
REMOTE_DB_CONTAINER="${REMOTE_PROJECT}-postgres-db-1"
|
REMOTE_DB_CONTAINER="${REMOTE_PROJECT}-postgres-db-1"
|
||||||
REMOTE_APP_CONTAINER="${REMOTE_PROJECT}-app-1"
|
REMOTE_APP_CONTAINER="${REMOTE_PROJECT}-mintel-me-app-1"
|
||||||
REMOTE_SITE_DIR="/home/deploy/sites/branch.mintel.me/$SLUG"
|
REMOTE_SITE_DIR="/home/deploy/sites/branch.mintel.me/$SLUG"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
|||||||
@@ -1,12 +1,62 @@
|
|||||||
import { RichText } from "@payloadcms/richtext-lexical/react";
|
import {
|
||||||
|
RichText,
|
||||||
|
defaultJSXConverters,
|
||||||
|
} from "@payloadcms/richtext-lexical/react";
|
||||||
import type { JSXConverters } from "@payloadcms/richtext-lexical/react";
|
import type { JSXConverters } from "@payloadcms/richtext-lexical/react";
|
||||||
import { MemeCard } from "@/src/components/MemeCard";
|
import { MemeCard } from "@/src/components/MemeCard";
|
||||||
import { Mermaid } from "@/src/components/Mermaid";
|
import { Mermaid } from "@/src/components/Mermaid";
|
||||||
import { LeadMagnet } from "@/src/components/LeadMagnet";
|
import { LeadMagnet } from "@/src/components/LeadMagnet";
|
||||||
import { ComparisonRow } from "@/src/components/Landing/ComparisonRow";
|
import { ComparisonRow } from "@/src/components/Landing/ComparisonRow";
|
||||||
import { mdxComponents } from "../content-engine/components";
|
import { mdxComponents } from "../content-engine/components";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders markdown-style inline links [text](/url) as <a> tags.
|
||||||
|
* Used by mintelP blocks which store body text with links.
|
||||||
|
*/
|
||||||
|
function renderInlineMarkdown(text: string): React.ReactNode {
|
||||||
|
if (!text) return null;
|
||||||
|
const parts = text.split(/(\[[^\]]+\]\([^)]+\)|<Marker>[^<]*<\/Marker>)/);
|
||||||
|
return parts.map((part, i) => {
|
||||||
|
const linkMatch = part.match(/\[([^\]]+)\]\(([^)]+)\)/);
|
||||||
|
if (linkMatch) {
|
||||||
|
return (
|
||||||
|
<a
|
||||||
|
key={i}
|
||||||
|
href={linkMatch[2]}
|
||||||
|
className="text-slate-900 underline underline-offset-4 hover:text-slate-600 transition-colors"
|
||||||
|
>
|
||||||
|
{linkMatch[1]}
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const markerMatch = part.match(/<Marker>([^<]*)<\/Marker>/);
|
||||||
|
if (markerMatch) {
|
||||||
|
return (
|
||||||
|
<mark key={i} className="bg-yellow-100/60 px-1 rounded">
|
||||||
|
{markerMatch[1]}
|
||||||
|
</mark>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return <React.Fragment key={i}>{part}</React.Fragment>;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const jsxConverters: JSXConverters = {
|
const jsxConverters: JSXConverters = {
|
||||||
|
...defaultJSXConverters,
|
||||||
|
// Override paragraph to filter out leftover <TableOfContents /> raw text
|
||||||
|
paragraph: ({ node, nodesToJSX }: any) => {
|
||||||
|
const children = node?.children;
|
||||||
|
if (
|
||||||
|
children?.length === 1 &&
|
||||||
|
children[0]?.type === "text" &&
|
||||||
|
children[0]?.text?.trim()?.startsWith("<") &&
|
||||||
|
children[0]?.text?.trim()?.endsWith("/>")
|
||||||
|
) {
|
||||||
|
return null; // suppress raw JSX component text like <TableOfContents />
|
||||||
|
}
|
||||||
|
return <p>{nodesToJSX({ nodes: children })}</p>;
|
||||||
|
},
|
||||||
blocks: {
|
blocks: {
|
||||||
memeCard: ({ node }: any) => (
|
memeCard: ({ node }: any) => (
|
||||||
<div className="my-8">
|
<div className="my-8">
|
||||||
@@ -49,6 +99,15 @@ const jsxConverters: JSXConverters = {
|
|||||||
showShare={true}
|
showShare={true}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
|
// --- Core text blocks ---
|
||||||
|
mintelP: ({ node }: any) => (
|
||||||
|
<p className="text-base md:text-lg text-slate-600 leading-relaxed mb-6">
|
||||||
|
{renderInlineMarkdown(node.fields.text)}
|
||||||
|
</p>
|
||||||
|
),
|
||||||
|
mintelTldr: ({ node }: any) => (
|
||||||
|
<mdxComponents.TLDR>{node.fields.content}</mdxComponents.TLDR>
|
||||||
|
),
|
||||||
// --- MDX Registry Injections ---
|
// --- MDX Registry Injections ---
|
||||||
leadParagraph: ({ node }: any) => (
|
leadParagraph: ({ node }: any) => (
|
||||||
<mdxComponents.LeadParagraph>
|
<mdxComponents.LeadParagraph>
|
||||||
@@ -81,37 +140,46 @@ const jsxConverters: JSXConverters = {
|
|||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
diagramState: ({ node }: any) => (
|
diagramState: ({ node }: any) => (
|
||||||
<mdxComponents.DiagramState
|
<div className="my-8">
|
||||||
states={[]}
|
<Mermaid id={`diagram-state-${node.fields.id || Date.now()}`}>
|
||||||
transitions={[]}
|
{node.fields.definition}
|
||||||
caption={node.fields.definition}
|
</Mermaid>
|
||||||
/>
|
</div>
|
||||||
),
|
),
|
||||||
diagramTimeline: ({ node }: any) => (
|
diagramTimeline: ({ node }: any) => (
|
||||||
<mdxComponents.DiagramTimeline
|
<div className="my-8">
|
||||||
events={[]}
|
<Mermaid id={`diagram-timeline-${node.fields.id || Date.now()}`}>
|
||||||
title={node.fields.definition}
|
{node.fields.definition}
|
||||||
/>
|
</Mermaid>
|
||||||
|
</div>
|
||||||
),
|
),
|
||||||
diagramGantt: ({ node }: any) => (
|
diagramGantt: ({ node }: any) => (
|
||||||
<mdxComponents.DiagramGantt tasks={[]} title={node.fields.definition} />
|
<div className="my-8">
|
||||||
|
<Mermaid id={`diagram-gantt-${node.fields.id || Date.now()}`}>
|
||||||
|
{node.fields.definition}
|
||||||
|
</Mermaid>
|
||||||
|
</div>
|
||||||
),
|
),
|
||||||
diagramPie: ({ node }: any) => (
|
diagramPie: ({ node }: any) => (
|
||||||
<mdxComponents.DiagramPie data={[]} title={node.fields.definition} />
|
<div className="my-8">
|
||||||
|
<Mermaid id={`diagram-pie-${node.fields.id || Date.now()}`}>
|
||||||
|
{node.fields.definition}
|
||||||
|
</Mermaid>
|
||||||
|
</div>
|
||||||
),
|
),
|
||||||
diagramSequence: ({ node }: any) => (
|
diagramSequence: ({ node }: any) => (
|
||||||
<mdxComponents.DiagramSequence
|
<div className="my-8">
|
||||||
participants={[]}
|
<Mermaid id={`diagram-seq-${node.fields.id || Date.now()}`}>
|
||||||
steps={[]}
|
{node.fields.definition}
|
||||||
title={node.fields.definition}
|
</Mermaid>
|
||||||
/>
|
</div>
|
||||||
),
|
),
|
||||||
diagramFlow: ({ node }: any) => (
|
diagramFlow: ({ node }: any) => (
|
||||||
<mdxComponents.DiagramFlow
|
<div className="my-8">
|
||||||
nodes={[]}
|
<Mermaid id={`diagram-flow-${node.fields.id || Date.now()}`}>
|
||||||
edges={[]}
|
{node.fields.definition}
|
||||||
title={node.fields.definition}
|
</Mermaid>
|
||||||
/>
|
</div>
|
||||||
),
|
),
|
||||||
|
|
||||||
waterfallChart: ({ node }: any) => (
|
waterfallChart: ({ node }: any) => (
|
||||||
@@ -128,12 +196,22 @@ const jsxConverters: JSXConverters = {
|
|||||||
),
|
),
|
||||||
iconList: ({ node }: any) => (
|
iconList: ({ node }: any) => (
|
||||||
<mdxComponents.IconList>
|
<mdxComponents.IconList>
|
||||||
{node.fields.items?.map((item: any, i: number) => (
|
{node.fields.items?.map((item: any, i: number) => {
|
||||||
// @ts-ignore
|
const isCheck = item.icon === "check" || !item.icon;
|
||||||
<mdxComponents.IconListItem key={i} icon={item.icon || "check"}>
|
const isCross = item.icon === "x" || item.icon === "cross";
|
||||||
{item.description}
|
const isBullet = item.icon === "circle" || item.icon === "bullet";
|
||||||
</mdxComponents.IconListItem>
|
return (
|
||||||
))}
|
// @ts-ignore
|
||||||
|
<mdxComponents.IconListItem
|
||||||
|
key={i}
|
||||||
|
check={isCheck}
|
||||||
|
cross={isCross}
|
||||||
|
bullet={isBullet}
|
||||||
|
>
|
||||||
|
{item.title || item.description}
|
||||||
|
</mdxComponents.IconListItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</mdxComponents.IconList>
|
</mdxComponents.IconList>
|
||||||
),
|
),
|
||||||
statsGrid: ({ node }: any) => {
|
statsGrid: ({ node }: any) => {
|
||||||
@@ -159,8 +237,8 @@ const jsxConverters: JSXConverters = {
|
|||||||
<mdxComponents.Carousel
|
<mdxComponents.Carousel
|
||||||
items={
|
items={
|
||||||
node.fields.slides?.map((s: any) => ({
|
node.fields.slides?.map((s: any) => ({
|
||||||
title: s.caption || "Image",
|
title: s.title || s.caption || "Slide",
|
||||||
content: "",
|
content: s.content || s.caption || "",
|
||||||
icon: undefined,
|
icon: undefined,
|
||||||
})) || []
|
})) || []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
import { ComponentShareButton } from '../ComponentShareButton';
|
import { ComponentShareButton } from '../ComponentShareButton';
|
||||||
import { Reveal } from '../Reveal';
|
import { Reveal } from '../Reveal';
|
||||||
import { Play, RotateCcw } from 'lucide-react';
|
import { RotateCcw } from 'lucide-react';
|
||||||
|
|
||||||
export function LoadTimeSimulator({ className = '' }: { className?: string }) {
|
export function LoadTimeSimulator({ className = '' }: { className?: string }) {
|
||||||
const [isRunning, setIsRunning] = useState(false);
|
const [isRunning, setIsRunning] = useState(false);
|
||||||
const [timeElapsed, setTimeElapsed] = useState(0);
|
const [timeElapsed, setTimeElapsed] = useState(0);
|
||||||
const [legacyState, setLegacyState] = useState(0);
|
const [legacyState, setLegacyState] = useState(0);
|
||||||
|
const [hasAutoStarted, setHasAutoStarted] = useState(false);
|
||||||
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const [mintelState, setMintelState] = useState(0);
|
const [mintelState, setMintelState] = useState(0);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -36,6 +38,25 @@ export function LoadTimeSimulator({ className = '' }: { className?: string }) {
|
|||||||
return () => clearInterval(interval);
|
return () => clearInterval(interval);
|
||||||
}, [isRunning, timeElapsed]);
|
}, [isRunning, timeElapsed]);
|
||||||
|
|
||||||
|
// Auto-start the race when scrolled into viewport
|
||||||
|
useEffect(() => {
|
||||||
|
if (hasAutoStarted) return;
|
||||||
|
const el = containerRef.current;
|
||||||
|
if (!el) return;
|
||||||
|
const observer = new IntersectionObserver(
|
||||||
|
([entry]) => {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
setHasAutoStarted(true);
|
||||||
|
setIsRunning(true);
|
||||||
|
observer.disconnect();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ threshold: 0.4 }
|
||||||
|
);
|
||||||
|
observer.observe(el);
|
||||||
|
return () => observer.disconnect();
|
||||||
|
}, [hasAutoStarted]);
|
||||||
|
|
||||||
const startRace = () => {
|
const startRace = () => {
|
||||||
setTimeElapsed(0);
|
setTimeElapsed(0);
|
||||||
setLegacyState(0);
|
setLegacyState(0);
|
||||||
@@ -45,7 +66,7 @@ export function LoadTimeSimulator({ className = '' }: { className?: string }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Reveal direction="up" delay={0.1}>
|
<Reveal direction="up" delay={0.1}>
|
||||||
<div className={`not-prose max-w-4xl mx-auto my-12 relative group ${className}`}>
|
<div ref={containerRef} className={`not-prose max-w-4xl mx-auto my-12 relative group ${className}`}>
|
||||||
<div className="absolute -inset-1 bg-gradient-to-r from-red-100 to-emerald-100 rounded-3xl blur opacity-30" />
|
<div className="absolute -inset-1 bg-gradient-to-r from-red-100 to-emerald-100 rounded-3xl blur opacity-30" />
|
||||||
|
|
||||||
<div id="sim-load-time" className="relative bg-white rounded-2xl border border-slate-200 shadow-sm overflow-hidden flex flex-col">
|
<div id="sim-load-time" className="relative bg-white rounded-2xl border border-slate-200 shadow-sm overflow-hidden flex flex-col">
|
||||||
@@ -63,13 +84,15 @@ export function LoadTimeSimulator({ className = '' }: { className?: string }) {
|
|||||||
Simulieren Sie den Unterschied zwischen dynamischem Server-Rendering (PHP/MySQL) und statischer Edge-Auslieferung (<span className="font-mono bg-slate-200 px-1 rounded text-[10px]">TTV < 500ms</span>).
|
Simulieren Sie den Unterschied zwischen dynamischem Server-Rendering (PHP/MySQL) und statischer Edge-Auslieferung (<span className="font-mono bg-slate-200 px-1 rounded text-[10px]">TTV < 500ms</span>).
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<button
|
{timeElapsed > 0 && !isRunning && (
|
||||||
onClick={startRace}
|
<button
|
||||||
className="shrink-0 flex items-center gap-2 px-6 py-2.5 bg-slate-900 !text-white rounded-full font-bold text-sm hover:hover:bg-black hover:scale-105 active:scale-95 transition-all shadow-md"
|
onClick={startRace}
|
||||||
>
|
className="shrink-0 flex items-center gap-2 px-6 py-2.5 bg-slate-900 !text-white rounded-full font-bold text-sm hover:hover:bg-black hover:scale-105 active:scale-95 transition-all shadow-md"
|
||||||
{timeElapsed > 0 ? <RotateCcw size={16} /> : <Play size={16} />}
|
>
|
||||||
{timeElapsed > 0 ? "Neustart" : "Rennen Starten"}
|
<RotateCcw size={16} />
|
||||||
</button>
|
Neustart
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid md:grid-cols-2 divide-y md:divide-y-0 md:divide-x divide-slate-100 bg-slate-50/50">
|
<div className="grid md:grid-cols-2 divide-y md:divide-y-0 md:divide-x divide-slate-100 bg-slate-50/50">
|
||||||
|
|||||||
@@ -11,12 +11,6 @@ export const ArchitectureBuilderBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "ArchitectureBuilder",
|
|
||||||
description:
|
|
||||||
"Interactive comparison between a standard SaaS rental approach and a custom Built-First (Mintel) architecture. Useful for articles discussing digital ownership, software rent vs. build, or technological assets. Requires no props.",
|
|
||||||
usageExample: "'<ArchitectureBuilder />'",
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "preset",
|
name: "preset",
|
||||||
|
|||||||
@@ -11,12 +11,6 @@ export const ArticleBlockquoteBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "ArticleBlockquote",
|
|
||||||
description: "Styled blockquote for expert quotes or key statements.",
|
|
||||||
usageExample:
|
|
||||||
"'<ArticleBlockquote>\n Performance ist keine IT-Kennzahl, sondern ein ökonomischer Hebel.\n</ArticleBlockquote>'",
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "quote",
|
name: "quote",
|
||||||
@@ -25,7 +19,7 @@ export const ArticleBlockquoteBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den mehrzeiligen Text für quote ein.",
|
description: "Geben Sie den mehrzeiligen Text für quote ein.",
|
||||||
@@ -37,7 +31,7 @@ export const ArticleBlockquoteBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für author ein.",
|
description: "Geben Sie den Text für author ein.",
|
||||||
@@ -49,7 +43,7 @@ export const ArticleBlockquoteBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für role ein.",
|
description: "Geben Sie den Text für role ein.",
|
||||||
|
|||||||
@@ -10,13 +10,6 @@ export const ArticleMemeBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "ArticleMeme",
|
|
||||||
description:
|
|
||||||
"Real image-based meme from the media library. Use for static screenshots or custom memes that are not available via memegen.link.",
|
|
||||||
usageExample:
|
|
||||||
'<ArticleMeme image="/media/my-meme.png" alt="Sarcastic dev meme" caption="When the code finally builds." />',
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "image",
|
name: "image",
|
||||||
@@ -32,7 +25,7 @@ export const ArticleMemeBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für alt ein.",
|
description: "Geben Sie den Text für alt ein.",
|
||||||
@@ -44,7 +37,7 @@ export const ArticleMemeBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für caption ein.",
|
description: "Geben Sie den Text für caption ein.",
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export const ArticleQuoteBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den mehrzeiligen Text für quote ein.",
|
description: "Geben Sie den mehrzeiligen Text für quote ein.",
|
||||||
@@ -39,7 +39,7 @@ export const ArticleQuoteBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für author ein.",
|
description: "Geben Sie den Text für author ein.",
|
||||||
@@ -51,7 +51,7 @@ export const ArticleQuoteBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für role ein.",
|
description: "Geben Sie den Text für role ein.",
|
||||||
@@ -63,7 +63,7 @@ export const ArticleQuoteBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für source ein.",
|
description: "Geben Sie den Text für source ein.",
|
||||||
@@ -75,7 +75,7 @@ export const ArticleQuoteBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für sourceUrl ein.",
|
description: "Geben Sie den Text für sourceUrl ein.",
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export const BoldNumberBlock: MintelBlock = {
|
|||||||
description: "e.g. 53% or 2.5M€",
|
description: "e.g. 53% or 2.5M€",
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -38,7 +38,7 @@ export const BoldNumberBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für label ein.",
|
description: "Geben Sie den Text für label ein.",
|
||||||
@@ -50,7 +50,7 @@ export const BoldNumberBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für source ein.",
|
description: "Geben Sie den Text für source ein.",
|
||||||
@@ -62,7 +62,7 @@ export const BoldNumberBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für sourceUrl ein.",
|
description: "Geben Sie den Text für sourceUrl ein.",
|
||||||
|
|||||||
@@ -11,13 +11,6 @@ export const ButtonBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "Button",
|
|
||||||
description:
|
|
||||||
"DEPRECATED: Use <LeadMagnet /> instead for main CTAs. Only use for small secondary links.",
|
|
||||||
usageExample:
|
|
||||||
'<Button href="/contact" variant="outline">Webprojekt anfragen</Button>',
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "label",
|
name: "label",
|
||||||
@@ -26,7 +19,7 @@ export const ButtonBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für label ein.",
|
description: "Geben Sie den Text für label ein.",
|
||||||
|
|||||||
@@ -11,18 +11,21 @@ export const CarouselBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "Carousel",
|
|
||||||
description:
|
|
||||||
"Interactive swipeable slider for multi-step explanations. IMPORTANT: items array must contain at least 2 items with substantive title and content text (no empty content).",
|
|
||||||
usageExample:
|
|
||||||
'\'<Carousel items={[{ title: "Schritt 1", content: "Analyse der aktuellen Performance..."',
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "slides",
|
name: "slides",
|
||||||
type: "array",
|
type: "array",
|
||||||
fields: [
|
fields: [
|
||||||
|
{
|
||||||
|
name: "title",
|
||||||
|
type: "text",
|
||||||
|
admin: { description: "Titel der Slide-Karte." },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "content",
|
||||||
|
type: "textarea",
|
||||||
|
admin: { description: "Beschreibungstext der Slide-Karte." },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "image",
|
name: "image",
|
||||||
type: "upload",
|
type: "upload",
|
||||||
@@ -35,7 +38,7 @@ export const CarouselBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für caption ein.",
|
description: "Geben Sie den Text für caption ein.",
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export const ComparisonRowBlock: MintelBlock = {
|
|||||||
description: "Optional overarching description for the comparison.",
|
description: "Optional overarching description for the comparison.",
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -44,7 +44,7 @@ export const ComparisonRowBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für negativeLabel ein.",
|
description: "Geben Sie den Text für negativeLabel ein.",
|
||||||
@@ -57,7 +57,7 @@ export const ComparisonRowBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für negativeText ein.",
|
description: "Geben Sie den Text für negativeText ein.",
|
||||||
@@ -71,7 +71,7 @@ export const ComparisonRowBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für positiveLabel ein.",
|
description: "Geben Sie den Text für positiveLabel ein.",
|
||||||
@@ -84,7 +84,7 @@ export const ComparisonRowBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für positiveText ein.",
|
description: "Geben Sie den Text für positiveText ein.",
|
||||||
|
|||||||
@@ -11,12 +11,6 @@ export const DiagramFlowBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "DiagramFlow",
|
|
||||||
description:
|
|
||||||
"Mermaid flowchart diagram defining the graph structure. MUST output raw mermaid code, no quotes or HTML.",
|
|
||||||
usageExample: "graph TD\\n A[Start] --> B[End]",
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "definition",
|
name: "definition",
|
||||||
@@ -25,7 +19,7 @@ export const DiagramFlowBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den mehrzeiligen Text für definition ein.",
|
description: "Geben Sie den mehrzeiligen Text für definition ein.",
|
||||||
|
|||||||
@@ -11,12 +11,6 @@ export const DiagramGanttBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "DiagramGantt",
|
|
||||||
description: "Mermaid Gantt timeline chart. MUST output raw mermaid code.",
|
|
||||||
usageExample:
|
|
||||||
"gantt\\n title Project Roadmap\\n dateFormat YYYY-MM-DD\\n Section Design\\n Draft UI :a1, 2024-01-01, 7d",
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "definition",
|
name: "definition",
|
||||||
@@ -25,7 +19,7 @@ export const DiagramGanttBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den mehrzeiligen Text für definition ein.",
|
description: "Geben Sie den mehrzeiligen Text für definition ein.",
|
||||||
|
|||||||
@@ -11,11 +11,6 @@ export const DiagramPieBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "DiagramPie",
|
|
||||||
description: "Mermaid pie chart diagram. MUST output raw mermaid code.",
|
|
||||||
usageExample: 'pie title Market Share\\n "Chrome" : 60\\n "Safari" : 20',
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "definition",
|
name: "definition",
|
||||||
@@ -24,7 +19,7 @@ export const DiagramPieBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den mehrzeiligen Text für definition ein.",
|
description: "Geben Sie den mehrzeiligen Text für definition ein.",
|
||||||
|
|||||||
@@ -11,13 +11,6 @@ export const DiagramSequenceBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "DiagramSequence",
|
|
||||||
description:
|
|
||||||
"Mermaid sequence diagram showing actor interactions. MUST output raw mermaid code.",
|
|
||||||
usageExample:
|
|
||||||
"sequenceDiagram\\n Client->>Server: GET /api\\n Server-->>Client: 200 OK",
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "definition",
|
name: "definition",
|
||||||
@@ -26,7 +19,7 @@ export const DiagramSequenceBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den mehrzeiligen Text für definition ein.",
|
description: "Geben Sie den mehrzeiligen Text für definition ein.",
|
||||||
|
|||||||
@@ -11,12 +11,6 @@ export const DiagramStateBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "DiagramState",
|
|
||||||
description:
|
|
||||||
"Mermaid state diagram showing states and transitions. MUST output raw mermaid code.",
|
|
||||||
usageExample: "stateDiagram-v2\\n [*] --> Idle\\n Idle --> Loading",
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "definition",
|
name: "definition",
|
||||||
@@ -25,7 +19,7 @@ export const DiagramStateBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den mehrzeiligen Text für definition ein.",
|
description: "Geben Sie den mehrzeiligen Text für definition ein.",
|
||||||
|
|||||||
@@ -11,13 +11,6 @@ export const DiagramTimelineBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "DiagramTimeline",
|
|
||||||
description:
|
|
||||||
"Mermaid timeline or journey diagram. MUST output raw mermaid code.",
|
|
||||||
usageExample:
|
|
||||||
"timeline\\n title Project Timeline\\n 2024\\n : Q1 : Planning\\n : Q2 : Execution",
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "definition",
|
name: "definition",
|
||||||
@@ -26,7 +19,7 @@ export const DiagramTimelineBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den mehrzeiligen Text für definition ein.",
|
description: "Geben Sie den mehrzeiligen Text für definition ein.",
|
||||||
|
|||||||
@@ -11,12 +11,6 @@ export const DigitalAssetVisualizerBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "DigitalAssetVisualizer",
|
|
||||||
description:
|
|
||||||
"Interactive visualization illustrating the financial difference between software as a liability (SaaS/rent) and software as a digital asset (Custom IP). Great for articles concerning CTO strategies, business value of code, and digital independence. Requires no props.",
|
|
||||||
usageExample: "'<DigitalAssetVisualizer />'",
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "assetId",
|
name: "assetId",
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export const ExternalLinkBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für label ein.",
|
description: "Geben Sie den Text für label ein.",
|
||||||
|
|||||||
@@ -16,13 +16,6 @@ export const FAQSectionBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "FAQSection",
|
|
||||||
description:
|
|
||||||
"Semantic wrapper for FAQ questions at the end of the article. Put standard Markdown H3/Paragraphs inside.",
|
|
||||||
usageExample:
|
|
||||||
"'<FAQSection>\n <H3>Frage 1</H3>\n <Paragraph>Antwort 1</Paragraph>\n</FAQSection>'",
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "content",
|
name: "content",
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export const H2Block: MintelBlock = {
|
|||||||
description: "Geben Sie den Text für die H2-Überschrift ein.",
|
description: "Geben Sie den Text für die H2-Überschrift ein.",
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export const H3Block: MintelBlock = {
|
|||||||
description: "Geben Sie den Text für die H3-Überschrift ein.",
|
description: "Geben Sie den Text für die H3-Überschrift ein.",
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export const HeadingBlock: MintelBlock = {
|
|||||||
description: "Der Text der Überschrift.",
|
description: "Der Text der Überschrift.",
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export const IconListBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für title ein.",
|
description: "Geben Sie den Text für title ein.",
|
||||||
@@ -56,7 +56,7 @@ export const IconListBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den mehrzeiligen Text für description ein.",
|
description: "Geben Sie den mehrzeiligen Text für description ein.",
|
||||||
|
|||||||
@@ -11,12 +11,6 @@ export const ImageTextBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "ImageText",
|
|
||||||
description: "Layout component for image next to explanatory text.",
|
|
||||||
usageExample:
|
|
||||||
'\'<ImageText image="/img.jpg" title="Architektur">Erklärung...</ImageText>\'',
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "image",
|
name: "image",
|
||||||
@@ -32,7 +26,7 @@ export const ImageTextBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den mehrzeiligen Text für text ein.",
|
description: "Geben Sie den mehrzeiligen Text für text ein.",
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export const LeadMagnetBlock: MintelBlock = {
|
|||||||
description: "The strong headline for the Call-to-Action",
|
description: "The strong headline for the Call-to-Action",
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -40,7 +40,7 @@ export const LeadMagnetBlock: MintelBlock = {
|
|||||||
description: "The value proposition text.",
|
description: "The value proposition text.",
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -53,7 +53,7 @@ export const LeadMagnetBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für buttonText ein.",
|
description: "Geben Sie den Text für buttonText ein.",
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export const LeadParagraphBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den mehrzeiligen Text für text ein.",
|
description: "Geben Sie den mehrzeiligen Text für text ein.",
|
||||||
|
|||||||
@@ -11,13 +11,6 @@ export const LinkedInEmbedBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "LinkedInEmbed",
|
|
||||||
description:
|
|
||||||
"Embeds a professional post from LinkedIn. Use the activity URN (e.g. urn:li:activity:1234567890).",
|
|
||||||
usageExample:
|
|
||||||
"'<LinkedInEmbed urn=\"urn:li:activity:7153664326573674496\" />'",
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "url",
|
name: "url",
|
||||||
|
|||||||
@@ -11,12 +11,6 @@ export const LoadTimeSimulatorBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "LoadTimeSimulator",
|
|
||||||
description:
|
|
||||||
"Interactive visual race simulating the loading experience of a slow legacy CMS vs a fast headless stack. Great for articles discussing load times, technical debt, or user frustration. Requires no props.",
|
|
||||||
usageExample: "'<LoadTimeSimulator />'",
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "initialLoadTime",
|
name: "initialLoadTime",
|
||||||
|
|||||||
@@ -11,12 +11,6 @@ export const MarkerBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "Marker",
|
|
||||||
description:
|
|
||||||
"Inline highlight (yellow marker effect) for emphasizing key phrases within paragraphs.",
|
|
||||||
usageExample: "'<Marker>entscheidender Wettbewerbsvorteil</Marker>'",
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "text",
|
name: "text",
|
||||||
@@ -25,7 +19,7 @@ export const MarkerBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für text ein.",
|
description: "Geben Sie den Text für text ein.",
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export const MemeCardBlock: MintelBlock = {
|
|||||||
ai: {
|
ai: {
|
||||||
name: "MemeCard",
|
name: "MemeCard",
|
||||||
description:
|
description:
|
||||||
'Real meme image from memegen.link. template must be a valid memegen.link ID. IMPORTANT: Captions must be EXTREMELY SARCASTIC and PUNCHY (mocking bad B2B agencies, max 6 words per line). Best templates: drake (2-line prefer/dislike), gru (4-step plan backfire), disastergirl (burning house), fine (this is fine dog). Use German captions. Wrap in div with className="my-8".',
|
"Real meme from memegen.link. ONLY use these templates: drake, distracted-bf, change-my-mind, uno-draw-25, always-has-been. Captions MUST be in German, extremely sarcastic, max 6 words per line. Use pipe | to separate caption lines. Use sparingly: MAX 1 meme per article.",
|
||||||
usageExample: `<div className="my-8">
|
usageExample: `<div className="my-8">
|
||||||
<MemeCard template="drake" captions="47 WordPress Plugins installieren|Eine saubere Serverless Architektur" />
|
<MemeCard template="drake" captions="47 WordPress Plugins installieren|Eine saubere Serverless Architektur" />
|
||||||
</div>`,
|
</div>`,
|
||||||
@@ -28,7 +28,7 @@ export const MemeCardBlock: MintelBlock = {
|
|||||||
"The template ID from memegen.link (e.g. 'drake', 'disastergirl')",
|
"The template ID from memegen.link (e.g. 'drake', 'disastergirl')",
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -42,7 +42,7 @@ export const MemeCardBlock: MintelBlock = {
|
|||||||
"Pipe-separated captions for the meme (e.g. 'Legacy Code|Mintel Stack'). Maximum 6 words per line.",
|
"Pipe-separated captions for the meme (e.g. 'Legacy Code|Mintel Stack'). Maximum 6 words per line.",
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export const MermaidBlock: MintelBlock = {
|
|||||||
description: "Optional title displayed above the diagram.",
|
description: "Optional title displayed above the diagram.",
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -59,7 +59,7 @@ export const MermaidBlock: MintelBlock = {
|
|||||||
"The raw Mermaid.js syntax (e.g. graph TD... shadowing, loops, etc.).",
|
"The raw Mermaid.js syntax (e.g. graph TD... shadowing, loops, etc.).",
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -11,12 +11,6 @@ export const MetricBarBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "MetricBar",
|
|
||||||
description:
|
|
||||||
"Animated horizontal progress bar. Use multiple in sequence to compare metrics. IMPORTANT: value MUST be a real number > 0, never use 0 or placeholder values. Props: label, value (number), max (default 100), unit (default %), color (red|green|blue|slate).",
|
|
||||||
usageExample: '<MetricBar label="WordPress Sites" value={33',
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "label",
|
name: "label",
|
||||||
@@ -25,7 +19,7 @@ export const MetricBarBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für label ein.",
|
description: "Geben Sie den Text für label ein.",
|
||||||
@@ -50,7 +44,7 @@ export const MetricBarBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für unit ein.",
|
description: "Geben Sie den Text für unit ein.",
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export const ParagraphBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den mehrzeiligen Text für text ein.",
|
description: "Geben Sie den mehrzeiligen Text für text ein.",
|
||||||
|
|||||||
@@ -11,13 +11,6 @@ export const PerformanceChartBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "PerformanceChart",
|
|
||||||
description:
|
|
||||||
"A visual chart illustrating performance metrics (e.g. PageSpeed, TTFB) over time or in comparison. Use to emphasize technical improvements.",
|
|
||||||
usageExample:
|
|
||||||
'<PerformanceChart items={[{ label: "Vorher", value: 12 }, { label: "Nachher", value: 98 }]} />',
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "title",
|
name: "title",
|
||||||
@@ -26,7 +19,7 @@ export const PerformanceChartBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für title ein.",
|
description: "Geben Sie den Text für title ein.",
|
||||||
|
|||||||
@@ -11,12 +11,6 @@ export const PerformanceROICalculatorBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "PerformanceROICalculator",
|
|
||||||
description:
|
|
||||||
"Interactive simulation calculator showing the monetary ROI of improving load times (based on Deloitte B2B metrics). Use exactly once in performance-related articles to provide a highly engaging simulation. Requires no props.",
|
|
||||||
usageExample: "'<PerformanceROICalculator />'",
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "baseConversionRate",
|
name: "baseConversionRate",
|
||||||
|
|||||||
@@ -11,13 +11,6 @@ export const PremiumComparisonChartBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "PremiumComparisonChart",
|
|
||||||
description:
|
|
||||||
"Advanced chart for comparing performance metrics with industrial aesthetics.",
|
|
||||||
usageExample:
|
|
||||||
'\'<PremiumComparisonChart title="TTFB Vergleich" items={[{ label: "Alt", value: 800, max: 1000, color: "red"',
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "title",
|
name: "title",
|
||||||
@@ -25,7 +18,7 @@ export const PremiumComparisonChartBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für title ein.",
|
description: "Geben Sie den Text für title ein.",
|
||||||
@@ -37,7 +30,7 @@ export const PremiumComparisonChartBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für subtitle ein.",
|
description: "Geben Sie den Text für subtitle ein.",
|
||||||
@@ -54,7 +47,7 @@ export const PremiumComparisonChartBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für label ein.",
|
description: "Geben Sie den Text für label ein.",
|
||||||
@@ -82,7 +75,7 @@ export const PremiumComparisonChartBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für unit ein.",
|
description: "Geben Sie den Text für unit ein.",
|
||||||
@@ -102,7 +95,7 @@ export const PremiumComparisonChartBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für description ein.",
|
description: "Geben Sie den Text für description ein.",
|
||||||
|
|||||||
@@ -12,13 +12,6 @@ export const RevealBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "Reveal",
|
|
||||||
description:
|
|
||||||
"Scroll-triggered reveal animation wrapper. Wrap any content to animate on scroll.",
|
|
||||||
usageExample:
|
|
||||||
'\'<Reveal>\n <StatsDisplay value="100" label="PageSpeed Score" />\n</Reveal>\'',
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "direction",
|
name: "direction",
|
||||||
|
|||||||
@@ -11,12 +11,6 @@ export const RevenueLossCalculatorBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "RevenueLossCalculator",
|
|
||||||
description:
|
|
||||||
"Interactive calculator that estimates financial loss due to slow page load times. Use to build a business case for performance optimization.",
|
|
||||||
usageExample: "<RevenueLossCalculator />",
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "title",
|
name: "title",
|
||||||
@@ -25,7 +19,7 @@ export const RevenueLossCalculatorBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für title ein.",
|
description: "Geben Sie den Text für title ein.",
|
||||||
|
|||||||
@@ -12,12 +12,6 @@ export const SectionBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "Section",
|
|
||||||
description: "Wraps a thematic section block with optional heading.",
|
|
||||||
usageExample:
|
|
||||||
"'<Section>\n <h3>Section Title</h3>\n <p>Content here.</p>\n</Section>'",
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "title",
|
name: "title",
|
||||||
@@ -25,7 +19,7 @@ export const SectionBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für title ein.",
|
description: "Geben Sie den Text für title ein.",
|
||||||
|
|||||||
@@ -11,13 +11,6 @@ export const StatsDisplayBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "StatsDisplay",
|
|
||||||
description:
|
|
||||||
"A single large stat card with prominent value, label, and optional subtext.",
|
|
||||||
usageExample:
|
|
||||||
'\'<StatsDisplay value="-20%" label="Conversion" subtext="Jede Sekunde Verzögerung kostet." />\'',
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "label",
|
name: "label",
|
||||||
@@ -25,7 +18,7 @@ export const StatsDisplayBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für label ein.",
|
description: "Geben Sie den Text für label ein.",
|
||||||
@@ -38,7 +31,7 @@ export const StatsDisplayBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für value ein.",
|
description: "Geben Sie den Text für value ein.",
|
||||||
@@ -50,7 +43,7 @@ export const StatsDisplayBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für subtext ein.",
|
description: "Geben Sie den Text für subtext ein.",
|
||||||
|
|||||||
@@ -11,13 +11,6 @@ export const StatsGridBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "StatsGrid",
|
|
||||||
description:
|
|
||||||
"Grid of 2–4 stat cards in a row. Use tilde (~) to separate stats, pipe (|) to separate value|label|subtext within each stat.",
|
|
||||||
usageExample:
|
|
||||||
"'<StatsGrid stats=\"53%|Mehr Umsatz|Rakuten 24~33%|Conversion Boost|nach CWV Fix~24%|Top 3 Ranking|bei bestandenen CWV\" />'",
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "stats",
|
name: "stats",
|
||||||
@@ -30,7 +23,7 @@ export const StatsGridBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für label ein.",
|
description: "Geben Sie den Text für label ein.",
|
||||||
@@ -43,7 +36,7 @@ export const StatsGridBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für value ein.",
|
description: "Geben Sie den Text für value ein.",
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export const TLDRBlock: MintelBlock = {
|
|||||||
description: "The summary content for the TLDR box.",
|
description: "The summary content for the TLDR box.",
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -11,13 +11,6 @@ export const TrackedLinkBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "TrackedLink",
|
|
||||||
description:
|
|
||||||
"A wrapper around next/link that tracks clicks. Use for all INTERNAL navigational links that should be tracked.",
|
|
||||||
usageExample:
|
|
||||||
'\'<TrackedLink href="/contact" className="text-blue-600 font-bold">Jetzt anfragen</TrackedLink>\'',
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "href",
|
name: "href",
|
||||||
@@ -32,7 +25,7 @@ export const TrackedLinkBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für label ein.",
|
description: "Geben Sie den Text für label ein.",
|
||||||
|
|||||||
@@ -11,13 +11,6 @@ export const TwitterEmbedBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "TwitterEmbed",
|
|
||||||
description:
|
|
||||||
"Embeds a post from X.com (Twitter). Used to provide social proof, industry quotes, or examples. Provide the numerical tweetId.",
|
|
||||||
usageExample:
|
|
||||||
'\'<TwitterEmbed tweetId="1753464161943834945" theme="light" />\'',
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "url",
|
name: "url",
|
||||||
|
|||||||
@@ -11,15 +11,6 @@ export const WaterfallChartBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "WaterfallChart",
|
|
||||||
description:
|
|
||||||
"A timeline visualization of network requests (waterfall). Use to show loading sequences or bottlenecks. Labels auto-color coded by type (JS, HTML, IMG).",
|
|
||||||
usageExample: `<WaterfallChart
|
|
||||||
title="Initial Load"
|
|
||||||
events={[
|
|
||||||
{ name: "Document", start: 0, duration: 150`,
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "title",
|
name: "title",
|
||||||
@@ -27,7 +18,7 @@ export const WaterfallChartBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für title ein.",
|
description: "Geben Sie den Text für title ein.",
|
||||||
@@ -44,7 +35,7 @@ export const WaterfallChartBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für label ein.",
|
description: "Geben Sie den Text für label ein.",
|
||||||
|
|||||||
@@ -11,12 +11,6 @@ export const WebVitalsScoreBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
group: "MDX Components",
|
group: "MDX Components",
|
||||||
},
|
},
|
||||||
ai: {
|
|
||||||
name: "WebVitalsScore",
|
|
||||||
description:
|
|
||||||
"Displays Core Web Vitals (LCP, INP, CLS) in a premium card layout with automatic traffic light coloring (Good/Needs Improvement/Poor). Use for performance audits or comparisons.",
|
|
||||||
usageExample: "'<WebVitalsScore values={{ lcp: 2.5, inp: 200, cls: 0.1",
|
|
||||||
},
|
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "lcp",
|
name: "lcp",
|
||||||
@@ -42,7 +36,7 @@ export const WebVitalsScoreBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für description ein.",
|
description: "Geben Sie den Text für description ein.",
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export const YouTubeEmbedBlock: MintelBlock = {
|
|||||||
admin: {
|
admin: {
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/AiFieldButton#AiFieldButton",
|
"@mintel/payload-ai/components/FieldGenerators/AiFieldButton#AiFieldButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
description: "Geben Sie den Text für title ein.",
|
description: "Geben Sie den Text für title ein.",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { CollectionConfig } from "payload";
|
import type { CollectionConfig } from "payload";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { fileURLToPath } from "url";
|
import { fileURLToPath } from "url";
|
||||||
import { replicateMediaHandler } from "@mintel/payload-ai/endpoints/replicateMediaEndpoint.js";
|
import { replicateMediaHandler } from "@mintel/payload-ai/endpoints/replicateMediaEndpoint";
|
||||||
|
|
||||||
const filename = fileURLToPath(import.meta.url);
|
const filename = fileURLToPath(import.meta.url);
|
||||||
const dirname = path.dirname(filename);
|
const dirname = path.dirname(filename);
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export const Posts: CollectionConfig = {
|
|||||||
position: "sidebar",
|
position: "sidebar",
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/GenerateSlugButton#GenerateSlugButton",
|
"@mintel/payload-ai/components/FieldGenerators/GenerateSlugButton#GenerateSlugButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -100,7 +100,7 @@ export const Posts: CollectionConfig = {
|
|||||||
position: "sidebar",
|
position: "sidebar",
|
||||||
components: {
|
components: {
|
||||||
afterInput: [
|
afterInput: [
|
||||||
"@mintel/payload-ai/components/GenerateThumbnailButton#GenerateThumbnailButton",
|
"@mintel/payload-ai/components/FieldGenerators/GenerateThumbnailButton#GenerateThumbnailButton",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -52,7 +52,8 @@
|
|||||||
"pnpm": {
|
"pnpm": {
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"@sentry/nextjs": "10.38.0",
|
"@sentry/nextjs": "10.38.0",
|
||||||
"eslint": "10.0.0"
|
"eslint": "10.0.0",
|
||||||
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"onlyBuiltDependencies": [
|
"onlyBuiltDependencies": [
|
||||||
"@parcel/watcher",
|
"@parcel/watcher",
|
||||||
|
|||||||
6
pnpm-lock.yaml
generated
6
pnpm-lock.yaml
generated
@@ -119,8 +119,8 @@ importers:
|
|||||||
specifier: link:../../../at-mintel/packages/meme-generator
|
specifier: link:../../../at-mintel/packages/meme-generator
|
||||||
version: link:../../../at-mintel/packages/meme-generator
|
version: link:../../../at-mintel/packages/meme-generator
|
||||||
"@mintel/payload-ai":
|
"@mintel/payload-ai":
|
||||||
specifier: ^1.9.15
|
specifier: link:../../../at-mintel/packages/payload-ai
|
||||||
version: 1.9.15(@payloadcms/next@3.77.0(graphql@16.12.0)(monaco-editor@0.55.1)(next@16.1.6(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.77.4))(payload@3.77.0(graphql@16.12.0)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(@payloadcms/ui@3.77.0(monaco-editor@0.55.1)(next@16.1.6(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.77.4))(payload@3.77.0(graphql@16.12.0)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(payload@3.77.0(graphql@16.12.0)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)(ws@8.19.0)
|
version: link:../../../at-mintel/packages/payload-ai
|
||||||
"@mintel/pdf":
|
"@mintel/pdf":
|
||||||
specifier: link:../../../at-mintel/packages/pdf-library
|
specifier: link:../../../at-mintel/packages/pdf-library
|
||||||
version: link:../../../at-mintel/packages/pdf-library
|
version: link:../../../at-mintel/packages/pdf-library
|
||||||
@@ -314,7 +314,7 @@ importers:
|
|||||||
specifier: ^0.18.5
|
specifier: ^0.18.5
|
||||||
version: 0.18.5
|
version: 0.18.5
|
||||||
zod:
|
zod:
|
||||||
specifier: ^3.25.76
|
specifier: ^3.23.8
|
||||||
version: 3.25.76
|
version: 3.25.76
|
||||||
devDependencies:
|
devDependencies:
|
||||||
"@eslint/eslintrc":
|
"@eslint/eslintrc":
|
||||||
|
|||||||
Reference in New Issue
Block a user