site template cleanup 1/3
This commit is contained in:
parent
85f5f65a21
commit
9e72aca04c
@ -1,7 +1,7 @@
|
||||
|
||||
export default new Map([
|
||||
["src/content/infopages/community.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Finfopages%2Fcommunity.mdx&astroContentModuleFlag=true")],
|
||||
["src/content/infopages/contact.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Finfopages%2Fcontact.mdx&astroContentModuleFlag=true")],
|
||||
["src/content/infopages/community.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Finfopages%2Fcommunity.mdx&astroContentModuleFlag=true")],
|
||||
["src/content/infopages/resources.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Finfopages%2Fresources.mdx&astroContentModuleFlag=true")],
|
||||
["src/content/infopages/software.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Finfopages%2Fsoftware.mdx&astroContentModuleFlag=true")]]);
|
||||
|
||||
@ -3,15 +3,15 @@ import pMap from 'p-map'
|
||||
import { GlobOptions } from 'glob'
|
||||
import { sanitizeUri } from 'micromark-util-sanitize-uri'
|
||||
import ExifReader from 'exifreader'
|
||||
|
||||
import { loadImage } from "imagetools/api"
|
||||
|
||||
import { sanitizeFilename } from '@polymech/fs/utils'
|
||||
import { resolve } from '@polymech/commons'
|
||||
import { files } from '@polymech/commons'
|
||||
import { sync as exists } from '@polymech/fs/exists'
|
||||
import { sync as read } from '@polymech/fs/read'
|
||||
import { sync as mv } from '@polymech/fs/move'
|
||||
import { logger } from '@/base/index.js'
|
||||
import { env } from './index.js'
|
||||
import { GalleryImage, MetaJSON } from './images.js'
|
||||
|
||||
import {
|
||||
removeArrayValues,
|
||||
@ -25,12 +25,8 @@ import {
|
||||
DEFAULT_IMAGE_URL, ASSETS_LOCAL,
|
||||
ASSETS_GLOB
|
||||
} from 'config/config.js'
|
||||
import { GalleryImage, MetaJSON } from './images.js'
|
||||
|
||||
import { validateFilename, sanitizeFilename } from "@polymech/fs/utils"
|
||||
|
||||
import { env } from './index.js'
|
||||
|
||||
export const default_sanitizer = (files:string[]) => files.map((f) => sanitizeFilename(f))
|
||||
|
||||
export const default_sort = (files: string[]): string[] => {
|
||||
const getSortableParts = (filename: string) => {
|
||||
@ -51,25 +47,6 @@ export const default_sort = (files: string[]): string[] => {
|
||||
})
|
||||
}
|
||||
|
||||
export const default_sanitize = (paths: string[]): string[] => {
|
||||
return paths.map((filePath) => {
|
||||
const dir = path.dirname(filePath);
|
||||
const originalFilename = path.basename(filePath);
|
||||
const sanitizedFilename = sanitizeFilename(originalFilename)
|
||||
if (originalFilename === sanitizedFilename) {
|
||||
return filePath;
|
||||
}
|
||||
const newPath = path.join(dir, sanitizedFilename);
|
||||
|
||||
try {
|
||||
mv(filePath, newPath);
|
||||
return newPath;
|
||||
} catch (error) {
|
||||
return filePath; // Return the original path in case of failure
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const default_filter = async (url: string) => {
|
||||
try {
|
||||
const response = await fetch(url, { method: 'HEAD' })
|
||||
@ -103,25 +80,23 @@ export const image_url = async (src, fallback = DEFAULT_IMAGE_URL) => {
|
||||
return safeSrc
|
||||
}
|
||||
|
||||
export const gallery = async (
|
||||
assetPath,
|
||||
product): Promise<GalleryImage[] | undefined> => {
|
||||
product = '' + product
|
||||
export const gallery = async ( assetPath, item): Promise<GalleryImage[]> => {
|
||||
|
||||
const root = resolve(PRODUCT_ROOT())
|
||||
const profile = env()
|
||||
const assetSlug = path.parse(assetPath).name
|
||||
|
||||
const productConfig: any = read(PRODUCT_CONFIG(product), "json")
|
||||
if (!productConfig) {
|
||||
logger.warn(`item gallery : item ${product} config not found !`)
|
||||
const itemConfig: any = read(PRODUCT_CONFIG(item), "json")
|
||||
if (!itemConfig) {
|
||||
logger.warn(`item gallery : item ${item} config not found !`)
|
||||
return []
|
||||
}
|
||||
const mediaPath = `${root}/${product}/${assetPath}/`
|
||||
const mediaPath = `${root}/${item}/${assetPath}/`
|
||||
if (!exists(mediaPath)) {
|
||||
logger.warn(`item gallery : item ${product} media path not found ${mediaPath}!`)
|
||||
logger.warn(`item gallery : item ${item} media path not found ${mediaPath}!`)
|
||||
return []
|
||||
}
|
||||
const galleryGlob = (productConfig.gallery || {})[assetSlug]?.glob || ASSETS_GLOB
|
||||
const galleryGlob = (itemConfig.gallery || {})[assetSlug]?.glob || ASSETS_GLOB
|
||||
let galleryFiles: any[] = files(mediaPath, galleryGlob, {
|
||||
cwd: mediaPath,
|
||||
absolute: false,
|
||||
@ -133,7 +108,7 @@ export const gallery = async (
|
||||
}
|
||||
|
||||
if (!galleryFiles) {
|
||||
logger.warn(`ProductGallery : Product ${product} media files not found ! ${mediaPath}`)
|
||||
logger.warn(`gallery : ${item} media files not found ! ${mediaPath}`)
|
||||
return []
|
||||
}
|
||||
const assetUrl = (filePath) => {
|
||||
@ -141,20 +116,19 @@ export const gallery = async (
|
||||
{
|
||||
assetPath,
|
||||
filePath,
|
||||
ITEM_REL: product,
|
||||
ITEM_REL: item,
|
||||
...profile.variables
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
if (!ASSETS_LOCAL) {
|
||||
galleryFiles = await pMap(galleryFiles, async (f) => (await default_filter(assetUrl(f))) ? f : null, { concurrency: 5 })
|
||||
galleryFiles = galleryFiles.filter((f) => f !== null)
|
||||
galleryFiles = default_sort(galleryFiles)
|
||||
} else {
|
||||
galleryFiles = galleryFiles.filter(default_filter_locale)
|
||||
galleryFiles = default_sort(galleryFiles)
|
||||
}
|
||||
galleryFiles = default_sort(galleryFiles)
|
||||
|
||||
return await pMap(galleryFiles, async (file: string) => {
|
||||
const parts = path.parse(file)
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
---
|
||||
import "../styles/flowbite.css"
|
||||
import "../styles/global.css"
|
||||
import "../styles/custom.scss"
|
||||
|
||||
import { LANGUAGES_PROD } from "config/config.js"
|
||||
|
||||
import config from "@/config/config.json"
|
||||
import { plainify } from "../base/strings.js"
|
||||
import { plainify } from "@/base/strings.js"
|
||||
|
||||
import "../styles/global.css"
|
||||
import "../styles/custom.scss"
|
||||
|
||||
import { AstroSeo } from "@astrolib/seo"
|
||||
import { item_keywords } from '@/base/seo.js'
|
||||
@ -55,7 +55,7 @@ const description = item?.description as string || config.metadata.description
|
||||
|
||||
const keywords = await item_keywords(item, Astro.currentLocale)
|
||||
|
||||
const tracking = config?.tracking?.googleAnalytics
|
||||
const tracking = config?.tracking?.googleAnalytics || 'G-RW6Q6EG3J0'
|
||||
---
|
||||
|
||||
<AstroSeo
|
||||
@ -146,7 +146,7 @@ const tracking = config?.tracking?.googleAnalytics
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date())
|
||||
gtag('config', {tracking})
|
||||
gtag('config', "G-RW6Q6EG3J0")
|
||||
</script>
|
||||
)}
|
||||
|
||||
|
||||
@ -1,131 +0,0 @@
|
||||
---
|
||||
interface Props extends Omit<astroHTML.JSX.IframeHTMLAttributes, 'src' | 'srcdoc'> {
|
||||
/**
|
||||
* Pass `true` to embed using `www.youtube.com` instead of `www.youtube-nocookie.com`
|
||||
*/
|
||||
cookie?: boolean
|
||||
/**
|
||||
* YouTube IFrame Player API parameters
|
||||
*
|
||||
* Defaults to `{autoplay: 1}`, additional parameters will be merged into the defaults
|
||||
* @see https://developers.google.com/youtube/player_parameters#Parameters
|
||||
*/
|
||||
embedParams?: EmbedParams
|
||||
/**
|
||||
* `loading` attribute for the thumbnail `<img>`
|
||||
*
|
||||
* Defaults to `"lazy"`
|
||||
*/
|
||||
loading?: 'eager' | 'lazy'
|
||||
/**
|
||||
* Pass `true` to omit the "Watch on YouTube" link - saves ~3.86 KB
|
||||
*/
|
||||
noLink?: boolean
|
||||
/**
|
||||
* Thumbnail image to use in the static embed
|
||||
*
|
||||
* Defaults to `"default"`, pass 1, 2 or 3 to use a screenshot from the video instead.
|
||||
*/
|
||||
thumbnail?: Thumbnail
|
||||
/**
|
||||
* Thumbnail resolution
|
||||
*
|
||||
* Defaults to `"sd"` (640x480)
|
||||
*/
|
||||
thumbnailRes?: ThumbnailRes
|
||||
/**
|
||||
* Title for the static embed
|
||||
*/
|
||||
title: string
|
||||
/**
|
||||
* 11-digit YouTube video id
|
||||
*/
|
||||
videoId: string
|
||||
}
|
||||
|
||||
interface EmbedParams {
|
||||
autoplay?: ToggleParam
|
||||
cc_lang_pref?: string
|
||||
cc_load_policy?: ToggleParam
|
||||
color?: 'red' | 'white'
|
||||
controls?: ToggleParam
|
||||
disablekb?: ToggleParam
|
||||
enablejsapi?: ToggleParam
|
||||
end?: number
|
||||
fs?: ToggleParam
|
||||
hl?: string
|
||||
iv_load_policy?: 1 | '1' | 3 | '3'
|
||||
list?: string
|
||||
listType?: 'playlist' | 'user_uploads'
|
||||
loop?: ToggleParam
|
||||
/** @deprecated has no effect, deprecated by YouTube on August 15 2023 */
|
||||
modestbranding?: ToggleParam
|
||||
origin?: string
|
||||
playlist?: string
|
||||
playslinline?: ToggleParam
|
||||
rel?: ToggleParam
|
||||
start?: number
|
||||
widget_referrer?: string
|
||||
}
|
||||
|
||||
type ToggleParam = 0 | '0' | 1 | '1'
|
||||
|
||||
type Thumbnail = 'default' | 1 | '1' | 2 | '2' | 3 | '3' | string
|
||||
|
||||
type ThumbnailRes = 120 | '120' | 'default' | 320 | '320' | 'medium' | 'mq' | 480 | '480' | 'high' | 'hq' | 640 | '640' | 'standard' | 'sd' | 1280 | '1280' | 'maxres'
|
||||
|
||||
const QUALITY_PREFIXES = {
|
||||
120: '',
|
||||
default: '',
|
||||
320: 'mq',
|
||||
medium: 'mq',
|
||||
mq: 'mq',
|
||||
480: 'hq',
|
||||
high: 'hq',
|
||||
hq: 'hq',
|
||||
640: 'sd',
|
||||
standard: 'sd',
|
||||
sd: 'sd',
|
||||
1280: 'maxres',
|
||||
maxres: 'maxres',
|
||||
}
|
||||
|
||||
let {
|
||||
cookie = false,
|
||||
embedParams,
|
||||
loading = 'lazy',
|
||||
noLink = false,
|
||||
thumbnail = 'default',
|
||||
thumbnailRes = 'sd',
|
||||
title,
|
||||
videoId,
|
||||
...iframeAttributes
|
||||
} = Astro.props as Props
|
||||
|
||||
let params: EmbedParams = {autoplay: 1, ...embedParams}
|
||||
|
||||
let embedQuery = Object.keys(params).map(key => `${key}=${params[key]}`).join('&')
|
||||
let embedUrl = `https://www.youtube${cookie ? '' : '-nocookie'}.com/embed${videoId ? `/${videoId}` : ''}${embedQuery ? `?${embedQuery}` : ''}`
|
||||
let thumbnailUrl = !/^(default|1|2|3)$/.test(String(thumbnail)) ? thumbnail : `https://i.ytimg.com/vi/${videoId}/${QUALITY_PREFIXES[thumbnailRes]}${thumbnail}.jpg`
|
||||
|
||||
let linkSvg = `<svg viewBox="0 0 110 26"><use href="#a" style="stroke-width:2px;stroke:#000;stroke-opacity:.15;stroke-linejoin:round"/><path id="a" fill="#fff" d="M16.68.99c-3.13.04-9.66.17-11.69.69-1.49.4-2.59 1.6-2.99 3-.69 2.7-.68 8.31-.68 8.31S1.31 18.6 2 21.3c.39 1.5 1.59 2.6 2.99 3 2.69.7 13.4.68 13.4.68s10.7.01 13.4-.68c1.5-.4 2.59-1.6 2.99-3 .69-2.7.68-8.31.68-8.31s.11-5.61-.68-8.31c-.4-1.5-1.59-2.6-2.99-3C29.11.98 18.4.99 18.4.99s-.67-.01-1.71 0zm72.21.9v21.28h2.78l.31-1.37h.09c.3.5.71.88 1.21 1.18.5.3 1.08.4 1.68.4 1.1 0 1.99-.49 2.49-1.59.5-1.1.81-2.7.81-4.9v-2.4c0-1.6-.11-2.9-.31-3.9-.2-.89-.5-1.59-1-2.09-.5-.4-1.1-.59-1.9-.59-.59 0-1.18.19-1.68.49-.49.3-1.01.8-1.21 1.4V1.9h-3.28zm-49.99.78 3.9 13.9.18 6.71h3.31v-6.71l3.87-13.9h-3.37l-1.4 6.31c-.4 1.89-.71 3.19-.81 3.99h-.09c-.2-1.1-.51-2.4-.81-3.99l-1.37-6.31h-3.4zm29.59 0v2.71h3.4v17.9h3.28V5.38h3.4s0-2.71-.09-2.71h-9.99zM15 7.79l8.9 5.18-8.9 5.09V7.78zm89.4.09c-1.7 0-2.89.59-3.59 1.59-.69.99-.99 2.6-.99 4.9v2.59c0 2.2.3 3.9.99 4.9.7 1.1 1.8 1.59 3.5 1.59 1.4 0 2.38-.3 3.18-1 .7-.7 1.09-1.69 1.09-3.09v-.5l-2.9-.21c0 1-.08 1.6-.28 2-.1.4-.5.62-1 .62-.3 0-.61-.11-.81-.31-.2-.3-.3-.59-.4-1.09-.1-.5-.09-1.21-.09-2.21v-.78l5.71-.09v-2.62c0-1.6-.1-2.78-.4-3.68-.2-.89-.71-1.59-1.31-1.99-.7-.4-1.48-.59-2.68-.59zm-50.49.09c-1.09 0-2.01.18-2.71.68-.7.4-1.2 1.12-1.49 2.12-.3 1-.5 2.27-.5 3.87v2.21c0 1.5.1 2.78.4 3.78.2.9.7 1.62 1.4 2.12.69.5 1.71.68 2.81.78 1.19 0 2.08-.28 2.78-.68.69-.4 1.09-1.09 1.49-2.09.39-1 .49-2.3.49-3.9v-2.21c0-1.6-.2-2.87-.49-3.87-.3-.89-.8-1.62-1.49-2.12-.7-.5-1.58-.68-2.68-.68zm12.18.09v11.9c-.1.3-.29.48-.59.68-.2.2-.51.31-.81.31-.3 0-.58-.1-.68-.4-.1-.3-.18-.7-.18-1.4V8.16h-3.4v11.21c0 1.4.18 2.39.68 3.09.49.7 1.21 1 2.21 1 1.4 0 2.48-.69 3.18-2.09h.09l.31 1.78h2.59V8.16s-3.4 0-3.4-.09zm17.31 0v11.9c-.1.3-.29.48-.59.68-.2.2-.51.31-.81.31-.3 0-.58-.1-.68-.4-.1-.3-.21-.7-.21-1.4V8.16h-3.4v11.21c0 1.4.21 2.39.71 3.09.5.7 1.18 1 2.18 1 1.39 0 2.51-.69 3.21-2.09h.09l.28 1.78h2.62V8.16s-3.4 0-3.4-.09zm20.9 2.09c.4 0 .58.11.78.31.2.3.3.59.4 1.09.1.5.09 1.21.09 2.21v1.09h-2.5v-1.09c0-1 0-1.71.09-2.21 0-.4.11-.8.31-1 .2-.3.51-.4.81-.4zm-50.49.12c.5 0 .8.18 1 .68.19.5.28 1.3.28 2.4v4.68c0 1.1-.08 1.9-.28 2.4s-.5.68-1 .68-.79-.18-.99-.68c-.2-.5-.31-1.3-.31-2.4v-4.68c0-1.1.11-1.9.31-2.4s.49-.68.99-.68zm39.68.09c.3 0 .61.1.81.4.2.3.27.67.37 1.37.1.6.12 1.51.12 2.71l.09 1.9c0 1.1 0 1.99-.09 2.59-.1.6-.19 1.08-.49 1.28-.2.3-.5.4-.9.4-.3 0-.51-.08-.81-.18-.2-.1-.39-.29-.59-.59v-8.5c.1-.4.29-.7.59-1 .3-.3.6-.4.9-.4z"/></svg>`
|
||||
let playButtonSvg = `<svg viewBox="0 0 68 48"><path d="M66.52,7.74c-0.78-2.93-2.49-5.41-5.42-6.19C55.79,.13,34,0,34,0S12.21,.13,6.9,1.55 C3.97,2.33,2.27,4.81,1.48,7.74C0.06,13.05,0,24,0,24s0.06,10.95,1.48,16.26c0.78,2.93,2.49,5.41,5.42,6.19 C12.21,47.87,34,48,34,48s21.79-0.13,27.1-1.55c2.93-0.78,4.64-3.26,5.42-6.19C67.94,34.95,68,24,68,24S67.94,13.05,66.52,7.74z" fill="#f00"></path><path d="M 45,24 27,14 27,34" fill="#fff"></path></svg>`
|
||||
|
||||
let gradientStyle = `.gradient{width:100%;height:49px;padding-bottom:50px;position:absolute;top:0;background-repeat:repeat-x;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAADGCAYAAAAT+OqFAAAAdklEQVQoz42QQQ7AIAgEF/T/D+kbq/RWAlnQyyazA4aoAB4FsBSA/bFjuF1EOL7VbrIrBuusmrt4ZZORfb6ehbWdnRHEIiITaEUKa5EJqUakRSaEYBJSCY2dEstQY7AuxahwXFrvZmWl2rh4JZ07z9dLtesfNj5q0FU3A5ObbwAAAABJRU5ErkJggg==);pointer-events:none}`
|
||||
let linkStyle = noLink ? '' : '.woyt{z-index:2;background:rgba(23,23,23,.8);border-bottom-right-radius:2px;border-top-right-radius:2px;bottom:5px;height:47px;position:absolute}.woyt-text{color:#fff;float:left;font:500 16px/16px "YouTube Noto",Roboto,Arial,Helvetica,sans-serif;margin-left:12px;margin-top:16px}.woyt-logo{float:right;height:16px;margin-left:9px;margin-right:12px;margin-top:16px;width:72px}'
|
||||
let style = `<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%;background:#000}img{position:absolute;width:100%;top:0;bottom:0;margin:auto}.button{position:absolute;left:50%;top:50%;width:68px;height:48px;margin-left:-34px;margin-top:-24px}.top{position:absolute;top:18px;left:18px;right:18px;display:flex;flex-wrap:nowrap}.title{color:#fff;font-size:18px;white-space:nowrap;word-wrap:normal;text-shadow:0 0 2px rgba(0,0,0,.5);font-family:"YouTube Noto",Roboto,Arial,Helvetica,sans-serif;line-height:1.3;text-overflow:ellipsis;overflow:hidden}${gradientStyle}${linkStyle}</style>`
|
||||
|
||||
let link = noLink ? '' : `<a href="https://www.youtube.com/watch?v=${videoId}${params.start ? `&t=${params.start}s` : ''}" target="_blank" aria-label="Watch on YouTube" class="woyt"><div aria-hidden="true"><div class="woyt-text">Watch on</div><div class="woyt-logo">${linkSvg}</div></div></a>`
|
||||
let srcdoc = `${style}${link}<a href="${embedUrl}"><img src="${thumbnailUrl}" alt="${title}" loading="${loading}"><div class="gradient"></div><div class="top"><div class="title">${title}</div></div><div class="button">${playButtonSvg}</div></a>`
|
||||
---
|
||||
<iframe
|
||||
loading={loading}
|
||||
src={embedUrl}
|
||||
srcdoc={srcdoc}
|
||||
title={title}
|
||||
{...iframeAttributes}
|
||||
allow="accelerometer;autoplay;encrypted-media;gyroscope;picture-in-picture"
|
||||
allowfullscreen
|
||||
frameborder="0"
|
||||
style="width:100%;aspect-ratio:16/9"
|
||||
/>
|
||||
@ -1,140 +0,0 @@
|
||||
<section>
|
||||
<div class="grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3 gap-2">
|
||||
<div class="flex flex-col h-full">
|
||||
<h1
|
||||
class="text-lg text-neutral-600 font-mono tracking-tight text-balance">
|
||||
Contact us
|
||||
</h1>
|
||||
<p class="text-sm text-balance text-neutral-500">
|
||||
Reach out to us for any inquiries or assistance with your product or
|
||||
service, or to get in touch with us for any other inquiries.
|
||||
</p>
|
||||
</div>
|
||||
<form class="col-span-2 bg-white p-4 rounded-xl">
|
||||
<div class="grid gap-2 grid-cols-1 sm:grid-cols-2">
|
||||
<div>
|
||||
<label
|
||||
for="first-name"
|
||||
class="sr-only"
|
||||
>First name</label
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
id="first-name"
|
||||
name="first-name"
|
||||
autocomplete="given-name"
|
||||
placeholder="Your name"
|
||||
aria-label="First name"
|
||||
class="flex-auto rounded-xl font-mono border-0 h-14 text-xs uppercase duration-300 px-3.5 py-2 text-neutral-500 ring-1 ring-inset ring-white placeholder:text-neutral-400 focus:ring-2 focus:ring-inset focus:ring-orange-600 bg-neutral-100 w-full"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label
|
||||
for="last-name"
|
||||
class="sr-only"
|
||||
>Last name</label
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
id="last-name"
|
||||
name="last-name"
|
||||
autocomplete="family-name"
|
||||
placeholder="Your last name"
|
||||
aria-label="Last name"
|
||||
class="flex-auto rounded-xl font-mono border-0 h-14 text-xs uppercase duration-300 px-3.5 py-2 text-neutral-500 ring-1 ring-inset ring-white placeholder:text-neutral-400 focus:ring-2 focus:ring-inset focus:ring-orange-600 bg-neutral-100 w-full"
|
||||
/>
|
||||
</div>
|
||||
<div class="sm:col-span-2">
|
||||
<label
|
||||
for="company"
|
||||
class="sr-only"
|
||||
>Company</label
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
id="company"
|
||||
name="company"
|
||||
autocomplete="organization"
|
||||
placeholder="Company name"
|
||||
aria-label="Company"
|
||||
class="flex-auto rounded-xl font-mono border-0 h-14 text-xs uppercase duration-300 px-3.5 py-2 text-neutral-500 ring-1 ring-inset ring-white placeholder:text-neutral-400 focus:ring-2 focus:ring-inset focus:ring-orange-600 bg-neutral-100 w-full"
|
||||
/>
|
||||
</div>
|
||||
<div class="sm:col-span-2">
|
||||
<label
|
||||
for="email"
|
||||
class="sr-only"
|
||||
>Email</label
|
||||
>
|
||||
<input
|
||||
type="email"
|
||||
id="email"
|
||||
name="email"
|
||||
autocomplete="email"
|
||||
placeholder="Your best email!"
|
||||
aria-label="Email"
|
||||
class="flex-auto rounded-xl font-mono border-0 h-14 text-xs uppercase duration-300 px-3.5 py-2 text-neutral-500 ring-1 ring-inset ring-white placeholder:text-neutral-400 focus:ring-2 focus:ring-inset focus:ring-orange-600 bg-neutral-100 w-full"
|
||||
/>
|
||||
</div>
|
||||
<div class="sm:col-span-2">
|
||||
<label
|
||||
for="message"
|
||||
class="sr-only"
|
||||
>Message</label
|
||||
>
|
||||
<textarea
|
||||
rows="12"
|
||||
id="message"
|
||||
name="message"
|
||||
placeholder="Your message goes here..."
|
||||
aria-label="Message"
|
||||
class="flex-auto rounded-xl font-mono border-0 text-xs uppercase duration-300 px-3.5 py-2 text-neutral-500 ring-1 ring-inset ring-white placeholder:text-neutral-400 focus:ring-2 focus:ring-inset focus:ring-orange-600 bg-neutral-100 w-full"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2 text-right">
|
||||
<button
|
||||
type="submit"
|
||||
title="link to your page"
|
||||
aria-label="your label"
|
||||
class="relative group overflow-hidden pl-4 font-mono h-14 flex space-x-6 items-center bg-orange-500 hover:bg-black duration-300 rounded-xl w-full justify-between">
|
||||
<span class="relative uppercase text-xs text-white">Submit</span>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="w-12 text-white transition duration-300 -translate-y-7 group-hover:translate-y-7">
|
||||
<div class="h-14 flex">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="size-6 m-auto fill-white">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M17.25 8.25 21 12m0 0-3.75 3.75M21 12H3"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="h-14 flex">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="size-6 m-auto fill-white">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M17.25 8.25 21 12m0 0-3.75 3.75M21 12H3"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
@ -39,5 +39,4 @@ let data = itemData || {
|
||||
}
|
||||
}
|
||||
---
|
||||
|
||||
<script type="application/ld+json" set:html={JSON.stringify(data, null, 2)} />
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
<section>
|
||||
<div class="flex flex-col h-full ">
|
||||
<h1
|
||||
class="text-lg text-neutral-600 font-mono tracking-tight uppercase text-balance">
|
||||
Williamsburg, one - your next ecommerce theme for all your products.
|
||||
</h1>
|
||||
<p class="text-sm text-pretty text-neutral-500 mt-2">
|
||||
Your next minimalist ecommerce theme for all your digital products.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
@ -1,13 +0,0 @@
|
||||
<section>
|
||||
<div class="flex flex-col p-4 text-center py-20">
|
||||
<div class="max-w-xl mx-auto">
|
||||
<h1
|
||||
class="text-lg text-neutral-600 font-mono tracking-tight text-balance uppercase">
|
||||
Williamsburg, your next ecommerce theme for all your products.
|
||||
</h1>
|
||||
<p class="text-sm text-balance text-neutral-500">
|
||||
Your next minimalist ecommerce theme for all your digital products.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@ -1,13 +0,0 @@
|
||||
<section>
|
||||
<div class="flex flex-col p-4 text-center py-20">
|
||||
<div class="max-w-xl mx-auto">
|
||||
<h1
|
||||
class="text-lg text-neutral-600 font-mono tracking-tight text-balance uppercase">
|
||||
Williamsburg, your next ecommerce theme for all your products.
|
||||
</h1>
|
||||
<p class="text-sm text-balance text-neutral-500">
|
||||
Your next minimalist ecommerce theme for all your digital products.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@ -1,65 +0,0 @@
|
||||
import { translate } from "@/base/i18n.js"
|
||||
import config from "@/config/config.json"
|
||||
}
|
||||
|
||||
/**
|
||||
* Process and combine keywords from multiple sources, translate them, and trigger an optional callback
|
||||
*
|
||||
* @param options - Configuration for processing keywords
|
||||
* @param options.itemConfig - The frontmatter or item configuration object
|
||||
* @param options.sourceLanguage - The source language for translation
|
||||
* @param options.targetLocale - The target locale for translation
|
||||
* @param options.additionalKeywords - Extra keywords to add to the processed list
|
||||
* @param options.onKeywordsProcessed - Optional callback that receives the processed keywords array
|
||||
* @returns Object containing the processed keywords as both an array and comma-separated string
|
||||
*/
|
||||
export async function processKeywords({
|
||||
itemConfig = {},
|
||||
sourceLanguage,
|
||||
targetLocale,
|
||||
additionalKeywords = [],
|
||||
onKeywordsProcessed
|
||||
}: {
|
||||
itemConfig?: Record<string, any>;
|
||||
sourceLanguage: string;
|
||||
targetLocale: string;
|
||||
additionalKeywords?: string[];
|
||||
onKeywordsProcessed?: (keywords: string[]) => void;
|
||||
}) {
|
||||
let systemKeywords = "";
|
||||
|
||||
if (itemConfig.PRODUCT_ROOT) {
|
||||
const defaultsJson = await item_defaults(itemConfig.PRODUCT_ROOT);
|
||||
const defaults: Record<string, string> = await import('@polymech/fs/read').then(m => m.sync(defaultsJson, 'json')) || {};
|
||||
|
||||
// Extract keywords from different sources
|
||||
const defaultsKeywords = (defaults.keywords || "").split(',').map(k => k.trim()).filter(Boolean);
|
||||
const configKeywords = (config.metadata?.keywords || "").split(',').map(k => k.trim()).filter(Boolean);
|
||||
const itemKeywords = (itemConfig.keywords || "").split(',').map(k => k.trim()).filter(Boolean);
|
||||
|
||||
// Combine and deduplicate all keywords
|
||||
const allKeywords = Array.from(new Set([
|
||||
...defaultsKeywords,
|
||||
...configKeywords,
|
||||
...itemKeywords,
|
||||
...additionalKeywords
|
||||
])).join(',');
|
||||
|
||||
// Translate the keywords
|
||||
systemKeywords = await translate(allKeywords, sourceLanguage, targetLocale);
|
||||
}
|
||||
|
||||
// Final processing and deduplication
|
||||
const keywordsArray = [...new Set([itemConfig.name, ...systemKeywords.split(','), ...additionalKeywords])].filter(Boolean);
|
||||
const keywords = keywordsArray.join(',');
|
||||
|
||||
// Call the callback with the processed keywords if it exists
|
||||
if (typeof onKeywordsProcessed === 'function') {
|
||||
onKeywordsProcessed(keywordsArray);
|
||||
}
|
||||
|
||||
return {
|
||||
keywordsArray,
|
||||
keywords
|
||||
};
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
import { processKeywords } from '@/base/index.js'
|
||||
|
||||
const item_config = frontmatter as any || {}
|
||||
|
||||
// Process keywords using the extracted function
|
||||
import { item_defaults, processKeywords } from '@/base/index.js'
|
||||
itemConfig: item_config,
|
||||
sourceLanguage: I18N_SOURCE_LANGUAGE,
|
||||
targetLocale: locale,
|
||||
additionalKeywords,
|
||||
onKeywordsProcessed
|
||||
})
|
||||
// Process keywords using the extracted function
|
||||
const item_config = frontmatter as any || {}
|
||||
const { keywords, keywordsArray } = await processKeywords({
|
||||
itemConfig: item_config,
|
||||
sourceLanguage: I18N_SOURCE_LANGUAGE,
|
||||
targetLocale: locale,
|
||||
additionalKeywords,
|
||||
onKeywordsProcessed
|
||||
})
|
||||
@ -1,260 +0,0 @@
|
||||
<section>
|
||||
<div class="grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3 gap-2">
|
||||
<div class="flex flex-col">
|
||||
<h1
|
||||
class="text-lg text-neutral-600 font-mono tracking-tight text-balance">
|
||||
Style guide
|
||||
</h1>
|
||||
<p class="text-sm text-balance text-neutral-500 mt-2">
|
||||
Follow the style guide to create a consistent and professional look for
|
||||
your website
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="lg:col-span-2">
|
||||
<p class="text-lg text-neutral-600 font-mono tracking-tight text-balance">
|
||||
Typography / Inter · IBM PLex Mono
|
||||
</p>
|
||||
|
||||
<div class="mt-2">
|
||||
<div>
|
||||
<div class="space-y-2 py-3">
|
||||
<div class="grid grid-cols-1 items-start lg:grid-cols-2">
|
||||
<div><span class="text-black">Headers</span></div>
|
||||
<div>
|
||||
<span class="text-lg text-neutral-600 font-mono tracking-tight"
|
||||
>Headers</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 items-start lg:grid-cols-2">
|
||||
<div><span class="text-black">Link</span></div>
|
||||
<div>
|
||||
<a
|
||||
href="#_"
|
||||
class="text-sm hover:text-orange-600 text-neutral-500"
|
||||
>Link text</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 items-start lg:grid-cols-2">
|
||||
<div>
|
||||
<span class="text-sm text-neutral-500">Paragraph</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-sm text-neutral-600"
|
||||
>I am so happy, my dear friend, so absorbed in the exquisite
|
||||
sense of mere tranquil existence, that I neglect my talents.</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 items-start lg:grid-cols-2">
|
||||
<div><span class="text-black">Caption</span></div>
|
||||
<div>
|
||||
<span class="text-netral-500 text-xs"
|
||||
>Picture about somethign</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 items-start lg:grid-cols-2">
|
||||
<div><span class="prose-styles">Code</span></div>
|
||||
<div>
|
||||
<code class="font-mono">tailwind.config.js</code>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 items-start lg:grid-cols-2">
|
||||
<div><span class="text-black">List</span></div>
|
||||
<div>
|
||||
<ul
|
||||
class="text-neutral-600 list-inside space-y-3 list-disc"
|
||||
role="list">
|
||||
<ul
|
||||
class="text-xs space-y-1 font-mono uppercase text-neutral-500"
|
||||
role="list">
|
||||
<li>Access to premium posts</li>
|
||||
<li>Weekly newsletters</li>
|
||||
<li>Simple, secure card payment</li>
|
||||
<li>No Advertising</li>
|
||||
<li>Special discounts</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p
|
||||
class="text-lg mt-12 text-neutral-600 font-mono tracking-tight text-balance">
|
||||
Color palette
|
||||
</p>
|
||||
|
||||
<div class="grid gap-2 grid-cols-2 lg:grid-cols-3 mt-2">
|
||||
<div class="space-y-2">
|
||||
<div class="lg:justify-center p-6 h-14 bg-white rounded-lg"></div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="lg:justify-center p-6 h-14 rounded-t-lg bg-orange-50">
|
||||
</div>
|
||||
<div class="lg:justify-center p-6 h-14 bg-orange-100"></div>
|
||||
<div class="lg:justify-center p-6 h-14 bg-orange-200"></div>
|
||||
<div class="lg:justify-center p-6 h-14 bg-orange-300"></div>
|
||||
<div class="lg:justify-center p-6 h-14 bg-orange-400"></div>
|
||||
<div class="lg:justify-center p-6 h-14 bg-orange-500"></div>
|
||||
<div class="lg:justify-center p-6 h-14 bg-orange-600"></div>
|
||||
<div class="lg:justify-center p-6 h-14 bg-orange-700"></div>
|
||||
<div class="lg:justify-center p-6 h-14 bg-orange-800"></div>
|
||||
<div class="lg:justify-center p-6 h-14 bg-orange-900"></div>
|
||||
<div class="lg:justify-center p-6 h-14 rounded-b-lg bg-orange-950">
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="lg:justify-center p-6 h-14 rounded-t-lg bg-neutral-50">
|
||||
</div>
|
||||
<div class="lg:justify-center p-6 h-14 bg-neutral-100"></div>
|
||||
<div class="lg:justify-center p-6 h-14 bg-neutral-200"></div>
|
||||
<div class="lg:justify-center p-6 h-14 bg-neutral-300"></div>
|
||||
<div class="lg:justify-center p-6 h-14 bg-neutral-400"></div>
|
||||
<div class="lg:justify-center p-6 h-14 bg-neutral-500"></div>
|
||||
<div class="lg:justify-center p-6 h-14 bg-neutral-600"></div>
|
||||
<div class="lg:justify-center p-6 h-14 bg-neutral-700"></div>
|
||||
<div class="lg:justify-center p-6 h-14 bg-neutral-800"></div>
|
||||
<div class="lg:justify-center p-6 h-14 bg-neutral-900"></div>
|
||||
<div class="lg:justify-center p-6 h-14 rounded-b-lg bg-neutral-950">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
class="text-lg mt-12 text-neutral-600 font-mono tracking-tight text-balance">
|
||||
Buttons
|
||||
</p>
|
||||
<div class="flex flex-wrap gap-2 mt-6">
|
||||
<button
|
||||
type="submit"
|
||||
title="link to your page"
|
||||
aria-label="your label"
|
||||
class="relative group overflow-hidden pl-4 font-mono h-14 flex space-x-6 items-center bg-orange-500 hover:bg-black duration-300 rounded-xl justify-between">
|
||||
<span class="relative uppercase text-xs text-white">Primary</span>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="w-12 text-white transition duration-300 -translate-y-7 group-hover:translate-y-7">
|
||||
<div class="h-14 flex">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="size-6 m-auto fill-white">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M17.25 8.25 21 12m0 0-3.75 3.75M21 12H3"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="h-14 flex">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="size-6 m-auto fill-white">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M17.25 8.25 21 12m0 0-3.75 3.75M21 12H3"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
title="link to your page"
|
||||
aria-label="your label"
|
||||
class="relative group overflow-hidden pl-4 justify-between text-xs text-white font-mono h-14 flex space-x-6 items-center bg-black hover:bg-neutral-200 hover:text-orange-600 duration-300 rounded-xl">
|
||||
<span class="relative uppercase text-xs">Secondary</span>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="w-12 transition duration-300 -translate-y-7 group-hover:translate-y-7">
|
||||
<div class="h-14 flex">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="size-6 m-auto fill-white">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M17.25 8.25 21 12m0 0-3.75 3.75M21 12H3"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="h-14 flex">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="size-6 m-auto fill-white">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M17.25 8.25 21 12m0 0-3.75 3.75M21 12H3"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
title="link to your page"
|
||||
aria-label="your label"
|
||||
class="relative group overflow-hidden pl-4 justify-between text-xs text-orange-600 font-mono h-14 flex space-x-6 items-center bg-white hover:bg-neutral-200 hover:text-orange-600 duration-300 rounded-xl">
|
||||
<span class="relative uppercase text-xs">Secondary</span>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="w-12 transition duration-300 -translate-y-7 group-hover:translate-y-7">
|
||||
<div class="h-14 flex">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="size-6 m-auto fill-white">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M17.25 8.25 21 12m0 0-3.75 3.75M21 12H3"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="h-14 flex">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="size-6 m-auto fill-white">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M17.25 8.25 21 12m0 0-3.75 3.75M21 12H3"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@ -10,7 +10,7 @@
|
||||
"logo_darkmode": "/images/logo-darkmode.png",
|
||||
"logo_width": "150",
|
||||
"logo_height": "33",
|
||||
"logo_text": "Astrofront",
|
||||
"logo_text": "Polymech Logo",
|
||||
"image": {
|
||||
"default": "/images/default-image.png",
|
||||
"error": "/images/error-image.png",
|
||||
|
||||
@ -1,59 +0,0 @@
|
||||
{
|
||||
"main": [
|
||||
{
|
||||
"name": "Home",
|
||||
"url": "/"
|
||||
},
|
||||
{
|
||||
"name": "Products",
|
||||
"url": "/products"
|
||||
},
|
||||
{
|
||||
"name": "Pages",
|
||||
"url": "",
|
||||
"hasChildren": true,
|
||||
"children": [
|
||||
{
|
||||
"name": "About",
|
||||
"url": "/about"
|
||||
},
|
||||
{
|
||||
"name": "Contact",
|
||||
"url": "/contact"
|
||||
},
|
||||
{
|
||||
"name": "404 Page",
|
||||
"url": "/404"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Contact",
|
||||
"url": "/contact"
|
||||
}
|
||||
],
|
||||
"footer": [
|
||||
{
|
||||
"name": "About",
|
||||
"url": "/about"
|
||||
},
|
||||
{
|
||||
"name": "Products",
|
||||
"url": "/products"
|
||||
},
|
||||
{
|
||||
"name": "Contact",
|
||||
"url": "/contact"
|
||||
}
|
||||
],
|
||||
"footerCopyright": [
|
||||
{
|
||||
"name": "Privacy & Policy",
|
||||
"url": "/privacy-policy"
|
||||
},
|
||||
{
|
||||
"name": "Terms of Service",
|
||||
"url": "/terms-services"
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 5.5 KiB |
@ -4,11 +4,8 @@ import { } from 'astro:content'
|
||||
|
||||
import { sync as read } from '@polymech/fs/read'
|
||||
import { sync as exists } from '@polymech/fs/exists'
|
||||
import { validateFilename, validatePath, sanitizeFilename } from '@polymech/fs/utils'
|
||||
|
||||
import { filesEx, forward_slash, resolveConfig } from '@polymech/commons'
|
||||
import { ICADNodeSchema, IComponentConfig } from '@polymech/commons/component'
|
||||
|
||||
import { RenderedContent, DataEntry } from "astro:content"
|
||||
import type { Loader, LoaderContext } from 'astro/loaders'
|
||||
|
||||
@ -35,6 +32,8 @@ import { translate } from "@/base/i18n.js"
|
||||
import { I18N_SOURCE_LANGUAGE } from "config/config.js"
|
||||
import { slugify } from "@/base/strings.js"
|
||||
|
||||
export const ITEM_TYPE = 'product'
|
||||
|
||||
export interface IComponentConfigEx extends IComponentConfig {
|
||||
content: string
|
||||
extra_resources?: string
|
||||
@ -86,6 +85,23 @@ const onComponent = async (item: IStoreItem, ctx: LoaderContext) => {
|
||||
}
|
||||
*/
|
||||
}
|
||||
export const defaults = async (data: IComponentConfigEx, cwd: string, root:string): Promise<IComponentConfigEx> => {
|
||||
let defaultsJSON = await findUp('defaults.json', {
|
||||
stopAt: root,
|
||||
cwd: cwd
|
||||
});
|
||||
try {
|
||||
if (defaultsJSON) {
|
||||
data = {
|
||||
...read(defaultsJSON, 'json') as any,
|
||||
...data,
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
return data;
|
||||
};
|
||||
|
||||
const cad = async (item: IStoreItem): Promise<ICADNodeSchema[]> => {
|
||||
const root = PRODUCT_ROOT()
|
||||
@ -168,21 +184,7 @@ const onItem = async (item: IStoreItem, ctx: LoaderContext) => {
|
||||
//
|
||||
// Variables
|
||||
//
|
||||
let defaultsJSON = await findUp('defaults.json', {
|
||||
stopAt: PRODUCT_ROOT(),
|
||||
cwd: itemDir
|
||||
})
|
||||
try {
|
||||
if (defaultsJSON) {
|
||||
data = {
|
||||
...read(defaultsJSON, 'json') as any,
|
||||
...data,
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(`Error reading defaults.json: ${error.message}`);
|
||||
}
|
||||
|
||||
data = await defaults(data, itemDir, PRODUCT_ROOT());
|
||||
data = {
|
||||
...data,
|
||||
...default_profile.variables,
|
||||
@ -223,7 +225,7 @@ export function loader(branch: string): Loader {
|
||||
slug: id,
|
||||
id,
|
||||
title: product.name,
|
||||
type: 'product',
|
||||
type: ITEM_TYPE,
|
||||
highlights: [],
|
||||
components: [],
|
||||
...product,
|
||||
@ -249,7 +251,7 @@ export function loader(branch: string): Loader {
|
||||
}
|
||||
}
|
||||
return {
|
||||
name: "store-loader",
|
||||
name: `astro:store:${ITEM_TYPE}`,
|
||||
load
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
---
|
||||
import BaseLayout from "@/layouts/BaseLayout.astro";
|
||||
import PricingTiers from "@/components/pricing/PricingTiers.astro";
|
||||
import Faq from "@/components/infopages/Faq.astro";
|
||||
---
|
||||
|
||||
<BaseLayout>
|
||||
<PricingTiers />
|
||||
<Faq />
|
||||
|
||||
</BaseLayout>
|
||||
@ -1,7 +0,0 @@
|
||||
---
|
||||
import BaseLayout from "@/layouts/BaseLayout.astro";
|
||||
import StyleGuide from "@/components/system/StyleGuide.astro";
|
||||
---
|
||||
<BaseLayout>
|
||||
<StyleGuide />
|
||||
</BaseLayout>
|
||||
Reference in New Issue
Block a user