generated from polymech/site-template
refactor pm base | config
This commit is contained in:
parent
3da1040d72
commit
a7ee97717b
@ -23,7 +23,7 @@
|
||||
"format": "unix-time"
|
||||
}
|
||||
],
|
||||
"default": "2025-12-27T18:35:25.856Z"
|
||||
"default": "2025-12-28T08:31:54.457Z"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -1,4 +1,57 @@
|
||||
{
|
||||
"llm": {
|
||||
"cache": true,
|
||||
"cache_dir": "./.cache/kbot"
|
||||
},
|
||||
"howtos": {
|
||||
"glob": "**/config.json",
|
||||
"files_web": "https://files.polymech.info/files/machines/howtos/",
|
||||
"edit_root": "https://git.polymech.io/osr-plastic/osr-machines/src/branch/master/howtos",
|
||||
"filter_llm": false,
|
||||
"llm_keywords": false,
|
||||
"annotations": false,
|
||||
"annotations_cache": false,
|
||||
"complete_resources": false,
|
||||
"add_hardware": false,
|
||||
"add_resources": false,
|
||||
"add_references": false,
|
||||
"complete_skills": false,
|
||||
"local_resources": false,
|
||||
"seo_llm": false,
|
||||
"max_items": 10,
|
||||
"root_intern": "./public/resources/howtos",
|
||||
"root": "${OSR_ROOT}/osr-machines/howtos"
|
||||
},
|
||||
"directory": {
|
||||
"glob": "**/config.json",
|
||||
"files_base": "https://files.polymech.info/files/directory/",
|
||||
"edit_root": "https://git.polymech.info/polymech/machines/src/branch/master/directory",
|
||||
"filter_llm": true,
|
||||
"annotations": false,
|
||||
"annotations_cache": false,
|
||||
"complete_resources": true,
|
||||
"add_hardware": false,
|
||||
"add_resources": true,
|
||||
"add_references": true,
|
||||
"complete_skills": false,
|
||||
"local_resources": false,
|
||||
"seo_llm": true,
|
||||
"max_items": 0,
|
||||
"migration": "./data/last.json",
|
||||
"root_intern": "./public/resources/directory",
|
||||
"root": "${OSR_ROOT}/osr-machines/directory"
|
||||
},
|
||||
"components": {
|
||||
"root": "${OSR_ROOT}/osr-machines",
|
||||
"glob": "**/config.json",
|
||||
"enabled": "${OSR_ROOT}/components/config/machines.json"
|
||||
},
|
||||
"tasks": {
|
||||
"config_log_directory": "./config/",
|
||||
"log_directory": "./logs/",
|
||||
"compile_content": true,
|
||||
"compile_content_cache": false
|
||||
},
|
||||
"site": {
|
||||
"title": "Polymech Library",
|
||||
"base_url": "https://library.polymech.info/",
|
||||
@ -154,7 +207,13 @@
|
||||
},
|
||||
"retail": {
|
||||
"library_branch": "site-dev",
|
||||
"projects_branch": "projects"
|
||||
"projects_branch": "projects",
|
||||
"compile_cache": false,
|
||||
"media_cache": true,
|
||||
"log_level_i18n_product_assets": "info",
|
||||
"convert_product_media": true,
|
||||
"translate_product_assets": false,
|
||||
"populate_product_defaults": true
|
||||
},
|
||||
"rss": {
|
||||
"title": "Polymech RSS Feed",
|
||||
@ -208,6 +267,8 @@
|
||||
"cam_main_match": "${product}/cad*/*-CNC*.+(SLDASM)"
|
||||
},
|
||||
"assets": {
|
||||
"local": false,
|
||||
"glob": "*.+(JPG|jpg|jpeg|png|PNG|gif)",
|
||||
"cad_url": "${OSR_MACHINES_ASSETS_URL}/${file}",
|
||||
"url": "${OSR_MACHINES_ASSETS_URL}/products/${product_rel_min}/${file}",
|
||||
"item_url_r": "${OSR_MACHINES_ASSETS_URL}/${ITEM_REL}/${assetPath}/${filePath}",
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
{
|
||||
"core": {
|
||||
"logging_namespace": "LOCAL_CONFIG_OVERRIDE"
|
||||
}
|
||||
}
|
||||
6
package-lock.json
generated
6
package-lock.json
generated
@ -7265,9 +7265,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001700",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001700.tgz",
|
||||
"integrity": "sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ==",
|
||||
"version": "1.0.30001761",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001761.tgz",
|
||||
"integrity": "sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
|
||||
@ -129,4 +129,4 @@
|
||||
"ts-jest": "^29.3.0",
|
||||
"vitest": "^1.3.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
264
src/app/config-types.ts
Normal file
264
src/app/config-types.ts
Normal file
@ -0,0 +1,264 @@
|
||||
export interface AppConfig {
|
||||
llm: Llm;
|
||||
howtos: Directory;
|
||||
directory: Directory;
|
||||
components: Components;
|
||||
tasks: Tasks;
|
||||
site: Site;
|
||||
footer_left: FooterLeft[];
|
||||
footer_right: any[];
|
||||
settings: Settings;
|
||||
params: Params;
|
||||
navigation: Navigation;
|
||||
navigation_button: NavigationButton;
|
||||
ecommerce: Ecommerce;
|
||||
metadata: Metadata;
|
||||
shopify: Shopify;
|
||||
pages: Pages;
|
||||
core: Core;
|
||||
dev: Dev;
|
||||
i18n: I18N;
|
||||
products: Components;
|
||||
retail: Retail;
|
||||
rss: Rss;
|
||||
osrl: Osrl;
|
||||
features: { [key: string]: boolean };
|
||||
defaults: Defaults;
|
||||
cad: Cad;
|
||||
assets: Assets;
|
||||
optimization: Optimization;
|
||||
}
|
||||
|
||||
export interface Assets {
|
||||
local: boolean;
|
||||
glob: string;
|
||||
cad_url: string;
|
||||
url: string;
|
||||
item_url_r: string;
|
||||
item_url: string;
|
||||
}
|
||||
|
||||
export interface Cad {
|
||||
cache: boolean;
|
||||
export_configurations: boolean;
|
||||
export_sub_components: boolean;
|
||||
renderer: string;
|
||||
renderer_view: string;
|
||||
renderer_quality: number;
|
||||
extensions: string[];
|
||||
model_ext: string;
|
||||
default_configuration: string;
|
||||
main_match: string;
|
||||
cam_main_match: string;
|
||||
}
|
||||
|
||||
export interface Components {
|
||||
root: string;
|
||||
glob: string;
|
||||
enabled: string;
|
||||
howto_migration?: string;
|
||||
}
|
||||
|
||||
export interface Core {
|
||||
logging_namespace: string;
|
||||
translate_content: boolean;
|
||||
languages: string[];
|
||||
languages_prod: string[];
|
||||
rtl_languages: string[];
|
||||
osr_root: string;
|
||||
}
|
||||
|
||||
export interface Defaults {
|
||||
image_url: string;
|
||||
license: string;
|
||||
contact: string;
|
||||
}
|
||||
|
||||
export interface Dev {
|
||||
file_server: string;
|
||||
}
|
||||
|
||||
export interface Directory {
|
||||
glob: string;
|
||||
files_base?: string;
|
||||
edit_root: string;
|
||||
filter_llm: boolean;
|
||||
annotations: boolean;
|
||||
annotations_cache: boolean;
|
||||
complete_resources: boolean;
|
||||
add_hardware: boolean;
|
||||
add_resources: boolean;
|
||||
add_references: boolean;
|
||||
complete_skills: boolean;
|
||||
local_resources: boolean;
|
||||
seo_llm: boolean;
|
||||
max_items: number;
|
||||
migration?: string;
|
||||
root_intern: string;
|
||||
root: string;
|
||||
files_web?: string;
|
||||
llm_keywords?: boolean;
|
||||
}
|
||||
|
||||
export interface Ecommerce {
|
||||
brand: string;
|
||||
currencySymbol: string;
|
||||
currencyCode: string;
|
||||
}
|
||||
|
||||
export interface FooterLeft {
|
||||
href: string;
|
||||
text: string;
|
||||
}
|
||||
|
||||
export interface I18N {
|
||||
store: string;
|
||||
cache: boolean;
|
||||
source_language: string;
|
||||
asset_path: string;
|
||||
}
|
||||
|
||||
export interface Llm {
|
||||
cache: boolean;
|
||||
cache_dir: string;
|
||||
}
|
||||
|
||||
export interface Metadata {
|
||||
country: string;
|
||||
city: string;
|
||||
author: string;
|
||||
author_bio: string;
|
||||
author_url: string;
|
||||
image: string;
|
||||
description: string;
|
||||
keywords: string;
|
||||
}
|
||||
|
||||
export interface Navigation {
|
||||
top: FooterLeft[];
|
||||
}
|
||||
|
||||
export interface NavigationButton {
|
||||
enable: boolean;
|
||||
label: string;
|
||||
link: string;
|
||||
}
|
||||
|
||||
export interface Optimization {
|
||||
image_settings: ImageSettings;
|
||||
presets: Presets;
|
||||
}
|
||||
|
||||
export interface ImageSettings {
|
||||
gallery: Gallery;
|
||||
lightbox: Gallery;
|
||||
}
|
||||
|
||||
export interface Gallery {
|
||||
show_title: boolean;
|
||||
show_description: boolean;
|
||||
sizes_thumb: string;
|
||||
sizes_large: string;
|
||||
sizes_regular: string;
|
||||
}
|
||||
|
||||
export interface Presets {
|
||||
slow: Fast;
|
||||
medium: Fast;
|
||||
fast: Fast;
|
||||
}
|
||||
|
||||
export interface Fast {
|
||||
sizes_medium: string;
|
||||
sizes_thumbs: string;
|
||||
sizes_large: string;
|
||||
}
|
||||
|
||||
export interface Osrl {
|
||||
env: string;
|
||||
env_dev: string;
|
||||
module_name: string;
|
||||
lang_flavor: string;
|
||||
product_profile: string;
|
||||
}
|
||||
|
||||
export interface Pages {
|
||||
home: Home;
|
||||
}
|
||||
|
||||
export interface Home {
|
||||
hero: string;
|
||||
_blog: Blog;
|
||||
}
|
||||
|
||||
export interface Blog {
|
||||
store: string;
|
||||
}
|
||||
|
||||
export interface Params {
|
||||
contact_form_action: string;
|
||||
copyright: string;
|
||||
}
|
||||
|
||||
export interface Retail {
|
||||
library_branch: string;
|
||||
projects_branch: string;
|
||||
compile_cache: boolean;
|
||||
media_cache: boolean;
|
||||
log_level_i18n_product_assets: string;
|
||||
convert_product_media: boolean;
|
||||
translate_product_assets: boolean;
|
||||
populate_product_defaults: boolean;
|
||||
}
|
||||
|
||||
export interface Rss {
|
||||
title: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface Settings {
|
||||
search: boolean;
|
||||
account: boolean;
|
||||
sticky_header: boolean;
|
||||
theme_switcher: boolean;
|
||||
default_theme: string;
|
||||
}
|
||||
|
||||
export interface Shopify {
|
||||
currencySymbol: string;
|
||||
currencyCode: string;
|
||||
collections: Collections;
|
||||
}
|
||||
|
||||
export interface Collections {
|
||||
hero_slider: string;
|
||||
featured_products: string;
|
||||
}
|
||||
|
||||
export interface Site {
|
||||
title: string;
|
||||
base_url: string;
|
||||
description: string;
|
||||
base_path: string;
|
||||
trailing_slash: boolean;
|
||||
favicon: string;
|
||||
logo: string;
|
||||
logo_darkmode: string;
|
||||
logo_width: string;
|
||||
logo_height: string;
|
||||
logo_text: string;
|
||||
image: Image;
|
||||
}
|
||||
|
||||
export interface Image {
|
||||
default: string;
|
||||
error: string;
|
||||
alt: string;
|
||||
}
|
||||
|
||||
export interface Tasks {
|
||||
config_log_directory: string;
|
||||
log_directory: string;
|
||||
compile_content: boolean;
|
||||
compile_content_cache: boolean;
|
||||
}
|
||||
67
src/app/config.d.ts
vendored
67
src/app/config.d.ts
vendored
@ -1,4 +1,9 @@
|
||||
export interface AppConfig {
|
||||
llm: Llm;
|
||||
howtos: Directory;
|
||||
directory: Directory;
|
||||
components: Components;
|
||||
tasks: Tasks;
|
||||
site: Site;
|
||||
footer_left: FooterLeft[];
|
||||
footer_right: any[];
|
||||
@ -13,7 +18,7 @@ export interface AppConfig {
|
||||
core: Core;
|
||||
dev: Dev;
|
||||
i18n: I18N;
|
||||
products: Products;
|
||||
products: Components;
|
||||
retail: Retail;
|
||||
rss: Rss;
|
||||
osrl: Osrl;
|
||||
@ -25,6 +30,8 @@ export interface AppConfig {
|
||||
}
|
||||
|
||||
export interface Assets {
|
||||
local: boolean;
|
||||
glob: string;
|
||||
cad_url: string;
|
||||
url: string;
|
||||
item_url_r: string;
|
||||
@ -45,6 +52,13 @@ export interface Cad {
|
||||
cam_main_match: string;
|
||||
}
|
||||
|
||||
export interface Components {
|
||||
root: string;
|
||||
glob: string;
|
||||
enabled: string;
|
||||
howto_migration?: string;
|
||||
}
|
||||
|
||||
export interface Core {
|
||||
logging_namespace: string;
|
||||
translate_content: boolean;
|
||||
@ -64,6 +78,28 @@ export interface Dev {
|
||||
file_server: string;
|
||||
}
|
||||
|
||||
export interface Directory {
|
||||
glob: string;
|
||||
files_base?: string;
|
||||
edit_root: string;
|
||||
filter_llm: boolean;
|
||||
annotations: boolean;
|
||||
annotations_cache: boolean;
|
||||
complete_resources: boolean;
|
||||
add_hardware: boolean;
|
||||
add_resources: boolean;
|
||||
add_references: boolean;
|
||||
complete_skills: boolean;
|
||||
local_resources: boolean;
|
||||
seo_llm: boolean;
|
||||
max_items: number;
|
||||
migration?: string;
|
||||
root_intern: string;
|
||||
root: string;
|
||||
files_web?: string;
|
||||
llm_keywords?: boolean;
|
||||
}
|
||||
|
||||
export interface Ecommerce {
|
||||
brand: string;
|
||||
currencySymbol: string;
|
||||
@ -82,6 +118,11 @@ export interface I18N {
|
||||
asset_path: string;
|
||||
}
|
||||
|
||||
export interface Llm {
|
||||
cache: boolean;
|
||||
cache_dir: string;
|
||||
}
|
||||
|
||||
export interface Metadata {
|
||||
country: string;
|
||||
city: string;
|
||||
@ -159,16 +200,15 @@ export interface Params {
|
||||
copyright: string;
|
||||
}
|
||||
|
||||
export interface Products {
|
||||
root: string;
|
||||
howto_migration: string;
|
||||
glob: string;
|
||||
enabled: string;
|
||||
}
|
||||
|
||||
export interface Retail {
|
||||
library_branch: string;
|
||||
projects_branch: string;
|
||||
library_branch: string;
|
||||
projects_branch: string;
|
||||
compile_cache: boolean;
|
||||
media_cache: boolean;
|
||||
log_level_i18n_product_assets: string;
|
||||
convert_product_media: boolean;
|
||||
translate_product_assets: boolean;
|
||||
populate_product_defaults: boolean;
|
||||
}
|
||||
|
||||
export interface Rss {
|
||||
@ -215,3 +255,10 @@ export interface Image {
|
||||
error: string;
|
||||
alt: string;
|
||||
}
|
||||
|
||||
export interface Tasks {
|
||||
config_log_directory: string;
|
||||
log_directory: string;
|
||||
compile_content: boolean;
|
||||
compile_content_cache: boolean;
|
||||
}
|
||||
|
||||
@ -1,6 +1,47 @@
|
||||
// Generated by ts-to-zod
|
||||
import { z } from "zod";
|
||||
|
||||
export const llmSchema = z.object({
|
||||
cache: z.boolean(),
|
||||
cache_dir: z.string()
|
||||
});
|
||||
|
||||
export const directorySchema = z.object({
|
||||
glob: z.string(),
|
||||
files_base: z.string().optional(),
|
||||
edit_root: z.string(),
|
||||
filter_llm: z.boolean(),
|
||||
annotations: z.boolean(),
|
||||
annotations_cache: z.boolean(),
|
||||
complete_resources: z.boolean(),
|
||||
add_hardware: z.boolean(),
|
||||
add_resources: z.boolean(),
|
||||
add_references: z.boolean(),
|
||||
complete_skills: z.boolean(),
|
||||
local_resources: z.boolean(),
|
||||
seo_llm: z.boolean(),
|
||||
max_items: z.number(),
|
||||
migration: z.string().optional(),
|
||||
root_intern: z.string(),
|
||||
root: z.string(),
|
||||
files_web: z.string().optional(),
|
||||
llm_keywords: z.boolean().optional()
|
||||
});
|
||||
|
||||
export const componentsSchema = z.object({
|
||||
root: z.string(),
|
||||
glob: z.string(),
|
||||
enabled: z.string(),
|
||||
howto_migration: z.string().optional()
|
||||
});
|
||||
|
||||
export const tasksSchema = z.object({
|
||||
config_log_directory: z.string(),
|
||||
log_directory: z.string(),
|
||||
compile_content: z.boolean(),
|
||||
compile_content_cache: z.boolean()
|
||||
});
|
||||
|
||||
export const footerLeftSchema = z.object({
|
||||
href: z.string(),
|
||||
text: z.string()
|
||||
@ -66,16 +107,15 @@ export const i18NSchema = z.object({
|
||||
asset_path: z.string()
|
||||
});
|
||||
|
||||
export const productsSchema = z.object({
|
||||
root: z.string(),
|
||||
howto_migration: z.string(),
|
||||
glob: z.string(),
|
||||
enabled: z.string()
|
||||
});
|
||||
|
||||
export const retailSchema = z.object({
|
||||
library_branch: z.string(),
|
||||
projects_branch: z.string()
|
||||
projects_branch: z.string(),
|
||||
compile_cache: z.boolean(),
|
||||
media_cache: z.boolean(),
|
||||
log_level_i18n_product_assets: z.string(),
|
||||
convert_product_media: z.boolean(),
|
||||
translate_product_assets: z.boolean(),
|
||||
populate_product_defaults: z.boolean()
|
||||
});
|
||||
|
||||
export const rssSchema = z.object({
|
||||
@ -112,6 +152,8 @@ export const cadSchema = z.object({
|
||||
});
|
||||
|
||||
export const assetsSchema = z.object({
|
||||
local: z.boolean(),
|
||||
glob: z.string(),
|
||||
cad_url: z.string(),
|
||||
url: z.string(),
|
||||
item_url_r: z.string(),
|
||||
@ -194,6 +236,11 @@ export const optimizationSchema = z.object({
|
||||
});
|
||||
|
||||
export const appConfigSchema = z.object({
|
||||
llm: llmSchema,
|
||||
howtos: directorySchema,
|
||||
directory: directorySchema,
|
||||
components: componentsSchema,
|
||||
tasks: tasksSchema,
|
||||
site: siteSchema,
|
||||
footer_left: z.array(footerLeftSchema),
|
||||
footer_right: z.array(z.any()),
|
||||
@ -208,7 +255,7 @@ export const appConfigSchema = z.object({
|
||||
core: coreSchema,
|
||||
dev: devSchema,
|
||||
i18n: i18NSchema,
|
||||
products: productsSchema,
|
||||
products: componentsSchema,
|
||||
retail: retailSchema,
|
||||
rss: rssSchema,
|
||||
osrl: osrlSchema,
|
||||
|
||||
@ -3,13 +3,22 @@ import { IMAGE_PRESET, E_BROADBAND_SPEED } from "./network.js"
|
||||
import { resolve, template } from '@polymech/commons'
|
||||
import { sync as read } from '@polymech/fs/read'
|
||||
import { sanitizeUri } from 'micromark-util-sanitize-uri'
|
||||
import { AppConfig } from './config-types.js'
|
||||
import { loadConfig } from '@polymech/astro-base/app/config-loader.js'
|
||||
import { appConfigSchema } from './config.schema.js'
|
||||
|
||||
import { loadConfig } from '@polymech/astro-base/app/config-loader'
|
||||
|
||||
const config = loadConfig()
|
||||
const config = loadConfig(
|
||||
'en',
|
||||
'./app-config.json',
|
||||
appConfigSchema
|
||||
) as AppConfig
|
||||
|
||||
export const OSR_ROOT = () => path.resolve(resolve(config.core.osr_root))
|
||||
export const FILE_SERVER_DEV = config.dev.file_server
|
||||
export const I18N_SOURCE_LANGUAGE = config.i18n.source_language
|
||||
// LLM
|
||||
export const LLM_CACHE = config.llm.cache
|
||||
export const LLM_CACHE_DIR = config.llm.cache_dir
|
||||
|
||||
export const LOGGING_NAMESPACE = config.core.logging_namespace
|
||||
export const TRANSLATE_CONTENT = config.core.translate_content
|
||||
@ -22,6 +31,58 @@ export const I18N_STORE = (root, lang) => template(config.i18n.store, { root, la
|
||||
export const I18N_CACHE = config.i18n.cache
|
||||
export const I18N_ASSET_PATH = config.i18n.asset_path
|
||||
|
||||
// Library - Howtos
|
||||
export const HOWTO_GLOB = config.howtos.glob
|
||||
export const FILES_WEB = config.howtos.files_web
|
||||
export const HOWTO_EDIT_ROOT = config.howtos.edit_root
|
||||
export const HOWTO_FILTER_LLM = config.howtos.filter_llm
|
||||
export const HOWTO_LLM_KEYWORDS = config.howtos.llm_keywords
|
||||
export const HOWTO_ANNOTATIONS = config.howtos.annotations
|
||||
export const HOWTO_ANNOTATIONS_CACHE = config.howtos.annotations_cache
|
||||
export const HOWTO_COMPLETE_RESOURCES = config.howtos.complete_resources
|
||||
export const HOWTO_ADD_HARDWARE = config.howtos.add_hardware
|
||||
export const HOWTO_ADD_RESOURCES = config.howtos.add_resources
|
||||
export const HOWTO_ADD_REFERENCES = config.howtos.add_references
|
||||
export const HOWTO_COMPLETE_SKILLS = config.howtos.complete_skills
|
||||
export const HOWTO_LOCAL_RESOURCES = config.howtos.local_resources
|
||||
export const HOWTO_SEO_LLM = config.howtos.seo_llm
|
||||
export const HOWTO_MAX_ITEMS = config.howtos.max_items
|
||||
|
||||
export const HOWTO_ROOT_INTERN = () => path.resolve(resolve(config.howtos.root_intern))
|
||||
export const HOWTO_ROOT = () => path.resolve(resolve(config.howtos.root))
|
||||
export const HOWTO_FILES_ABS = (id) => `${HOWTO_ROOT()}/${id}`
|
||||
export const HOWTO_FILES_WEB = (id: string) => `${FILES_WEB}/${id}`
|
||||
export const HOWTO_EDIT_URL = (id: string, lang: string) => `${HOWTO_EDIT_ROOT}/${id}`
|
||||
|
||||
// Library - Directory
|
||||
export const DIRECTORY_GLOB = config.directory.glob
|
||||
export const DIRECTORY_FILES_BASE = config.directory.files_base
|
||||
export const DIRECTORY_EDIT_ROOT = config.directory.edit_root
|
||||
export const DIRECTORY_FILTER_LLM = config.directory.filter_llm
|
||||
export const DIRECTORY_ANNOTATIONS = config.directory.annotations
|
||||
export const DIRECTORY_ANNOTATIONS_CACHE = config.directory.annotations_cache
|
||||
export const DIRECTORY_COMPLETE_RESOURCES = config.directory.complete_resources
|
||||
export const DIRECTORY_ADD_HARDWARE = config.directory.add_hardware
|
||||
export const DIRECTORY_ADD_RESOURCES = config.directory.add_resources
|
||||
export const DIRECTORY_ADD_REFERENCES = config.directory.add_references
|
||||
export const DIRECTORY_COMPLETE_SKILLS = config.directory.complete_skills
|
||||
export const DIRECTORY_LOCAL_RESOURCES = config.directory.local_resources
|
||||
export const DIRECTORY_SEO_LLM = config.directory.seo_llm
|
||||
export const DIRECTORY_MAX_ITEMS = config.directory.max_items
|
||||
|
||||
export const DIRECTORY_MIGRATION = () => path.resolve(resolve(config.directory.migration))
|
||||
export const DIRECTORY_ROOT_INTERN = () => path.resolve(resolve(config.directory.root_intern))
|
||||
export const DIRECTORY_ROOT = () => path.resolve(resolve(config.directory.root))
|
||||
export const DIRECTORY_FILES_ABS = (id) => `${DIRECTORY_ROOT()}/${id}`
|
||||
export const DIRECTORY_FILES_WEB = (id: string) => `${DIRECTORY_FILES_BASE}/${id}`
|
||||
export const DIRECTORY_EDIT_URL = (id: string, lang: string) => `${DIRECTORY_EDIT_ROOT}/${id}`
|
||||
|
||||
// Library Components
|
||||
export const COMPONENT_ROOT = () => path.resolve(resolve(config.components.root))
|
||||
export const COMPONENT_GLOB = config.components.glob
|
||||
export const ENABLED_COMPONENTS = resolve(config.components.enabled)
|
||||
export const COMPONENT_SPECS = (rel) => `${COMPONENT_ROOT()}/${rel}/specs.xlsx`
|
||||
|
||||
// Products
|
||||
export const HOWTO_MIGRATION = () => path.resolve(resolve(config.products.howto_migration))
|
||||
|
||||
@ -37,8 +98,14 @@ export const PRODUCT_CONFIG = (product) =>
|
||||
product
|
||||
}))
|
||||
export const PRODUCT_DIR = (product) => path.resolve(resolve(`${PRODUCT_ROOT()}/${product}`))
|
||||
export const PRODUCT_HUGO_TEMPLATE = './osr/hugo/root.html'
|
||||
export const PRODUCTS_TARGET_SRC = './src/content/en/retail'
|
||||
export const PRODUCTS_TARGET = (lang) => `./content/${lang}/products`
|
||||
|
||||
// Product assets
|
||||
export const ASSETS_LOCAL = config.assets.local
|
||||
export const ASSETS_GLOB = config.assets.glob
|
||||
|
||||
// OSRL - Language
|
||||
export const IS_DEV = true
|
||||
export const OSRL_ENV = config.osrl.env
|
||||
@ -53,24 +120,43 @@ export const ENABLED_PRODUCTS = resolve(config.products.enabled)
|
||||
export const PRODUCT_SPECS = (rel) => `${PRODUCT_ROOT()}/${rel}/specs.xlsx`
|
||||
|
||||
// Tasks
|
||||
export const TASK_CONFIG_LOG_DIRECTORY = './config/'
|
||||
export const TASK_CONFIG_LOG_DIRECTORY = config.tasks.config_log_directory
|
||||
|
||||
// Task: compile:content
|
||||
export const TASK_COMPILE_CONTENT = config.tasks.compile_content
|
||||
export const TASK_COMPILE_CONTENT_CACHE = config.tasks.compile_content_cache
|
||||
|
||||
// Task - Logging
|
||||
export const TASK_LOG_DIRECTORY = config.tasks.log_directory
|
||||
|
||||
|
||||
// Task - Retail Config
|
||||
export const REGISTER_PRODUCT_TASKS = true
|
||||
export const LIBARY_BRANCH = config.retail.library_branch
|
||||
export const PROJECTS_BRANCH = config.retail.projects_branch
|
||||
export const RETAIL_COMPILE_CACHE = false
|
||||
export const RETAIL_MEDIA_CACHE = true
|
||||
export const RETAIL_LOG_LEVEL_I18N_PRODUCT_ASSETS = 'info'
|
||||
export const RETAIL_COMPILE_CACHE = config.retail.compile_cache
|
||||
export const RETAIL_MEDIA_CACHE = config.retail.media_cache
|
||||
export const RETAIL_LOG_LEVEL_I18N_PRODUCT_ASSETS = config.retail.log_level_i18n_product_assets
|
||||
|
||||
export const ConvertProductMedia = config.retail.convert_product_media
|
||||
export const TranslateProductAssets = config.retail.translate_product_assets
|
||||
export const PopulateProductDefaults = config.retail.populate_product_defaults
|
||||
|
||||
// CAD
|
||||
export const CAD_MAIN_MATCH = (product) => template(config.cad.main_match, { product })
|
||||
export const CAD_CAM_MAIN_MATCH = (product) => template(config.cad.cam_main_match, { product })
|
||||
|
||||
export const CAD_CACHE = config.cad.cache
|
||||
export const CAD_EXPORT_CONFIGURATIONS = config.cad.export_configurations
|
||||
export const CAD_EXPORT_SUB_COMPONENTS = config.cad.export_sub_components
|
||||
export const CAD_MODEL_FILE_PATH = (SOURCE, CONFIGURATION = '') =>
|
||||
SOURCE.replace('.json', `${CONFIGURATION ? '-' + CONFIGURATION : ''}${config.cad.model_ext}`)
|
||||
|
||||
export const CAD_DEFAULT_CONFIGURATION = config.cad.default_configuration
|
||||
export const CAD_RENDERER = config.cad.renderer
|
||||
export const CAD_RENDERER_VIEW = config.cad.renderer_view
|
||||
export const CAD_RENDERER_QUALITY = config.cad.renderer_quality
|
||||
export const CAD_EXTENSIONS = config.cad.extensions
|
||||
export const CAD_MODEL_EXT = config.cad.model_ext
|
||||
|
||||
export const CAD_URL = (file: string, variables: Record<string, string>) =>
|
||||
sanitizeUri(template(config.assets.cad_url, { file, ...variables }))
|
||||
|
||||
@ -1,4 +1,9 @@
|
||||
import { z } from "zod"
|
||||
|
||||
import { loadConfig } from '@polymech/astro-base/app/config-loader.js'
|
||||
|
||||
const config = loadConfig()
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// Optimizations
|
||||
@ -24,9 +29,6 @@ const imagesSchema = z.object({
|
||||
|
||||
type Images = z.infer<typeof imagesSchema>;
|
||||
|
||||
import { loadConfig } from '@polymech/astro-base/app/config-loader.js'
|
||||
|
||||
const config = loadConfig()
|
||||
export const IMAGE_PRESET: Images =
|
||||
{
|
||||
[E_BROADBAND_SPEED.SLOW]: config.optimization.presets.slow,
|
||||
|
||||
@ -1,72 +0,0 @@
|
||||
import * as path from 'path'
|
||||
import { resolve } from '@polymech/commons'
|
||||
import { sync as exists } from '@polymech/fs/exists'
|
||||
|
||||
import type { IOptions } from '@polymech/i18n'
|
||||
import { CONFIG_DEFAULT } from '@polymech/commons'
|
||||
import {
|
||||
I18N_ASSET_PATH,
|
||||
I18N_CACHE,
|
||||
I18N_SOURCE_LANGUAGE,
|
||||
PRODUCT_SPECS,
|
||||
RETAIL_LOG_LEVEL_I18N_PRODUCT_ASSETS
|
||||
} from 'config/config.js'
|
||||
|
||||
import { translateXLS } from '@polymech/i18n/translate_xls'
|
||||
import { I18N_STORE, OSR_ROOT } from 'config/config.js'
|
||||
import { translateText } from '@polymech/i18n/translate_text'
|
||||
import { logger } from './index.js'
|
||||
|
||||
export type { IOptions } from '@polymech/i18n'
|
||||
|
||||
export const translate = async (text: string, srcLanguage = 'en', targetLanguage, opts = {}) => {
|
||||
if (!targetLanguage) {
|
||||
return text
|
||||
}
|
||||
try {
|
||||
const store = I18N_STORE(OSR_ROOT(), targetLanguage)
|
||||
let translation = text
|
||||
translation = await translateText(text, srcLanguage, targetLanguage, {
|
||||
store,
|
||||
...opts
|
||||
})
|
||||
return translation
|
||||
} catch (e) {
|
||||
logger.error(`Failed to translate text: ${text} from ${srcLanguage} to ${targetLanguage} : ${e.message}`)
|
||||
}
|
||||
return text
|
||||
}
|
||||
export const translateSheets = async (product, language) => {
|
||||
const config: any = CONFIG_DEFAULT()
|
||||
if (language === I18N_SOURCE_LANGUAGE) {
|
||||
return
|
||||
}
|
||||
const i18nOptions: IOptions = {
|
||||
srcLang: I18N_SOURCE_LANGUAGE,
|
||||
dstLang: language,
|
||||
src: PRODUCT_SPECS(product),
|
||||
store: I18N_STORE(OSR_ROOT(), language),
|
||||
dst: I18N_ASSET_PATH,
|
||||
query: "$[*][0,1,2,3]",
|
||||
cache: I18N_CACHE,
|
||||
api_key: config.deepl.auth_key,
|
||||
logLevel: RETAIL_LOG_LEVEL_I18N_PRODUCT_ASSETS
|
||||
}
|
||||
const src = `${PRODUCT_SPECS(product)}`
|
||||
const srcParts = path.parse(src)
|
||||
const dst = path.resolve(resolve(I18N_ASSET_PATH, false, {
|
||||
SRC_DIR: srcParts.dir,
|
||||
SRC_NAME: srcParts.name,
|
||||
SRC_EXT: srcParts.ext,
|
||||
DST_LANG: language
|
||||
}))
|
||||
if (I18N_CACHE && exists(dst)) {
|
||||
return dst
|
||||
}
|
||||
logger.debug(`Translate assets ${src} to ${language}`)
|
||||
try {
|
||||
return await translateXLS(path.resolve(src), dst, i18nOptions)
|
||||
} catch (e) {
|
||||
logger.error(`Failed to translate assets ${src} to ${language}`, e.message)
|
||||
}
|
||||
}
|
||||
@ -46,7 +46,7 @@ export async function markdownToHtml(markdown: string): Promise<string> {
|
||||
.use(remarkRehype, { allowDangerousHtml: true }) // ← preserve raw HTML
|
||||
.use(rehypeStringify, { allowDangerousHtml: true }) // ← allow it through
|
||||
.process(markdown);
|
||||
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
export const createMarkdownComponent = async (markdown: string) => {
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
|
||||
import { IComponentConfig } from '@polymech/commons'
|
||||
import { sync as read } from '@polymech/fs/read'
|
||||
import { I18N_SOURCE_LANGUAGE } from 'config/config.js'
|
||||
|
||||
import { translate } from '@/base/i18n.js'
|
||||
import { translate } from '@polymech/astro-base/base/i18n.js'
|
||||
import { item_defaults } from '@/base/index.js'
|
||||
|
||||
import config from "../config/config.json" with { "type": "json" }
|
||||
const I18N_SOURCE_LANGUAGE = 'en'
|
||||
|
||||
const keywords = (keywords: string) => keywords.split(',').map(k => k.trim()).filter(Boolean);
|
||||
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
---
|
||||
const { title, url, pubDate, description, image } = Astro.props;
|
||||
import { DEFAULT_IMAGE_URL } from "@/config/config";
|
||||
import { Img } from "imagetools/components";
|
||||
---
|
||||
|
||||
<div
|
||||
class="group relative flex flex-col h-full justify-between items-start p-4 bg-white text-sm text-neutral-500 rounded-2xl font-mono"
|
||||
>
|
||||
<dt>
|
||||
<h2 class="uppercase group-hover:text-orange-500 text-balance">
|
||||
<div class="z-0 scale-95 transition group-hover:scale-100"></div>
|
||||
<a href={url} title={title}>
|
||||
<span class="absolute -inset-x-4 -inset-y-6 z-20 sm:-inset-x-6"
|
||||
></span><span class="relative z-10">{title}</span><br /><span
|
||||
class="text-sm">{pubDate}</span
|
||||
></a
|
||||
>
|
||||
<div class="">
|
||||
<Img
|
||||
src={image.src || DEFAULT_IMAGE_URL}
|
||||
alt={image.alt}
|
||||
sizes={`
|
||||
(min-width: 1024px) 33vw,
|
||||
(min-width: 640px) 50vw,
|
||||
100vw
|
||||
`}
|
||||
attributes={{
|
||||
img: {
|
||||
class: "w-full p-2 rounded-2xl relative object-contain lg:mt-2",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</h2>
|
||||
</dt>
|
||||
<dd>
|
||||
<p class="relative z-10 line-clamp-2">
|
||||
{description}
|
||||
</p>
|
||||
</dd>
|
||||
</div>
|
||||
@ -1,29 +0,0 @@
|
||||
---
|
||||
const { title, url, description, pubDate, author, image } = Astro.props;
|
||||
import { translate } from "@/base/i18n.js";
|
||||
import { I18N_SOURCE_LANGUAGE } from "config/config.js";
|
||||
const locale = Astro.currentLocale;
|
||||
const title_i18n = await translate(title, I18N_SOURCE_LANGUAGE, locale);
|
||||
const description_i18n = await translate(description, I18N_SOURCE_LANGUAGE, locale);
|
||||
---
|
||||
|
||||
<article
|
||||
class="flex flex-col group items-start justify-between p-4 bg-white rounded-xl overflow-hidden relative">
|
||||
<h3
|
||||
class="text-sm text-neutral-600 uppercase font-mono tracking-tight group-hover:text-orange-600">
|
||||
<a
|
||||
href={url}
|
||||
title={title}
|
||||
aria-label={title}>
|
||||
<span class="absolute inset-0"></span>
|
||||
{title_i18n}
|
||||
</a>
|
||||
</h3>
|
||||
<p class="text-neutral-500 font-mono text-xs uppercase mt-2">
|
||||
{author} ·
|
||||
<time datetime={pubDate}>{pubDate}</time>
|
||||
</p>
|
||||
<p class="text-sm mt-12 text-balance text-neutral-500 line-clamp-2">
|
||||
{description_i18n}
|
||||
</p>
|
||||
</article>
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
import Translate from "@/components/polymech/i18n.astro"
|
||||
import { Img } from "imagetools/components"
|
||||
import Translate from "@polymech/astro-base/components/i18n.astro";
|
||||
import { Img } from "imagetools/components";
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
@ -12,18 +12,20 @@ interface Props {
|
||||
}
|
||||
|
||||
const {
|
||||
title = "Directory" ,
|
||||
title = "Directory",
|
||||
description = "",
|
||||
buttonText = "Directory",
|
||||
buttonLink = "/howtos",
|
||||
imageSrc = "/images/home/world.png",
|
||||
imageAlt = ""
|
||||
imageAlt = "",
|
||||
} = Astro.props;
|
||||
---
|
||||
|
||||
<section>
|
||||
<div class="py-2">
|
||||
<div class="flex flex-col md:flex-row gap-6 p-4 bg-white rounded-xl overflow-hidden relative">
|
||||
|
||||
<div
|
||||
class="flex flex-col md:flex-row gap-6 p-4 bg-white rounded-xl overflow-hidden relative"
|
||||
>
|
||||
<!-- Image takes 50% -->
|
||||
<div class="w-full md:w-1/2">
|
||||
<Img
|
||||
@ -31,8 +33,9 @@ const {
|
||||
alt={imageAlt}
|
||||
attributes={{
|
||||
img: {
|
||||
class: "w-full max-w-100 rounded-lg hover:ring-2 hover:ring-blue-500 aspect-square object-contain"
|
||||
}
|
||||
class:
|
||||
"w-full max-w-100 rounded-lg hover:ring-2 hover:ring-blue-500 aspect-square object-contain",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@ -52,30 +55,47 @@ const {
|
||||
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"><Translate>{buttonText}</Translate></span>
|
||||
<span class="relative uppercase text-xs text-white"
|
||||
><Translate>{buttonText}</Translate></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" />
|
||||
<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" />
|
||||
<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>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
import Translate from "@/components/polymech/i18n.astro"
|
||||
import { Img } from "imagetools/components"
|
||||
import Translate from "@polymech/astro-base/components/i18n.astro";
|
||||
import { Img } from "imagetools/components";
|
||||
interface Props {
|
||||
title: string;
|
||||
description: string;
|
||||
@ -16,13 +16,15 @@ const {
|
||||
buttonText = "Knowledge Base",
|
||||
buttonLink = "/howtos",
|
||||
imageSrc = "/images/home/icon-knowledgebase.png",
|
||||
imageAlt = ""
|
||||
imageAlt = "",
|
||||
} = Astro.props;
|
||||
---
|
||||
|
||||
<section>
|
||||
<div class="py-2">
|
||||
<div class="flex flex-col md:flex-row gap-6 p-4 bg-white rounded-xl overflow-hidden relative">
|
||||
|
||||
<div
|
||||
class="flex flex-col md:flex-row gap-6 p-4 bg-white rounded-xl overflow-hidden relative"
|
||||
>
|
||||
<!-- Image takes 50% -->
|
||||
<div class="w-full md:w-1/2">
|
||||
<Img
|
||||
@ -30,8 +32,9 @@ const {
|
||||
alt={imageAlt}
|
||||
attributes={{
|
||||
img: {
|
||||
class: "w-full max-w-100 rounded-lg hover:ring-2 hover:ring-blue-500 aspect-square object-contain"
|
||||
}
|
||||
class:
|
||||
"w-full max-w-100 rounded-lg hover:ring-2 hover:ring-blue-500 aspect-square object-contain",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@ -51,30 +54,47 @@ const {
|
||||
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"><Translate>{buttonText}</Translate></span>
|
||||
<span class="relative uppercase text-xs text-white"
|
||||
><Translate>{buttonText}</Translate></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" />
|
||||
<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" />
|
||||
<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>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
import Translate from "@/components/polymech/i18n.astro"
|
||||
import { Img } from "imagetools/components"
|
||||
import Translate from "@polymech/astro-base/components/i18n.astro";
|
||||
import { Img } from "imagetools/components";
|
||||
interface Props {
|
||||
title: string;
|
||||
description: string;
|
||||
@ -16,13 +16,15 @@ const {
|
||||
buttonText = "Shop",
|
||||
buttonLink = "/en/shop",
|
||||
imageSrc = "/images/home/shop.png",
|
||||
imageAlt = ""
|
||||
imageAlt = "",
|
||||
} = Astro.props;
|
||||
---
|
||||
|
||||
<section>
|
||||
<div class="py-2">
|
||||
<div class="flex flex-col md:flex-row gap-6 p-4 bg-white rounded-xl overflow-hidden relative">
|
||||
|
||||
<div
|
||||
class="flex flex-col md:flex-row gap-6 p-4 bg-white rounded-xl overflow-hidden relative"
|
||||
>
|
||||
<!-- Image takes 50% -->
|
||||
<div class="w-full md:w-1/2">
|
||||
<Img
|
||||
@ -30,8 +32,9 @@ const {
|
||||
alt={imageAlt}
|
||||
attributes={{
|
||||
img: {
|
||||
class: "w-full max-w-100 rounded-lg hover:ring-2 hover:ring-blue-500 aspect-square object-contain"
|
||||
}
|
||||
class:
|
||||
"w-full max-w-100 rounded-lg hover:ring-2 hover:ring-blue-500 aspect-square object-contain",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@ -51,30 +54,47 @@ const {
|
||||
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"><Translate>{buttonText}</Translate></span>
|
||||
<span class="relative uppercase text-xs text-white"
|
||||
><Translate>{buttonText}</Translate></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" />
|
||||
<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" />
|
||||
<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>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@ -23,15 +23,10 @@ import { applyFilters, shortenUrl } from "@/base/filters.js";
|
||||
import {
|
||||
HOWTO_FILES_WEB,
|
||||
HOWTO_FILES_ABS,
|
||||
I18N_SOURCE_LANGUAGE,
|
||||
HOWTO_COMPLETE_RESOURCES,
|
||||
HOWTO_COMPLETE_SKILLS,
|
||||
HOWTO_ADD_HARDWARE,
|
||||
HOWTO_LOCAL_RESOURCES,
|
||||
HOWTO_ADD_RESOURCES,
|
||||
HOWTO_ADD_REFERENCES,
|
||||
HOWTO_EDIT_URL,
|
||||
} from "config/config.js";
|
||||
I18N_SOURCE_LANGUAGE,
|
||||
} from "../../app/config.js";
|
||||
|
||||
import { filter } from "@/base/kbot.js";
|
||||
import { getCollection } from "astro:content";
|
||||
|
||||
@ -12,7 +12,7 @@ import pMap from "p-map";
|
||||
import { sync as exists } from "@polymech/fs/exists";
|
||||
import { sync as read } from "@polymech/fs/read";
|
||||
import { createHTMLComponent, createMarkdownComponent } from "@/base/index.js";
|
||||
import { translate } from "@/base/i18n.js";
|
||||
import { translate } from "@polymech/astro-base/base/i18n.js";
|
||||
import { applyFilters, shortenUrl } from "@/base/filters.js";
|
||||
// import { extract, extract_learned_skills, references } from "@/base/kbot.js";
|
||||
import {
|
||||
@ -27,6 +27,7 @@ import {
|
||||
HOWTO_ADD_REFERENCES,
|
||||
HOWTO_EDIT_URL,
|
||||
} from "config/config.js";
|
||||
|
||||
import { filter } from "@/base/kbot.js";
|
||||
|
||||
interface Props {
|
||||
@ -106,13 +107,12 @@ const EditLink = () => {
|
||||
)
|
||||
}
|
||||
*/
|
||||
|
||||
---
|
||||
|
||||
<BaseLayout class="markdown-content bg-gray-100" frontmatter={howto}>
|
||||
<Wrapper>
|
||||
<article class="bg-white shadow-lg rounded-lg overflow-hidden">
|
||||
<header class="p-4 ">
|
||||
<header class="p-4">
|
||||
<h1 class="text-4xl font-bold text-gray-800 mb-4">
|
||||
<Translate>{howto.title}</Translate>
|
||||
</h1>
|
||||
@ -146,7 +146,9 @@ const EditLink = () => {
|
||||
<strong><Translate>Creator:</Translate></strong>{howto._createdBy}
|
||||
</li>
|
||||
<li>
|
||||
<strong><Translate>Country:</Translate></strong>{authorGeo.countryName }
|
||||
<strong><Translate>Country:</Translate></strong>{
|
||||
authorGeo.countryName
|
||||
}
|
||||
</li>
|
||||
<li>
|
||||
<strong><Translate>Email:</Translate></strong>
|
||||
@ -216,7 +218,7 @@ const EditLink = () => {
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="border-gray-300 p-0 lg:p-6 mt-8">
|
||||
<section class="border-gray-300 p-0 lg:p-6 mt-8">
|
||||
<ol class="space-y-10">
|
||||
{
|
||||
stepsWithFilteredMarkdown.map((step, idx) => (
|
||||
@ -247,8 +249,16 @@ const EditLink = () => {
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<section class="bg-white shadow-lg rounded-lg border-gray-300 p-4 lg:p-6 mt-8 markdown-content"><Resources /></section>
|
||||
<section class="bg-white shadow-lg rounded-lg border-gray-300 p-4 lg:p-6 mt-8 markdown-content"><References /></section>
|
||||
<section
|
||||
class="bg-white shadow-lg rounded-lg border-gray-300 p-4 lg:p-6 mt-8 markdown-content"
|
||||
>
|
||||
<Resources />
|
||||
</section>
|
||||
<section
|
||||
class="bg-white shadow-lg rounded-lg border-gray-300 p-4 lg:p-6 mt-8 markdown-content"
|
||||
>
|
||||
<References />
|
||||
</section>
|
||||
<footer class="p-8 text-sm border-t bg-white text-gray-600">
|
||||
<div class="flex justify-between">
|
||||
<span
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
import { Img } from "imagetools/components";
|
||||
import { translate } from "@polymech/astro-base/base/i18n.js";
|
||||
import { decode } from "html-entities";
|
||||
import { I18N_SOURCE_LANGUAGE } from "config/config.js";
|
||||
import Translate from "@/components/polymech/i18n.astro";
|
||||
const I18N_SOURCE_LANGUAGE = 'en'
|
||||
import Translate from "@polymech/astro-base/components/i18n.astro";
|
||||
import type { IHowto } from "@/model/howto/howto.js";
|
||||
|
||||
export interface Props {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
import { IMAGE_SETTINGS } from "config/config.js";
|
||||
import Translate from "@/components/polymech/i18n.astro";
|
||||
import Translate from "@polymech/astro-base/components/i18n.astro";
|
||||
import { Img } from "imagetools/components";
|
||||
import { asset_local_rel, IHowto } from "@/model/howto/howto.js";
|
||||
const { title, url, model, selected = false } = Astro.props;
|
||||
@ -10,13 +10,17 @@ const coverLocaleRel = await asset_local_rel(item, item.cover_image);
|
||||
|
||||
const { images, gallerySettings = {}, lightboxSettings = {} } = Astro.props;
|
||||
const mergedGallerySettings = {
|
||||
SIZES_REGULAR: gallerySettings.SIZES_REGULAR || IMAGE_SETTINGS.GALLERY.SIZES_REGULAR,
|
||||
SIZES_THUMB: gallerySettings.SIZES_THUMB || IMAGE_SETTINGS.GALLERY.SIZES_THUMB,
|
||||
SIZES_REGULAR:
|
||||
gallerySettings.SIZES_REGULAR || IMAGE_SETTINGS.GALLERY.SIZES_REGULAR,
|
||||
SIZES_THUMB:
|
||||
gallerySettings.SIZES_THUMB || IMAGE_SETTINGS.GALLERY.SIZES_THUMB,
|
||||
SHOW_TITLE: gallerySettings.SHOW_TITLE ?? IMAGE_SETTINGS.GALLERY.SHOW_TITLE,
|
||||
SHOW_DESCRIPTION: gallerySettings.SHOW_DESCRIPTION ?? IMAGE_SETTINGS.GALLERY.SHOW_DESCRIPTION,
|
||||
}
|
||||
SHOW_DESCRIPTION:
|
||||
gallerySettings.SHOW_DESCRIPTION ?? IMAGE_SETTINGS.GALLERY.SHOW_DESCRIPTION,
|
||||
};
|
||||
---
|
||||
<div class={classes}>
|
||||
|
||||
<div class={classes}>
|
||||
<div
|
||||
class="p-4 overflow-hidden group-hover:opacity-75 duration-300 transition-all"
|
||||
>
|
||||
@ -30,13 +34,11 @@ const mergedGallerySettings = {
|
||||
placeholder="blurred"
|
||||
sizes={mergedGallerySettings.SIZES_REGULAR}
|
||||
breakpoints={{ count: 2, minWidth: 180, maxWidth: 450 }}
|
||||
attributes={
|
||||
{
|
||||
img: {
|
||||
class: "w-32 h-32 rounded hover:ring-2 aspect-square thumbnail-img"
|
||||
}
|
||||
}
|
||||
}
|
||||
attributes={{
|
||||
img: {
|
||||
class: "w-32 h-32 rounded hover:ring-2 aspect-square thumbnail-img",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@ -1,22 +0,0 @@
|
||||
---
|
||||
import { I18N_SOURCE_LANGUAGE } from "config/config.js"
|
||||
import { translate, IOptions } from '@/base/i18n.js'
|
||||
|
||||
export interface Props extends IOptions {
|
||||
language?: string,
|
||||
clazz?:string
|
||||
}
|
||||
|
||||
const {
|
||||
language = Astro.currentLocale,
|
||||
clazz = '',
|
||||
...rest
|
||||
} = Astro.props
|
||||
|
||||
const content = await Astro.slots.render('default')
|
||||
const translatedText = await translate(content, I18N_SOURCE_LANGUAGE, language, rest)
|
||||
|
||||
---
|
||||
<p data-widget="polymech.i18n" class={clazz}>
|
||||
{translatedText}
|
||||
</p>
|
||||
@ -1,40 +0,0 @@
|
||||
---
|
||||
import * as path from "path"
|
||||
import { sync as fileExists } from "@polymech/fs/exists"
|
||||
import { specs } from "@/base/specs.js"
|
||||
import { render, logger } from "@/base/index.js"
|
||||
import { translateSheets } from "@/base/i18n.js"
|
||||
import { I18N_SOURCE_LANGUAGE, LANGUAGES_PROD as LANGUAGES, PRODUCT_SPECS } from "config/config.js"
|
||||
|
||||
import DefaultComponent from "../Default.astro"
|
||||
const { frontmatter: data } = Astro.props
|
||||
const locale = Astro.currentLocale || I18N_SOURCE_LANGUAGE
|
||||
|
||||
const specs_table = async (relPath) =>
|
||||
{
|
||||
let specsPath = path.join(PRODUCT_SPECS(relPath));
|
||||
if (!fileExists(specsPath)) {
|
||||
logger.debug(`No specs found for ${specsPath}`);
|
||||
return null;
|
||||
}
|
||||
if (locale !== I18N_SOURCE_LANGUAGE && LANGUAGES.includes(locale)) {
|
||||
const i18n = await translateSheets(relPath, locale);
|
||||
if (!i18n) {
|
||||
logger.debug(`No i18n found for ${relPath} : ${locale}`);
|
||||
} else {
|
||||
specsPath = i18n
|
||||
}
|
||||
}
|
||||
return specs(specsPath)
|
||||
}
|
||||
const tableHTML = await specs_table(data.rel)
|
||||
let SpecsComponent
|
||||
if (tableHTML) {
|
||||
SpecsComponent = await render(tableHTML)
|
||||
} else {
|
||||
SpecsComponent = DefaultComponent
|
||||
}
|
||||
---
|
||||
<div class="bg-white rounded-xl specs specs-table">
|
||||
<SpecsComponent />
|
||||
</div>
|
||||
@ -1,34 +0,0 @@
|
||||
---
|
||||
import { translate } from "@/base/i18n.js";
|
||||
import { I18N_SOURCE_LANGUAGE } from "config/config.js";
|
||||
import { slugify } from "@/base/strings.js"
|
||||
|
||||
export interface Props {
|
||||
title: string;
|
||||
}
|
||||
const { title = "title" } = Astro.props;
|
||||
|
||||
const slug = `${slugify(title)}-tab-button`;
|
||||
const id = `#${slug}-tab`;
|
||||
const view = `#${slugify(title)}-view`;
|
||||
const locale = Astro.currentLocale;
|
||||
const title_i18n = await translate(title, I18N_SOURCE_LANGUAGE, locale);
|
||||
---
|
||||
|
||||
<li>
|
||||
<a
|
||||
data-tabs-target={view}
|
||||
href={id}
|
||||
class="inline-block p-4 border-b-2
|
||||
border-transparent rounded-t-lg
|
||||
text-xs
|
||||
hover:text-gray-600
|
||||
hover:border-gray-300
|
||||
dark:hover:text-gray-300"
|
||||
id={slug}
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-controls="settings"
|
||||
aria-selected="false">{title_i18n}</a
|
||||
>
|
||||
</li>
|
||||
@ -2,7 +2,7 @@
|
||||
"site": {
|
||||
"title": "Creava",
|
||||
"base_url": "https://creava.org/",
|
||||
"description" : "",
|
||||
"description": "",
|
||||
"base_path": "/",
|
||||
"trailing_slash": false,
|
||||
"favicon": "/images/favicon.png",
|
||||
@ -26,15 +26,13 @@
|
||||
{
|
||||
"href": "/infopages/contact",
|
||||
"text": "Contact"
|
||||
} ,
|
||||
},
|
||||
{
|
||||
"href": "/newsletter/newsletter_2024_09_en-hugo-release.html",
|
||||
"text": "Newsletter"
|
||||
}
|
||||
],
|
||||
"footer_right": [
|
||||
|
||||
],
|
||||
"footer_right": [],
|
||||
"settings": {
|
||||
"search": true,
|
||||
"account": true,
|
||||
@ -74,10 +72,10 @@
|
||||
"featured_products": "featured-products"
|
||||
}
|
||||
},
|
||||
"pages":{
|
||||
"home":{
|
||||
"pages": {
|
||||
"home": {
|
||||
"hero": "https://assets.osr-plastic.org/machines//assets/newsletter/common/products/extruders/overview-3.jpg",
|
||||
"blog":{
|
||||
"blog": {
|
||||
"store": "resources"
|
||||
}
|
||||
}
|
||||
@ -85,4 +83,4 @@
|
||||
"_tracking": {
|
||||
"googleAnalytics": "G-RW6Q6EG3J0"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,223 +1 @@
|
||||
import * as path from 'path'
|
||||
import { IMAGE_PRESET, E_BROADBAND_SPEED } from "./network.js"
|
||||
import { resolve, template } from '@polymech/commons'
|
||||
import { sync as read } from '@polymech/fs/read'
|
||||
import { sanitizeUri } from 'micromark-util-sanitize-uri'
|
||||
|
||||
// LLM
|
||||
export const LLM_CACHE = true
|
||||
export const LLM_CACHE_DIR = './.cache/kbot'
|
||||
|
||||
export const OSR_ROOT = () => path.resolve(resolve("${OSR_ROOT}"))
|
||||
|
||||
export const LOGGING_NAMESPACE = 'polymech-site'
|
||||
export const TRANSLATE_CONTENT = true
|
||||
export const LANGUAGES = ['en', 'es']
|
||||
export const LANGUAGES_SITE = ['en', 'ar', 'de', 'ja', 'es', 'zh', 'fr']
|
||||
export const LANGUAGES_PROD = ['en', 'es', 'fr', 'it', 'de']
|
||||
export const isRTL = (lang) => lang === 'ar'
|
||||
|
||||
// i18n constants
|
||||
export const I18N_STORE = (root, lang) => `${root}/i18n-store/store-${lang}.json`
|
||||
export const I18N_SOURCE_LANGUAGE = 'en'
|
||||
export const I18N_CACHE = true
|
||||
export const I18N_ASSET_PATH = "${SRC_DIR}/${SRC_NAME}-${DST_LANG}${SRC_EXT}"
|
||||
|
||||
// Library - Howtos
|
||||
export const HOWTO_GLOB = '**/config.json'
|
||||
export const FILES_WEB = 'https://files.polymech.info/files/machines/howtos/'
|
||||
export const HOWTO_EDIT_ROOT = 'https://git.polymech.io/osr-plastic/osr-machines/src/branch/master/howtos'
|
||||
export const HOWTO_FILTER_LLM = false
|
||||
export const HOWTO_LLM_KEYWORDS = false
|
||||
export const HOWTO_ANNOTATIONS = false
|
||||
export const HOWTO_ANNOTATIONS_CACHE = false
|
||||
export const HOWTO_COMPLETE_RESOURCES = false
|
||||
export const HOWTO_ADD_HARDWARE = false
|
||||
export const HOWTO_ADD_RESOURCES = false
|
||||
export const HOWTO_ADD_REFERENCES = false
|
||||
export const HOWTO_COMPLETE_SKILLS = false
|
||||
export const HOWTO_LOCAL_RESOURCES = false
|
||||
export const HOWTO_SEO_LLM = false
|
||||
export const HOWTO_MAX_ITEMS = 1000
|
||||
|
||||
export const HOWTO_MIGRATION = () => path.resolve(resolve("./data/last.json"))
|
||||
export const HOWTO_ROOT_INTERN = () => path.resolve(resolve("./public/resources/howtos"))
|
||||
export const HOWTO_ROOT = () => path.resolve(resolve("${OSR_ROOT}/osr-machines/howtos"))
|
||||
export const HOWTO_FILES_ABS = (id) => `${HOWTO_ROOT()}/${id}`
|
||||
export const HOWTO_FILES_WEB = (id: string) => `${FILES_WEB}/${id}`
|
||||
export const HOWTO_EDIT_URL = (id: string, lang: string) => `${HOWTO_EDIT_ROOT}/${id}`
|
||||
|
||||
// Library - Directory
|
||||
export const DIRECTORY_GLOB = '**/config.json'
|
||||
export const DIRECTORY_FILES_BASE = 'https://files.polymech.info/files/directory/'
|
||||
export const DIRECTORY_EDIT_ROOT = 'https://git.polymech.info/polymech/machines/src/branch/master/directory'
|
||||
export const DIRECTORY_FILTER_LLM = true
|
||||
export const DIRECTORY_ANNOTATIONS = false
|
||||
export const DIRECTORY_ANNOTATIONS_CACHE = false
|
||||
export const DIRECTORY_COMPLETE_RESOURCES = true
|
||||
export const DIRECTORY_ADD_HARDWARE = false
|
||||
export const DIRECTORY_ADD_RESOURCES = true
|
||||
export const DIRECTORY_ADD_REFERENCES = true
|
||||
export const DIRECTORY_COMPLETE_SKILLS = false
|
||||
export const DIRECTORY_LOCAL_RESOURCES = false
|
||||
export const DIRECTORY_SEO_LLM = true
|
||||
export const DIRECTORY_MAX_ITEMS = 0
|
||||
|
||||
export const DIRECTORY_MIGRATION = () => path.resolve(resolve("./data/last.json"))
|
||||
export const DIRECTORY_ROOT_INTERN = () => path.resolve(resolve("./public/resources/directory"))
|
||||
export const DIRECTORY_ROOT = () => path.resolve(resolve("${OSR_ROOT}/osr-machines/directory"))
|
||||
export const DIRECTORY_FILES_ABS = (id) => `${DIRECTORY_ROOT()}/${id}`
|
||||
export const DIRECTORY_FILES_WEB = (id: string) => `${DIRECTORY_FILES_BASE}/${id}`
|
||||
export const DIRECTORY_EDIT_URL = (id: string, lang: string) => `${DIRECTORY_EDIT_ROOT}/${id}`
|
||||
|
||||
// Library Products
|
||||
export const PRODUCT_ROOT = () => path.resolve(resolve("${OSR_ROOT}/products"))
|
||||
export const PRODUCT_BRANCHES = read('./library.json', 'json')
|
||||
export const PRODUCT_GLOB = '**/config.json'
|
||||
export const ENABLED_PRODUCTS = "${OSR_ROOT}/products/config/machines.json"
|
||||
export const PRODUCT_SPECS = (rel) => `${PRODUCT_ROOT()}/${rel}/specs.xlsx`
|
||||
|
||||
// Library Components
|
||||
export const COMPONENT_ROOT = () => path.resolve(resolve("${OSR_ROOT}/osr-machines"))
|
||||
export const COMPONENT_GLOB = '**/config.json'
|
||||
export const ENABLED_COMPONENTS = "${OSR_ROOT}/components/config/machines.json"
|
||||
export const COMPONENT_SPECS = (rel) => `${COMPONENT_ROOT()}/${rel}/specs.xlsx`
|
||||
|
||||
// Product compiler
|
||||
export const PRODUCT_CONFIG = (product) =>
|
||||
path.resolve(resolve(`${PRODUCT_ROOT()}/${product}/config.json`, false,
|
||||
{
|
||||
product
|
||||
}))
|
||||
export const PRODUCT_DIR = (product) => path.resolve(resolve(`${PRODUCT_ROOT()}/${product}`))
|
||||
export const PRODUCT_HUGO_TEMPLATE = './osr/hugo/root.html'
|
||||
export const PRODUCTS_TARGET_SRC = './src/content/en/retail'
|
||||
export const PRODUCTS_TARGET = (lang) => `./content/${lang}/products`
|
||||
|
||||
// Product assets
|
||||
export const ASSETS_LOCAL = false
|
||||
export const ASSETS_GLOB = '*.+(JPG|jpg|jpeg|png|PNG|gif)'
|
||||
|
||||
// OSRL - Language
|
||||
export const IS_DEV = true
|
||||
export const OSRL_ENV = 'astro-release'
|
||||
export const OSRL_ENV_DEV = 'astro-debug'
|
||||
export const OSRL_ENVIRONMENT = IS_DEV ? OSRL_ENV_DEV : OSRL_ENV
|
||||
export const OSRL_MODULE_NAME = 'polymech.io'
|
||||
export const OSRL_PRODUCT_PROFILE = './src/config/profile.json'
|
||||
export const OSRL_LANG_FLAVOR = 'osr'
|
||||
|
||||
// Tasks
|
||||
export const TASK_CONFIG_LOG_DIRECTORY = './config/'
|
||||
|
||||
// Task: compile:content
|
||||
export const TASK_COMPILE_CONTENT = true
|
||||
export const TASK_COMPILE_CONTENT_CACHE = false
|
||||
|
||||
// Task - Logging
|
||||
export const TASK_LOG_DIRECTORY = './logs/'
|
||||
|
||||
// Task - Retail Config
|
||||
export const REGISTER_PRODUCT_TASKS = true
|
||||
export const LIBARY_BRANCH = 'site-prod'
|
||||
export const PROJECTS_BRANCH = 'projects2'
|
||||
export const RETAIL_COMPILE_CACHE = false
|
||||
export const RETAIL_MEDIA_CACHE = true
|
||||
export const RETAIL_LOG_LEVEL_I18N_PRODUCT_ASSETS = 'info'
|
||||
|
||||
export const ConvertProductMedia = true
|
||||
export const TranslateProductAssets = false
|
||||
export const PopulateProductDefaults = true
|
||||
|
||||
// CAD
|
||||
export const CAD_MAIN_MATCH = (product) => `${product}/cad*/*Global*.+(SLDASM)`
|
||||
export const CAD_CAM_MAIN_MATCH = (product) => `${product}/cad*/*-CNC*.+(SLDASM)`
|
||||
|
||||
export const CAD_CACHE = true
|
||||
export const CAD_EXPORT_CONFIGURATIONS = false
|
||||
export const CAD_EXPORT_SUB_COMPONENTS = true
|
||||
export const CAD_MODEL_FILE_PATH = (SOURCE, CONFIGURATION = '') => SOURCE.replace('.json', `${CONFIGURATION ? '-' + CONFIGURATION : ''}.tree.json`)
|
||||
export const CAD_DEFAULT_CONFIGURATION = 'Default'
|
||||
export const CAD_RENDERER = 'solidworks'
|
||||
export const CAD_RENDERER_VIEW = 'Render'
|
||||
export const CAD_RENDERER_QUALITY = 1
|
||||
export const CAD_EXTENSIONS = ['.STEP', '.html']
|
||||
export const CAD_MODEL_EXT = '.tree.json'
|
||||
|
||||
export const CAD_URL = (file: string, variables: Record<string, string>) =>
|
||||
sanitizeUri(template("${OSR_MACHINES_ASSETS_URL}/${file}", { file, ...variables }))
|
||||
|
||||
export const ASSET_URL = (file: string, variables: Record<string, string>) =>
|
||||
sanitizeUri(template("${OSR_MACHINES_ASSETS_URL}/products/${product_rel_min}/${file}", { file, ...variables }))
|
||||
|
||||
export const ITEM_ASSET_URL = (variables: Record<string, string>) =>
|
||||
template("${OSR_MACHINES_ASSETS_URL}/${ITEM_REL}/${assetPath}/${filePath}", variables)
|
||||
|
||||
|
||||
//back compat - osr-cad
|
||||
export const parseBoolean = (value: string): boolean => { return value === '1' || value.toLowerCase() === 'true'; }
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// Rendering - Store
|
||||
|
||||
export const SHOW_DESCRIPTION = false
|
||||
export const SHOW_LICENSE = true
|
||||
export const SHOW_RENDERINGS = true
|
||||
export const SHOW_TABS = false
|
||||
export const SHOW_GALLERY = true
|
||||
export const SHOW_FILES = true
|
||||
export const SHOW_SPECS = true
|
||||
export const SHOW_CHECKOUT = true
|
||||
export const SHOW_CONTACT = true
|
||||
export const SHOW_3D_PREVIEW = true
|
||||
export const SHOW_RESOURCES = true
|
||||
export const SHOW_DEBUG = false
|
||||
export const SHOW_SAMPLES = true
|
||||
export const SHOW_README = false
|
||||
export const SHOW_RELATED = true
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// Plugins
|
||||
|
||||
// RSS
|
||||
export const RSS_CONFIG =
|
||||
{
|
||||
title: 'Polymech RSS Feed',
|
||||
description: '',
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// Defaults
|
||||
export const DEFAULT_IMAGE_URL = 'https://picsum.photos/640/640'
|
||||
export const default_image = () => {
|
||||
return {
|
||||
alt: 'none',
|
||||
src: DEFAULT_IMAGE_URL
|
||||
}
|
||||
}
|
||||
export const DEFAULT_LICENSE = `CERN Open Source Hardware License`
|
||||
export const DEFAULT_CONTACT = `sales@plastic-hub.com`
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// Optimization
|
||||
export const O_IMAGE = IMAGE_PRESET[E_BROADBAND_SPEED.MEDIUM]
|
||||
export const IMAGE_SETTINGS =
|
||||
{
|
||||
GALLERY: {
|
||||
SHOW_TITLE: true,
|
||||
SHOW_DESCRIPTION: false,
|
||||
SIZES_THUMB: O_IMAGE.sizes_thumbs,
|
||||
SIZES_LARGE: O_IMAGE.sizes_large,
|
||||
SIZES_REGULAR: O_IMAGE.sizes_medium
|
||||
},
|
||||
LIGHTBOX: {
|
||||
SHOW_TITLE: true,
|
||||
SHOW_DESCRIPTION: true,
|
||||
SIZES_THUMB: O_IMAGE.sizes_thumbs,
|
||||
SIZES_LARGE: O_IMAGE.sizes_large,
|
||||
SIZES_REGULAR: O_IMAGE.sizes_medium
|
||||
}
|
||||
}
|
||||
export * from '../app/config.js'
|
||||
@ -1,21 +0,0 @@
|
||||
---
|
||||
import BaseLayout from "./BaseLayout.astro";
|
||||
import Wrapper from "@/components/containers/Wrapper.astro";
|
||||
import { I18N_SOURCE_LANGUAGE } from "config/config.js"
|
||||
import { translate } from '@/base/i18n.js'
|
||||
import { createHTMLComponent } from '@/base/index.js'
|
||||
const content = await Astro.slots.render('default')
|
||||
const translatedText = await translate(content, I18N_SOURCE_LANGUAGE, Astro.currentLocale)
|
||||
const Markup = await createHTMLComponent(translatedText)
|
||||
---
|
||||
<BaseLayout>
|
||||
<Wrapper>
|
||||
<section>
|
||||
<div class="grid sm:grid-cols-1 lg:grid-cols-1 xl:grid-cols-1 gap-2 text-neutral-500 markdown-content">
|
||||
<div class="py-2 p-4 bg-white rounded-xl">
|
||||
<Markup/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</Wrapper>
|
||||
</BaseLayout>
|
||||
@ -17,8 +17,11 @@ import Specs from "@polymech/astro-base/components/specs.astro";
|
||||
import TabButton from "@polymech/astro-base/components/tab-button.astro";
|
||||
import TabContent from "@polymech/astro-base/components/tab-content.astro";
|
||||
|
||||
import { AppConfig } from "@/app/config.schema.js";
|
||||
import { loadConfig } from "@polymech/astro-base/app/config-loader.js";
|
||||
const config = loadConfig();
|
||||
|
||||
import {
|
||||
I18N_SOURCE_LANGUAGE,
|
||||
SHOW_3D_PREVIEW,
|
||||
SHOW_FILES,
|
||||
SHOW_GALLERY,
|
||||
@ -53,9 +56,10 @@ const content = substitute(false, data.content || "", {
|
||||
...data,
|
||||
LANG: Astro.currentLocale,
|
||||
});
|
||||
|
||||
const translated_content = await translate(
|
||||
content,
|
||||
I18N_SOURCE_LANGUAGE,
|
||||
config.i18n.source_language,
|
||||
Astro.currentLocale,
|
||||
);
|
||||
|
||||
|
||||
@ -7,10 +7,10 @@ import config from "config/config.json";
|
||||
import { getCollection } from "astro:content";
|
||||
import StoreEntries from "@/components/store/StoreEntries.astro";
|
||||
import CtaOne from "@/components/cta/CtaOne.astro";
|
||||
import { group_by_path } from "@/model/component/component.js";
|
||||
import { group_by_path } from "@polymech/astro-base/model/component.js";
|
||||
|
||||
const view = "library";
|
||||
const items = await getCollection("store");
|
||||
const items = await getCollection("library");
|
||||
const locale = Astro.currentLocale;
|
||||
const store = `/${locale}/${view}/`;
|
||||
|
||||
|
||||
@ -2,11 +2,11 @@
|
||||
import { group_by_cat } from "@/model/howto/howto.js";
|
||||
import { getCollection } from "astro:content";
|
||||
import BaseLayout from "@/layouts/BaseLayout.astro";
|
||||
import Sidebar from "@polymech/astro-base/components/sidebar/Sidebar.astro"
|
||||
import MobileToggle from "@polymech/astro-base/components/sidebar/MobileToggle.astro"
|
||||
import { getSidebarConfig } from '@polymech/astro-base/config/sidebar';
|
||||
import Sidebar from "@polymech/astro-base/components/sidebar/Sidebar.astro";
|
||||
import MobileToggle from "@polymech/astro-base/components/sidebar/MobileToggle.astro";
|
||||
import { getSidebarConfig } from "@polymech/astro-base/config/sidebar";
|
||||
import HowtoCard from "@/components/howtos/HowtoCard.astro";
|
||||
import Translate from "@/components/polymech/i18n.astro";
|
||||
import Translate from "@polymech/astro-base/components/i18n.astro";
|
||||
import { LANGUAGES_PROD as LANGUAGES } from "config/config.js";
|
||||
import type { IHowto } from "@/model/howto/howto.js";
|
||||
|
||||
@ -23,32 +23,42 @@ const categories = Object.keys(groups).sort();
|
||||
const organizedCategories: any[] = [];
|
||||
|
||||
// Separate and organize categories
|
||||
const uncategorizedItems = groups['Uncategorized'] || groups['uncategorized'] || [];
|
||||
const categorizedItems = categories.filter(cat =>
|
||||
cat.toLowerCase() !== 'uncategorized' && cat !== 'Uncategorized'
|
||||
).sort();
|
||||
const uncategorizedItems =
|
||||
groups["Uncategorized"] || groups["uncategorized"] || [];
|
||||
const categorizedItems = categories
|
||||
.filter(
|
||||
(cat) => cat.toLowerCase() !== "uncategorized" && cat !== "Uncategorized",
|
||||
)
|
||||
.sort();
|
||||
|
||||
// Add categorized items with better organization
|
||||
if (categorizedItems.length > 0) {
|
||||
organizedCategories.push({
|
||||
label: 'Browse by Category',
|
||||
label: "Browse by Category",
|
||||
collapsed: false,
|
||||
items: categorizedItems.map(category => ({
|
||||
items: categorizedItems.map((category) => ({
|
||||
label: `${category} (${groups[category].length})`,
|
||||
collapsed: true,
|
||||
isSubGroup: true, // This makes it a collapsible subgroup
|
||||
items: groups[category].slice(0, 8).map((howto: IHowto) => ({
|
||||
label: howto.title,
|
||||
href: `/${locale}/howtos/${howto.slug}`,
|
||||
isCurrent: false
|
||||
})).concat(
|
||||
groups[category].length > 8 ? [{
|
||||
label: `View all ${groups[category].length} guides...`,
|
||||
href: `/${locale}/howtos/category/${category.toLowerCase().replace(/\s+/g, '-')}`,
|
||||
isCurrent: false
|
||||
}] : []
|
||||
)
|
||||
}))
|
||||
items: groups[category]
|
||||
.slice(0, 8)
|
||||
.map((howto: IHowto) => ({
|
||||
label: howto.title,
|
||||
href: `/${locale}/howtos/${howto.slug}`,
|
||||
isCurrent: false,
|
||||
}))
|
||||
.concat(
|
||||
groups[category].length > 8
|
||||
? [
|
||||
{
|
||||
label: `View all ${groups[category].length} guides...`,
|
||||
href: `/${locale}/howtos/category/${category.toLowerCase().replace(/\s+/g, "-")}`,
|
||||
isCurrent: false,
|
||||
},
|
||||
]
|
||||
: [],
|
||||
),
|
||||
})),
|
||||
});
|
||||
}
|
||||
|
||||
@ -57,65 +67,73 @@ if (uncategorizedItems.length > 0) {
|
||||
organizedCategories.push({
|
||||
label: `Uncategorized (${uncategorizedItems.length})`,
|
||||
collapsed: true,
|
||||
items: uncategorizedItems.slice(0, 10).map((uncatHowto: IHowto) => ({
|
||||
label: uncatHowto.title,
|
||||
href: `/${locale}/howtos/${uncatHowto.slug}`,
|
||||
isCurrent: false
|
||||
})).concat(
|
||||
uncategorizedItems.length > 10 ? [{
|
||||
label: `View all ${uncategorizedItems.length} guides...`,
|
||||
href: `/${locale}/howtos/uncategorized`,
|
||||
isCurrent: false
|
||||
}] : []
|
||||
)
|
||||
items: uncategorizedItems
|
||||
.slice(0, 10)
|
||||
.map((uncatHowto: IHowto) => ({
|
||||
label: uncatHowto.title,
|
||||
href: `/${locale}/howtos/${uncatHowto.slug}`,
|
||||
isCurrent: false,
|
||||
}))
|
||||
.concat(
|
||||
uncategorizedItems.length > 10
|
||||
? [
|
||||
{
|
||||
label: `View all ${uncategorizedItems.length} guides...`,
|
||||
href: `/${locale}/howtos/uncategorized`,
|
||||
isCurrent: false,
|
||||
},
|
||||
]
|
||||
: [],
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
// Add quick navigation
|
||||
organizedCategories.unshift({
|
||||
label: 'Quick Navigation',
|
||||
label: "Quick Navigation",
|
||||
collapsed: false,
|
||||
items: [
|
||||
{
|
||||
label: 'All Guides',
|
||||
label: "All Guides",
|
||||
href: `/${locale}/howtos`,
|
||||
isCurrent: true // This is the current page
|
||||
isCurrent: true, // This is the current page
|
||||
},
|
||||
{
|
||||
label: 'Recently Added',
|
||||
label: "Recently Added",
|
||||
href: `/${locale}/howtos/recent`,
|
||||
isCurrent: false
|
||||
}
|
||||
]
|
||||
isCurrent: false,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const pageNavigation = organizedCategories;
|
||||
|
||||
|
||||
export async function getStaticPaths() {
|
||||
return LANGUAGES.map((lang) => ({
|
||||
params: { locale: lang },
|
||||
}));
|
||||
return LANGUAGES.map((lang) => ({
|
||||
params: { locale: lang },
|
||||
}));
|
||||
}
|
||||
---
|
||||
|
||||
<BaseLayout frontmatter={{
|
||||
title: "How-To Guides",
|
||||
description: "Browse our collection of step-by-step how-to guides"
|
||||
}}>
|
||||
<BaseLayout
|
||||
frontmatter={{
|
||||
title: "How-To Guides",
|
||||
description: "Browse our collection of step-by-step how-to guides",
|
||||
}}
|
||||
>
|
||||
<div class="layout-with-sidebar">
|
||||
<!-- Mobile Toggle -->
|
||||
<MobileToggle />
|
||||
|
||||
|
||||
<!-- Sidebar -->
|
||||
<div class="sidebar-wrapper">
|
||||
<Sidebar
|
||||
config={sidebarConfig}
|
||||
currentUrl={Astro.url}
|
||||
<Sidebar
|
||||
config={sidebarConfig}
|
||||
currentUrl={Astro.url}
|
||||
pageNavigation={pageNavigation}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="main-content-with-sidebar">
|
||||
<div class="container mx-auto px-4 py-4 md:px-6 md:py-6">
|
||||
@ -126,100 +144,143 @@ export async function getStaticPaths() {
|
||||
<Translate>How-To Guides</Translate>
|
||||
</h1>
|
||||
<p class="text-lg text-gray-600 mb-6">
|
||||
<Translate>{all.length} guide{all.length !== 1 ? 's' : ''} available across {categories.length} categories</Translate>
|
||||
<Translate
|
||||
>{all.length} guide{all.length !== 1 ? "s" : ""} available across
|
||||
{categories.length} categories</Translate
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- All Howtos Grid -->
|
||||
<div class="mb-12">
|
||||
<h2 class="text-2xl font-semibold text-gray-900 mb-6"><Translate>All Guides</Translate></h2>
|
||||
<div class="grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3 gap-6">
|
||||
{items.map((item) => {
|
||||
const correspondingItem = all.find(storeItem => storeItem.data.item.slug === item.slug);
|
||||
return correspondingItem ? (
|
||||
<HowtoCard
|
||||
url={`/${locale}/howtos/${item.slug}`}
|
||||
title={item.title}
|
||||
description={item.description}
|
||||
alt={item.title}
|
||||
category={item.category?.label}
|
||||
difficulty_level={item.difficulty_level}
|
||||
time={item.time}
|
||||
total_views={item.total_views}
|
||||
total_downloads={item.total_downloads}
|
||||
author={item._createdBy}
|
||||
tags={item.tags?.map(tag => typeof tag === 'string' ? tag : tag.label) || []}
|
||||
locale={locale}
|
||||
howto={item}
|
||||
/>
|
||||
) : null;
|
||||
})}
|
||||
<h2 class="text-2xl font-semibold text-gray-900 mb-6">
|
||||
<Translate>All Guides</Translate>
|
||||
</h2>
|
||||
<div
|
||||
class="grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3 gap-6"
|
||||
>
|
||||
{
|
||||
items.map((item) => {
|
||||
const correspondingItem = all.find(
|
||||
(storeItem) => storeItem.data.item.slug === item.slug,
|
||||
);
|
||||
return correspondingItem ? (
|
||||
<HowtoCard
|
||||
url={`/${locale}/howtos/${item.slug}`}
|
||||
title={item.title}
|
||||
description={item.description}
|
||||
alt={item.title}
|
||||
category={item.category?.label}
|
||||
difficulty_level={item.difficulty_level}
|
||||
time={item.time}
|
||||
total_views={item.total_views}
|
||||
total_downloads={item.total_downloads}
|
||||
author={item._createdBy}
|
||||
tags={
|
||||
item.tags?.map((tag) =>
|
||||
typeof tag === "string" ? tag : tag.label,
|
||||
) || []
|
||||
}
|
||||
locale={locale}
|
||||
howto={item}
|
||||
/>
|
||||
) : null;
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Categories Section -->
|
||||
<div class="space-y-12" id="categories">
|
||||
{categories.map((category) => (
|
||||
<section class="category-section">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<h2
|
||||
id={category.toLowerCase().replace(/\s+/g, '-')}
|
||||
class="text-2xl font-semibold text-gray-900 cursor-pointer hover:text-orange-600 transition-colors"
|
||||
onclick={`window.location.hash = '${category.toLowerCase().replace(/\s+/g, '-')}'`}
|
||||
>
|
||||
<Translate>{category}</Translate>
|
||||
</h2>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
|
||||
{groups[category].slice(0, 8).map((howto: IHowto) => {
|
||||
const correspondingItem = all.find(storeItem => storeItem.data.item.slug === howto.slug);
|
||||
return correspondingItem ? (
|
||||
<HowtoCard
|
||||
url={`/${locale}/howtos/${howto.slug}`}
|
||||
title={howto.title}
|
||||
description={howto.description}
|
||||
alt={howto.title}
|
||||
category={howto.category?.label}
|
||||
difficulty_level={howto.difficulty_level}
|
||||
time={howto.time}
|
||||
total_views={howto.total_views}
|
||||
total_downloads={howto.total_downloads}
|
||||
author={howto._createdBy}
|
||||
tags={howto.tags?.map(tag => typeof tag === 'string' ? tag : tag.label) || []}
|
||||
locale={locale}
|
||||
howto={howto}
|
||||
/>
|
||||
) : null;
|
||||
})}
|
||||
</div>
|
||||
|
||||
{groups[category].length > 8 && (
|
||||
<div class="mt-6 text-center">
|
||||
<a
|
||||
href={`/${locale}/howtos/category/${category.toLowerCase().replace(/\s+/g, '-')}`}
|
||||
class="inline-flex items-center px-4 py-2 bg-orange-500 hover:bg-orange-600 text-white rounded-lg transition-colors"
|
||||
{
|
||||
categories.map((category) => (
|
||||
<section class="category-section">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<h2
|
||||
id={category.toLowerCase().replace(/\s+/g, "-")}
|
||||
class="text-2xl font-semibold text-gray-900 cursor-pointer hover:text-orange-600 transition-colors"
|
||||
onclick={`window.location.hash = '${category.toLowerCase().replace(/\s+/g, "-")}'`}
|
||||
>
|
||||
<Translate>View all</Translate> {groups[category].length} <Translate>guides in</Translate> {category}
|
||||
<svg class="w-4 h-4 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
|
||||
</svg>
|
||||
</a>
|
||||
<Translate>{category}</Translate>
|
||||
</h2>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
))}
|
||||
|
||||
<div class="grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
|
||||
{groups[category].slice(0, 8).map((howto: IHowto) => {
|
||||
const correspondingItem = all.find(
|
||||
(storeItem) => storeItem.data.item.slug === howto.slug,
|
||||
);
|
||||
return correspondingItem ? (
|
||||
<HowtoCard
|
||||
url={`/${locale}/howtos/${howto.slug}`}
|
||||
title={howto.title}
|
||||
description={howto.description}
|
||||
alt={howto.title}
|
||||
category={howto.category?.label}
|
||||
difficulty_level={howto.difficulty_level}
|
||||
time={howto.time}
|
||||
total_views={howto.total_views}
|
||||
total_downloads={howto.total_downloads}
|
||||
author={howto._createdBy}
|
||||
tags={
|
||||
howto.tags?.map((tag) =>
|
||||
typeof tag === "string" ? tag : tag.label,
|
||||
) || []
|
||||
}
|
||||
locale={locale}
|
||||
howto={howto}
|
||||
/>
|
||||
) : null;
|
||||
})}
|
||||
</div>
|
||||
|
||||
{groups[category].length > 8 && (
|
||||
<div class="mt-6 text-center">
|
||||
<a
|
||||
href={`/${locale}/howtos/category/${category.toLowerCase().replace(/\s+/g, "-")}`}
|
||||
class="inline-flex items-center px-4 py-2 bg-orange-500 hover:bg-orange-600 text-white rounded-lg transition-colors"
|
||||
>
|
||||
<Translate>View all</Translate>{" "}
|
||||
{groups[category].length}{" "}
|
||||
<Translate>guides in</Translate> {category}
|
||||
<svg
|
||||
class="w-4 h-4 ml-2"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M9 5l7 7-7 7"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
|
||||
<!-- Back to top -->
|
||||
<div class="mt-12 text-center">
|
||||
<a
|
||||
href="#top"
|
||||
<a
|
||||
href="#top"
|
||||
class="inline-flex items-center px-4 py-2 bg-gray-100 hover:bg-gray-200 text-gray-700 rounded-lg transition-colors"
|
||||
>
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 10l7-7m0 0l7 7m-7-7v18"/>
|
||||
<svg
|
||||
class="w-4 h-4 mr-2"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M5 10l7-7m0 0l7 7m-7-7v18"></path>
|
||||
</svg>
|
||||
<Translate>Back to top</Translate>
|
||||
</a>
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
---
|
||||
import { getCollection } from 'astro:content'
|
||||
import { LANGUAGES_PROD as LANGUAGES } from "config/config.js"
|
||||
import InfoPagesLayout from '@/layouts/InfoPagesLayout.astro';
|
||||
export async function getStaticPaths()
|
||||
{
|
||||
const view = 'infopages'
|
||||
const items = await getCollection(view)
|
||||
const all: unknown[] = []
|
||||
LANGUAGES.forEach((lang) => {
|
||||
items.forEach((item) => {
|
||||
all.push({
|
||||
params: {
|
||||
locale: lang,
|
||||
path: item.slug,
|
||||
},
|
||||
props: {
|
||||
page: item,
|
||||
locale: lang,
|
||||
path: item.id,
|
||||
view
|
||||
},
|
||||
trailingSlash: false
|
||||
})
|
||||
})
|
||||
})
|
||||
return all
|
||||
}
|
||||
const { page } = Astro.props;
|
||||
const { Content } = await page.render();
|
||||
---
|
||||
<InfoPagesLayout frontmatter={page.data}>
|
||||
<Content />
|
||||
</InfoPagesLayout>
|
||||
@ -1,21 +0,0 @@
|
||||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import HelpcenterLayout from "../../layouts/HelpcenterLayout.astro";
|
||||
export async function getStaticPaths() {
|
||||
const helpcenter = await getCollection("helpcenter");
|
||||
const paths = helpcenter.map((page) => {
|
||||
return {
|
||||
params: { slug: page.slug },
|
||||
props: { page },
|
||||
trailingSlash: false,
|
||||
};
|
||||
});
|
||||
return paths;
|
||||
}
|
||||
const { page } = Astro.props;
|
||||
const { Content } = await page.render();
|
||||
---
|
||||
|
||||
<HelpcenterLayout frontmatter={page.data}>
|
||||
<Content />
|
||||
</HelpcenterLayout>
|
||||
@ -1,40 +0,0 @@
|
||||
---
|
||||
import BaseLayout from "@/layouts/BaseLayout.astro";
|
||||
import HelpEntries from "@/components/helpcenter/HelpEntries.astro";
|
||||
import { getCollection } from "astro:content";
|
||||
const allEntries = await getCollection("helpcenter");
|
||||
import Wrapper from "@/components/containers/Wrapper.astro";
|
||||
---
|
||||
|
||||
<BaseLayout>
|
||||
<Wrapper>
|
||||
<section>
|
||||
<div
|
||||
class="flex flex-col gap-12 h-full justify-between 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">
|
||||
Welcome to our help center, How can we help you?
|
||||
</h1>
|
||||
<p class="text-sm text-balance text-neutral-500">
|
||||
Search around for answers to your questions and get the help you need.
|
||||
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<div class="flex flex-col gap-2">
|
||||
{
|
||||
allEntries.slice().map((post) => (
|
||||
<HelpEntries
|
||||
url={"/helpcenter/" + post.slug}
|
||||
title={post.data.title}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
</Wrapper>
|
||||
</BaseLayout>
|
||||
@ -1,21 +0,0 @@
|
||||
---
|
||||
import { getCollection } from 'astro:content';
|
||||
import InfoPagesLayout from '@/layouts/InfoPagesLayout.astro';
|
||||
export async function getStaticPaths() {
|
||||
const infoPages = await getCollection('infopages');
|
||||
const paths = infoPages.map(page => {
|
||||
return {
|
||||
params: { slug: page.slug },
|
||||
props: { page },
|
||||
|
||||
trailingSlash: false,
|
||||
};
|
||||
});
|
||||
return paths;
|
||||
}
|
||||
const { page } = Astro.props;
|
||||
const { Content } = await page.render();
|
||||
---
|
||||
<InfoPagesLayout frontmatter={page.data}>
|
||||
<Content />
|
||||
</InfoPagesLayout>
|
||||
Loading…
Reference in New Issue
Block a user