generated from polymech/site-template
cta | lang | conf | detail | css
This commit is contained in:
parent
e31443c020
commit
b08965f6a1
@ -23,7 +23,7 @@
|
||||
"format": "unix-time"
|
||||
}
|
||||
],
|
||||
"default": "2025-03-30T18:54:22.851Z"
|
||||
"default": "2025-03-30T22:12:59.711Z"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -670,7 +670,7 @@
|
||||
},
|
||||
"https://scholarworks.uni.edu/cgi/viewcontent.cgi?article=3680%5C&context=grp": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743360864816
|
||||
"timestamp": 1743372781305
|
||||
},
|
||||
"https://pmc.ncbi.nlm.nih.gov/articles/PMC10489002/": {
|
||||
"isValid": true,
|
||||
@ -754,7 +754,7 @@
|
||||
},
|
||||
"https://journals.plos.org/plosone/article?id=10.1371%252Fjournal.pone.0288696": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743360876521
|
||||
"timestamp": 1743372781857
|
||||
},
|
||||
"https://www.youtube.com/watch?v=_a7usMe_K38": {
|
||||
"isValid": true,
|
||||
@ -841,7 +841,7 @@
|
||||
},
|
||||
"https://www.toraytac.com/media/c3feb206-1398-4e0e-bca6-df7780f11745/tcCurg/TenCate%2520Advanced%2520Composites/Documents/Technical%2520papers/TenCate_chopped_fiber_thermoplastics_compression_molding_technical_paper.pdf": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743360865908
|
||||
"timestamp": 1743372782143
|
||||
},
|
||||
"https://youtu.be/qtZv96cifIU": {
|
||||
"isValid": true,
|
||||
@ -1397,10 +1397,10 @@
|
||||
},
|
||||
"https://www.amazon.it/s?k=cnc+CNC%20Router": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743360867163,
|
||||
"timestamp": 1743371711863,
|
||||
"meta": {
|
||||
"title": "Amazon.it",
|
||||
"image": "https://images-na.ssl-images-amazon.com/captcha/docvmtpr/Captcha_zgssqnlsli.jpg",
|
||||
"title": "Ci dispiace",
|
||||
"image": "https://images-eu.ssl-images-amazon.com/images/G/29/x-locale/communities/people/logo.gif",
|
||||
"favicon": "https://www.amazon.it/favicon.ico"
|
||||
}
|
||||
},
|
||||
@ -1897,7 +1897,7 @@
|
||||
},
|
||||
"https://digitalcommons.calpoly.edu/cgi/viewcontent.cgi?article=1288%5C&context=eesp": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743360868623
|
||||
"timestamp": 1743371713054
|
||||
},
|
||||
"*": {
|
||||
"isValid": false,
|
||||
@ -1905,7 +1905,7 @@
|
||||
},
|
||||
"https://partners.noplasticsunday.com/NPSblog/?bmode=view%5C&idx=11164797": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743360872465,
|
||||
"timestamp": 1743371717064,
|
||||
"meta": {
|
||||
"title": "노플라스틱선데이",
|
||||
"description": "지속가능한 제조 서비스 NPS Partners",
|
||||
@ -2062,7 +2062,7 @@
|
||||
},
|
||||
"https://www.youtube.com/watch?v=Eq9IbetsLB4%5C&t=2s": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743360873850,
|
||||
"timestamp": 1743371718351,
|
||||
"meta": {
|
||||
"title": "Injection molding machine for recycling plastic",
|
||||
"description": "Injection molding machine for recycling plastic (called \"Smart Injector\"). The design is low-cost and uses easy componentsIMPORTANT! The machine is still wor...",
|
||||
@ -2647,7 +2647,7 @@
|
||||
},
|
||||
"https://www.youtube.com/watch?time_continue=163%5C&v=95aPYlXShTY%5C&feature=emb_logo": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743360875213,
|
||||
"timestamp": 1743371719484,
|
||||
"meta": {
|
||||
"title": "Hands-Free Door Opener: Technical Information",
|
||||
"description": "Discover our available models, printing and mounting instructions, and informational sticker for our 3D-printed hands-free door opener to avoid passing on CO...",
|
||||
@ -2895,7 +2895,7 @@
|
||||
},
|
||||
"https://crescent.education/wp-content/uploads/2019/02/MODULE-II-%25E2%2580%2593-FUNDAMENTALS-OF-EXTRUSION-MOULDING.pdf": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743360876383
|
||||
"timestamp": 1743371720792
|
||||
},
|
||||
"https://rjginc.com/essential-injection-molding-safety-standards-and-practices/": {
|
||||
"isValid": true,
|
||||
@ -2920,7 +2920,7 @@
|
||||
},
|
||||
"https://www.oldergeeks.com/downloads/search.php?limit=100%5C&string=Power+Software+Ltd.%5C&sort=file_name%5C&order=asc%5C&id=0%5C&page=9": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743360877625,
|
||||
"timestamp": 1743371722140,
|
||||
"meta": {
|
||||
"favicon": "https://www.oldergeeks.com/favicon.ico"
|
||||
}
|
||||
@ -3131,7 +3131,7 @@
|
||||
},
|
||||
"https://papers.ssrn.com/sol3/Delivery.cfm/733008ad-9620-43bf-896c-aa4a2e9931e5-MECA.pdf?abstractid=4611811%5C&mirid=1": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743360881343,
|
||||
"timestamp": 1743371725907,
|
||||
"meta": {
|
||||
"title": "Page Cannot be Found",
|
||||
"favicon": "https://papers.ssrn.com/favicon.ico"
|
||||
@ -3231,7 +3231,7 @@
|
||||
},
|
||||
"https://en.wikipedia.org/wiki/Jigsaw_%5C(power_tool%5C": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743360881897
|
||||
"timestamp": 1743371726807
|
||||
},
|
||||
"https://www.amazon.de/-/en/Stanley-10-099-Classic/dp/B001FWP58U": {
|
||||
"isValid": false,
|
||||
@ -3819,7 +3819,7 @@
|
||||
},
|
||||
"https://scibizsw.com/20_THE%2520OFFICIAL%2520RASPBERRY%2520PI%2520PROJECTS%2520BOOK%2520v3.pdf": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743360898321
|
||||
"timestamp": 1743371727942
|
||||
},
|
||||
"https://archive.org/stream/MagPi/Projects_Book_v3_djvu.txt": {
|
||||
"isValid": true,
|
||||
@ -10434,5 +10434,56 @@
|
||||
"favicon": "https://www.youtube.com/s/desktop/247b1e86/img/logos/favicon_32x32.png",
|
||||
"siteName": "YouTube"
|
||||
}
|
||||
},
|
||||
"https://www.inventables.com": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743371640343,
|
||||
"meta": {
|
||||
"title": "Inventables, Inc.",
|
||||
"description": "Inventables, Inc.",
|
||||
"image": "https://www.inventables.com/cdn/shop/files/INV_logo_r_yel-wht_h.png?v=1676992753",
|
||||
"favicon": "https://www.inventables.com/cdn/shop/files/favicon_v1.png?crop=center&height=32&v=1682972720&width=32",
|
||||
"siteName": "Inventables, Inc."
|
||||
}
|
||||
},
|
||||
"https://easel.com": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743371641334,
|
||||
"meta": {
|
||||
"title": "Easel ® | CNC Software | Official Site",
|
||||
"description": "Discover Easel, the browser-based CAD/CAM software for 3D carving, and Easel Cabinetmaker for effortless cabinet design. Simplify CNC woodworking today!",
|
||||
"image": "https://cdn.prod.website-files.com/67055e139de63bfa7ce3b278/670997a273d96fadb9f33c39_INV-HERO-Table%202x.jpg",
|
||||
"favicon": "https://cdn.prod.website-files.com/67055e139de63bfa7ce3b278/67abc6213b55379f6dd37f60_favicon.ico"
|
||||
}
|
||||
},
|
||||
"https://inkscape.org": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743371643811,
|
||||
"meta": {
|
||||
"title": "Inkscape - Draw Freely. | Inkscape",
|
||||
"description": "Inkscape is professional vector graphics software which runs on Linux, Mac OS X and Windows desktop computers.",
|
||||
"image": "https://media.inkscape.org/static/images/inkscape-og-front.svg",
|
||||
"favicon": "https://media.inkscape.org/static/images/inkscape-favicon.png"
|
||||
}
|
||||
},
|
||||
"https://thenounproject.com": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743371645295,
|
||||
"meta": {
|
||||
"title": "Noun Project: Free Icons & Stock Photos for Everything",
|
||||
"description": "Noun Project has the most diverse collection of free icons and stock photos. Download SVG and PNG. Over 7 million art-quality icons and free photos.",
|
||||
"image": "https://thenounproject.com/_next/static/media/row1-1-freshly-washed-batch-of-cherries-photo.3b89e0de.jpg",
|
||||
"favicon": "https://thenounproject.com/favicon-32x32.png"
|
||||
}
|
||||
},
|
||||
"https://community.preciousplastic.com/library/wall-peg-mould": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743371669962,
|
||||
"meta": {
|
||||
"title": "Wall Peg mould - Library - Precious Plastic",
|
||||
"description": "Here you will find the 3D model and blueprints to create the wall peg mold!",
|
||||
"image": "https://firebasestorage.googleapis.com/v0/b/onearmyworld.appspot.com/o/uploads%2Fhowtos%2F0Rfqeen9nVyjoGnzdGL4%2Fimage047-18391cf8ca9.jpg?alt=media&token=75080a06-d75f-4f55-a7c3-a760675b102d",
|
||||
"favicon": "data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODMyRDM5NTYyOEM0MTFFQUEwMzBGNDRGMjk0MzJDOEIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QjI0NzZFQjQyOEM0MTFFQUEwMzBGNDRGMjk0MzJDOEIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4MzJEMzk1NDI4QzQxMUVBQTAzMEY0NEYyOTQzMkM4QiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4MzJEMzk1NTI4QzQxMUVBQTAzMEY0NEYyOTQzMkM4QiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PvP7iH0AAAqRSURBVHja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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,9 @@
|
||||
{
|
||||
"model": "gpt-4o",
|
||||
"model": "perplexity/sonar-deep-research",
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "Create a concise description for SEO meta (around 150-160 characters) from the text below. \n Disregard any links or image references. \n Return only the final meta description, no extra commentary.\n\nText to process:\n## PP Sheet Press Guide\n\nPP sheet presses effectively mold pellets or HDPE chips; however, they fall short for various plastics, especially flakes from shredders. Large boards over 1 square meter (10.8 square feet) are unnecessary for most furniture applications. Thus, we developed a method to create boards from mixed plastics. This approach is particularly beneficial for remote areas like islands and mountains, where transporting waste to processing facilities is impractical.\n\n\nUser Location: Tan An, Viet Nam\n\nWe utilize mixed plastics, excluding PET due to its widespread collection. Our focus is on materials typically neglected by traditional systems, such as aluminum compounds, foams, tape, strings, nets, and various packaging materials. We intentionally exclude polyurethane from items like motorcycle seats. Our process produces durable surfaces, more resilient to degradation than those made with polypropylene or polyethylene.\n\nOur affordable press is portable enough to be transported easily. The resultant boards measure approximately 16.5×22.8×0.4 inches (42×58×1 cm), which is generally sufficient for most furniture projects, adding greater value compared to bricks or tiles.\n\nWe fill a tray measuring 62×42×20 cm (24.4×16.5×7.9 in) with a layer of EPS rocks and add some colorful HDPE or PP, comprising about 10 percent of the board's weight, approximately 200 grams (7.1 oz). Then, we add 1800 grams (63.5 oz) of mixed plastic waste. The tray is placed in a toaster between two hot aluminum plates. It has two parts for easy opening and cleaning with a steel brush. The thin iron sheets require minimal energy to heat.\n\nThe tray containing the heated plastic board is placed in a second frame and secured with clamps. A 19.7 in clamp exerts a pressure of 1,102 lbs, sufficient to maintain its shape during cooling. The toaster can then prepare the next board. Heating 4.4 lbs of plastic takes 20 minutes with a 5 kW system, as plastic transfers heat poorly and cannot absorb energy quickly.\n\n### Making Boards from HDPE Bottle Caps\n\nCreating boards from HDPE bottle caps offers limited environmental benefits. A more comprehensive approach is required to address the diverse plastics found in nature. Our technique enables the production of up to 20 boards, each measuring 23.6 x 15.7 x 0.4 inches (60 x 40 x 1 cm), per day. Some individuals invest in a PP sheet press, unaware that it is incompatible with flakes. Consequently, my video serves as a thought-provoking guide."
|
||||
"content": "Extract the required tools, software hardware from the following tutorial. Return as Markdown chapters (H3) with very short bullet points (not bold), with links, max. 5. per category.\n\nText to process:\n### Using the Injection Machine\n\nThis injection machine uses a motor to reduce manual effort and increase pressure for creating detailed products.\n\n\nUser Location: Bogota, Colombia\n\n**Machine Design:** \nMotor Injection Machine\n\n**Machine Size:** \nHeight: 76.77 inches (195 cm); Width: 19.69 inches (50 cm); Depth: 19.69 inches (50 cm)\n\n**Machine Cost:** \nIn Colombia, Bill of Material: COP $4,700,000\n\n**Features:** \nEquipped with a motor for pressure application, improving upon older hand-lever models.\n\n**Compatibility:** \nSuitable for injection molds.\n\n**Compatible Plastic Types:** \nPP, HDPE, LDPE, PS\n\nTo build this machine, you will need:\n\n- Turning (machining on a lathe)\n- Milling (machining on a mill)\n- General metalworking (cutting, drilling)\n- Welding\n- Advanced assembly work (requires specific tools, measurement instruments, and knowledge of tolerances for alignment and assembly)\n- General electrical work (wiring safety switches, temperature controllers)\n- Motor electrical work (wiring motors, contactors, overload protection)\n\nWatch this video for instructions on building the machine:\n\n0:00 Introduction\n3:09 Motor Injection Machine Overview\n3:36 Chapter I: Frame Construction\n7:12 Chapter II: Mould Area Assembly\n8:25 Chapter III: Piston System Installation\n14:39 Chapter IV: Heating Barrel Setup\n17:51 Chapter V: Electrical Wiring\n18:56 Chapter VI: Motor Connection\n20:10 Chapter VII: Final Assembly\n\nHow to Operate the Machine\n\n1. Activate the machine and load the barrel with plastic.\n2. For the initial injection, allow 25 minutes after activation and loading.\n3. Position the mold on the jack surface and press it firmly against the nozzle.\n4. Engage the motor to lower the piston, forcing the molten plastic into the mold until the belt slips in the pulley.\n5. Deactivate the motor and maintain piston pressure for approximately 5 seconds.\n6. Reverse the motor to raise the piston.\n7. For continuous use, refill the barrel before detaching the mold from the nozzle.\n8. Lower the jack to remove the mold.\n9. Open the mold and extract the molded part.\n10. Close the mold and repeat the process from step 3.\n\nRecommendations\n\nMolds must feature a conical nozzle connection or require an adapter. The machine generates significant pressure, allowing for the injection of items with thin walls.\n\n## How to Build a Motor Injection Machine\n\nTo construct a Motor Injection Machine, follow these steps:\n\n[No external links included]"
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
|
||||
@ -26,7 +26,7 @@ export function remarkReadingTime() {
|
||||
*/
|
||||
|
||||
export default defineConfig({
|
||||
site: 'https://polymech.io',
|
||||
site: 'https://creava.org',
|
||||
devToolbar: {
|
||||
enabled: false,
|
||||
},
|
||||
@ -48,15 +48,7 @@ export default defineConfig({
|
||||
tailwindcss({
|
||||
config: './tailwind.config.cjs',
|
||||
jit: true
|
||||
}),
|
||||
{
|
||||
name: 'auto-import-img',
|
||||
transform(code, id) {
|
||||
if (id.endsWith('.astro') || id.endsWith('.mdx')) {
|
||||
// return `import { Img } from 'imagetools/components';\n` + code;
|
||||
}
|
||||
},
|
||||
},
|
||||
}),
|
||||
],
|
||||
build: {
|
||||
target: 'esnext',
|
||||
@ -83,9 +75,7 @@ export default defineConfig({
|
||||
},
|
||||
integrations: [
|
||||
//starlight(),
|
||||
sitemap({
|
||||
|
||||
}),
|
||||
sitemap({}),
|
||||
mdx({
|
||||
rehypePlugins: [
|
||||
rehypeAccessibleEmojis,
|
||||
@ -108,14 +98,4 @@ export default defineConfig({
|
||||
})
|
||||
*/
|
||||
]
|
||||
});
|
||||
/*
|
||||
experimental: {
|
||||
responsiveImages: true,
|
||||
contentIntellisense: true,
|
||||
session: {
|
||||
// Required: the name of the unstorage driver
|
||||
driver: "fs",
|
||||
},
|
||||
},
|
||||
*/
|
||||
});
|
||||
@ -17,7 +17,6 @@ export const blacklist: readonly string[] = [
|
||||
] as const;
|
||||
|
||||
export const urlBlacklist: readonly string[] = [
|
||||
"thenounproject.com",
|
||||
"preciousplastic.com",
|
||||
"community.preciousplastic.com",
|
||||
"bazar.preciousplastic.com",
|
||||
|
||||
@ -20,7 +20,7 @@ interface CacheData {
|
||||
}
|
||||
|
||||
const CACHE_FILE = path.join(process.cwd(), '.cache', 'url-cache.json');
|
||||
const CACHE_EXPIRY = 7 * 24 * 60 * 60 * 1000; // 1 week in milliseconds
|
||||
const CACHE_EXPIRY = 7 * 10 * 24 * 60 * 60 * 1000; // 1 week in milliseconds
|
||||
|
||||
class UrlCache {
|
||||
private cache: CacheData = {};
|
||||
|
||||
@ -12,7 +12,6 @@ import { plainify } from "@/base/strings.js"
|
||||
import { AstroSeo } from "@astrolib/seo"
|
||||
import { item_keywords } from '@/base/seo.js'
|
||||
import StructuredData from './head/ArticleStructuredData.astro'
|
||||
|
||||
import Hreflang from '@/components/polymech/hreflang.astro'
|
||||
import { IComponentConfig } from "@polymech/commons"
|
||||
|
||||
|
||||
@ -1,3 +1,24 @@
|
||||
---
|
||||
import Translate from "@/components/polymech/i18n.astro"
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
description: string;
|
||||
buttonText: string;
|
||||
buttonLink: string;
|
||||
imageSrc: string;
|
||||
imageAlt?: string;
|
||||
}
|
||||
|
||||
const {
|
||||
title = "Directory" ,
|
||||
description = "",
|
||||
buttonText = "Directory",
|
||||
buttonLink = "/howtos",
|
||||
imageSrc = "/images/home/cta-world.png",
|
||||
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">
|
||||
@ -5,28 +26,28 @@
|
||||
<!-- Image takes 50% -->
|
||||
<div class="w-full md:w-1/2">
|
||||
<img
|
||||
class="w-full rounded-lg hover:ring-2 hover:ring-blue-500 aspect-square object-contain"
|
||||
src="/images/home/cta-world.png"
|
||||
alt=""
|
||||
class="w-full max-w-100 rounded-lg hover:ring-2 hover:ring-blue-500 aspect-square object-contain"
|
||||
src={imageSrc}
|
||||
alt={imageAlt}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Text content takes the other 50% -->
|
||||
<div class="w-full md:w-1/2 flex flex-col justify-start">
|
||||
<h1 class="text-lg text-neutral-600 font-mono tracking-tight uppercase">
|
||||
Shop
|
||||
<Translate>{title}</Translate>
|
||||
</h1>
|
||||
<p class="text-sm text-neutral-500">
|
||||
Subscribe today and enjoy more than 50,000 products in your cart.
|
||||
<Translate>{description}</Translate>
|
||||
</p>
|
||||
<div class="flex mt-6">
|
||||
<a
|
||||
href="/en/store"
|
||||
href={buttonLink}
|
||||
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">Directory</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"
|
||||
|
||||
@ -1,70 +1,76 @@
|
||||
---
|
||||
import Translate from "@/components/polymech/i18n.astro"
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
description: string;
|
||||
buttonText: string;
|
||||
buttonLink: string;
|
||||
imageSrc: string;
|
||||
imageAlt?: string;
|
||||
}
|
||||
|
||||
const {
|
||||
title = "Tutorials",
|
||||
description = "100+ Step by step tutorials",
|
||||
buttonText = "Tutorials",
|
||||
buttonLink = "/howtos",
|
||||
imageSrc = "/images/home/icon-tutorials-2.png",
|
||||
imageAlt = ""
|
||||
} = Astro.props;
|
||||
---
|
||||
<section>
|
||||
<div class="py-2">
|
||||
<div
|
||||
class="flex flex-col p-4 text-center py-32 bg-white rounded-xl overflow-hidden relative">
|
||||
<img
|
||||
class="size-96 absolute -left-0 md:scale-100 md:-bottom-0"
|
||||
src="/images/home/icon-tutorials.png"
|
||||
alt=""
|
||||
/>
|
||||
<img
|
||||
class="size-96 absolute ms:scale-150 md:-bottom-0 -right-4"
|
||||
src="/images/home/icon-tutorials-2.png"
|
||||
alt=""
|
||||
/>
|
||||
<div class="flex flex-col md:flex-row gap-6 p-4 bg-white rounded-xl overflow-hidden relative">
|
||||
|
||||
<div class="max-w-xl mx-auto relative">
|
||||
<h1
|
||||
class="text-lg text-neutral-600 font-mono tracking-tight text-balance uppercase">
|
||||
Discover hundreds of tutorials
|
||||
<!-- Image takes 50% -->
|
||||
<div class="w-full md:w-1/2">
|
||||
<img
|
||||
class="w-full max-w-100 rounded-lg hover:ring-2 hover:ring-blue-500 aspect-square object-contain"
|
||||
src={imageSrc}
|
||||
alt={imageAlt}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Text content takes the other 50% -->
|
||||
<div class="w-full md:w-1/2 flex flex-col justify-start">
|
||||
<h1 class="text-lg text-neutral-600 font-mono tracking-tight uppercase">
|
||||
<Translate>{title}</Translate>
|
||||
</h1>
|
||||
<p class="text-sm text-balance text-neutral-500">
|
||||
Learn how to use our products with our step-by-step tutorials.
|
||||
<p class="text-sm text-neutral-500">
|
||||
<Translate>{description}</Translate>
|
||||
</p>
|
||||
<div class="flex justify-center mt-12">
|
||||
<div class="flex mt-6">
|
||||
<a
|
||||
href="/howtos"
|
||||
href={buttonLink}
|
||||
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">Howtos</span>
|
||||
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>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="w-12 text-white transition duration-300 -translate-y-7 group-hover:translate-y-7">
|
||||
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 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>
|
||||
</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 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>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
65
src/components/cta/CtaHowtos2.astro
Normal file
65
src/components/cta/CtaHowtos2.astro
Normal file
@ -0,0 +1,65 @@
|
||||
<section>
|
||||
<div class="py-2">
|
||||
<div
|
||||
class="flex flex-col p-4 text-center py-32 bg-white rounded-xl overflow-hidden relative">
|
||||
<img
|
||||
class="size-96 absolute -left-0 md:scale-100 md:-bottom-0"
|
||||
src="/images/home/icon-tutorials.png"
|
||||
alt=""
|
||||
/>
|
||||
|
||||
<div class="max-w-xl mx-auto relative">
|
||||
<h1
|
||||
class="text-lg text-neutral-600 font-mono tracking-tight text-balance uppercase">
|
||||
Discover hundreds of tutorials
|
||||
</h1>
|
||||
<p class="text-sm text-balance text-neutral-500">
|
||||
Learn how to use our products with our step-by-step tutorials.
|
||||
</p>
|
||||
<div class="flex justify-center mt-12">
|
||||
<a
|
||||
href="/howtos"
|
||||
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">Howtos</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>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
76
src/components/cta/CtaKB.astro
Normal file
76
src/components/cta/CtaKB.astro
Normal file
@ -0,0 +1,76 @@
|
||||
---
|
||||
import Translate from "@/components/polymech/i18n.astro"
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
description: string;
|
||||
buttonText: string;
|
||||
buttonLink: string;
|
||||
imageSrc: string;
|
||||
imageAlt?: string;
|
||||
}
|
||||
|
||||
const {
|
||||
title = "Knowledge Base",
|
||||
description = "Papers, books, articles, and more",
|
||||
buttonText = "Knowledge Base",
|
||||
buttonLink = "/howtos",
|
||||
imageSrc = "/images/home/icon-knowledgebase.png",
|
||||
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">
|
||||
|
||||
<!-- Image takes 50% -->
|
||||
<div class="w-full md:w-1/2">
|
||||
<img
|
||||
class="w-full max-w-100 rounded-lg hover:ring-2 hover:ring-blue-500 aspect-square object-contain"
|
||||
src={imageSrc}
|
||||
alt={imageAlt}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Text content takes the other 50% -->
|
||||
<div class="w-full md:w-1/2 flex flex-col justify-start">
|
||||
<h1 class="text-lg text-neutral-600 font-mono tracking-tight uppercase">
|
||||
<Translate>{title}</Translate>
|
||||
</h1>
|
||||
<p class="text-sm text-neutral-500">
|
||||
<Translate>{description}</Translate>
|
||||
</p>
|
||||
<div class="flex mt-6">
|
||||
<a
|
||||
href={buttonLink}
|
||||
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"><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>
|
||||
</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>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@ -1,181 +0,0 @@
|
||||
---
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { decode } from 'html-entities'
|
||||
import { IHowto, asset_local_rel } from "@/model/howto.js";
|
||||
import { Img } from "imagetools/components";
|
||||
import { i18n as Translate } from "@polymech/astro-base";
|
||||
import BaseLayout from "@/layouts/BaseLayout.astro";
|
||||
import Wrapper from "@/components/containers/Wrapper.astro";
|
||||
import GalleryK from "@/components/polymech/GalleryK.astro";
|
||||
import { files, forward_slash } from "@polymech/commons";
|
||||
import pMap from "p-map";
|
||||
import { sync as exists } from "@polymech/fs/exists";
|
||||
import { sync as read } from "@polymech/fs/read";
|
||||
import { createMarkdownComponent } from "@/base/index.js";
|
||||
import { translate } from "@/base/i18n.js";
|
||||
import { applyFilters, shortenUrl } from "@/base/filters.js";
|
||||
import {
|
||||
HOWTO_FILES_WEB,
|
||||
HOWTO_FILES_ABS,
|
||||
I18N_SOURCE_LANGUAGE,
|
||||
} from "config/config.js";
|
||||
|
||||
interface Props {
|
||||
howto: IHowto;
|
||||
}
|
||||
const { howto } = Astro.props;
|
||||
const howto_abs = HOWTO_FILES_ABS(howto.slug);
|
||||
const howto_resources_default = `# Resources`;
|
||||
const howto_resources_path = path.join(howto_abs, "resources.md");
|
||||
const howto_resources = exists(howto_resources_path)
|
||||
? read(howto_resources_path, "string") || howto_resources_default
|
||||
: howto_resources_default;
|
||||
|
||||
let model_files: any = [...files(howto_abs, "**/**/*.(step|stp)")];
|
||||
model_files = model_files.map((f) =>
|
||||
forward_slash(`${howto.slug}/${path.relative(path.resolve(howto_abs), f)}`),
|
||||
);
|
||||
const content = async (str: string) =>{
|
||||
const ret = await translate(
|
||||
await applyFilters(str),
|
||||
I18N_SOURCE_LANGUAGE,
|
||||
Astro.currentLocale,
|
||||
);
|
||||
return ret
|
||||
}
|
||||
const component = async (str: string) => await createMarkdownComponent(await content(str))
|
||||
|
||||
const stepsWithFilteredMarkdown = await pMap(
|
||||
howto.steps,
|
||||
async (step) => ({
|
||||
...step,
|
||||
filteredMarkdownComponent: await component(step.text),
|
||||
}),
|
||||
{ concurrency: 1 },
|
||||
);
|
||||
|
||||
const Description = component(howto.description);
|
||||
const Resources = component(howto_resources);
|
||||
|
||||
const authorGeo = howto?.user?.geo || {
|
||||
countryName: "Unknown",
|
||||
data: { urls: [] },
|
||||
};
|
||||
|
||||
const authorLinks = (howto?.user?.data.urls || []).filter(
|
||||
(l) => !l.url.includes("one_army") && !l.url.includes("bazar")
|
||||
);
|
||||
---
|
||||
|
||||
<BaseLayout class="markdown-content bg-gray-100">
|
||||
<Wrapper>
|
||||
<article class="bg-white shadow-lg rounded-lg overflow-hidden">
|
||||
<header class="p-8 bg-gradient-to-r from-orange-200 to-orange-300">
|
||||
<h1 class="text-4xl font-bold text-gray-800 mb-4">
|
||||
<Translate>{howto.title}</Translate>
|
||||
</h1>
|
||||
<GalleryK images={[{ src: howto.cover_image.src, alt:'' }]} />
|
||||
<div class="flex gap-2 mb-4">
|
||||
{
|
||||
howto.tags.map((tag) => (
|
||||
<span class="bg-orange-600 text-white text-xs px-3 py-1 rounded-full">
|
||||
<Translate>{tag.toUpperCase()}</Translate>
|
||||
</span>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</header>
|
||||
</article>
|
||||
|
||||
<section class="p-8 meta-view">
|
||||
<ul class="grid grid-cols-2 sm:grid-cols-3 gap-4 mb-6">
|
||||
<li>
|
||||
<strong><Translate>Difficulty:</Translate></strong>
|
||||
<Translate>{howto.difficulty_level}</Translate>
|
||||
</li>
|
||||
<li>
|
||||
<strong><Translate>Time Required:</Translate></strong>
|
||||
<Translate>{decode(howto.time)}</Translate>
|
||||
</li>
|
||||
<li>
|
||||
<strong><Translate>Views:</Translate></strong>{howto.total_views}
|
||||
</li>
|
||||
<li>
|
||||
<strong><Translate>Creator:</Translate></strong>{howto._createdBy}
|
||||
</li>
|
||||
<li>
|
||||
<strong><Translate>Country:</Translate></strong>{authorGeo.countryName}
|
||||
</li>
|
||||
<li>
|
||||
<strong><Translate>Email:</Translate></strong>
|
||||
<a class="text-orange-600 underline" href={`mailto:${authorLinks.find((link)=>link.name.toLowerCase()==="email")?.url.replace("mailto:","")}`}>
|
||||
{authorLinks.find((link)=>link.name.toLowerCase()==="email")?.url.replace("mailto:","")}
|
||||
</a>
|
||||
</li>
|
||||
{
|
||||
authorLinks.filter((l)=>l.name.toLowerCase()!=="email").map((link)=>(
|
||||
<li>
|
||||
<strong>{link.name}:</strong>
|
||||
<a class="text-orange-600 underline" href={link.url} target="_blank">
|
||||
{shortenUrl(link.url)}
|
||||
</a>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
<li><strong><Translate>Downloads:</Translate></strong>{howto.total_downloads}</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="bg-white px-8 pb-8">
|
||||
<div class="mb-8 markdown-content">
|
||||
<Description />
|
||||
</div>
|
||||
<a href={HOWTO_FILES_WEB(howto.slug)} class="inline-block py-2 px-4 bg-orange-600 hover:bg-orange-700 text-white rounded-full mb-8"><Translate>Browse Files</Translate></a>
|
||||
</section>
|
||||
|
||||
<section class="px-8 py-8 bg-orange-50">
|
||||
<h2 class="font-bold mb-4 text-xl"><Translate>Table of Contents</Translate></h2>
|
||||
<ul class="grid grid-cols-1 md:grid-cols-2 gap-2 list-decimal p-4">
|
||||
{stepsWithFilteredMarkdown.map((step, idx)=>(
|
||||
<li>
|
||||
<a href={`#step-${idx+1}`} class="text-orange-600 hover:underline">
|
||||
<Translate>{step.title}</Translate>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="border-t border-gray-300 bg-gray-50 p-8">
|
||||
<h2 class="text-2xl font-bold text-gray-800 mb-6"><Translate>Steps</Translate></h2>
|
||||
<ol class="space-y-10">
|
||||
{stepsWithFilteredMarkdown.map((step, idx) => (
|
||||
<li id={`step-${idx + 1}`} class="bg-white shadow-sm rounded-lg p-6">
|
||||
<div class="mb-4 flex items-center">
|
||||
<span class="bg-orange-600 text-xl font-bold text-white rounded-full h-10 w-10 flex items-center justify-center mr-3">
|
||||
{idx + 1}
|
||||
</span>
|
||||
<h3 class="text-xl font-bold">
|
||||
<Translate>{step.t}</Translate>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="markdown-content">
|
||||
<step.filteredMarkdownComponent />
|
||||
</div>
|
||||
{step.images?.length > 0 && <GalleryK images={step.images} />}
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<section class="p-8 bg-white"><Resources /></section>
|
||||
|
||||
<footer class="p-8 text-sm border-t bg-white text-gray-600">
|
||||
<div class="flex justify-between">
|
||||
<span><Translate>Created on</Translate>: {new Date(howto._created).toLocaleDateString()}</span>
|
||||
<span>{howto.votedUsefulBy.length} <Translate>people found this useful</Translate></span>
|
||||
</div>
|
||||
</footer>
|
||||
</Wrapper>
|
||||
</BaseLayout>
|
||||
@ -33,7 +33,7 @@ import { filter } from "@/base/kbot.js";
|
||||
interface Props {
|
||||
howto: IHowto;
|
||||
}
|
||||
const { howto } = Astro.props;
|
||||
const { frontmatter: howto } = Astro.props;
|
||||
const howto_abs = HOWTO_FILES_ABS(howto.slug);
|
||||
|
||||
let model_files: any = [...files(howto_abs, "**/**/*.(step|stp)")];
|
||||
@ -100,7 +100,6 @@ if (HOWTO_LOCAL_RESOURCES && howto.user && howto.user.geo) {
|
||||
|
||||
const Resources = component(howto_resources);
|
||||
const References = component(howto_references);
|
||||
|
||||
/*
|
||||
const EditLink = () => {
|
||||
return (
|
||||
@ -111,10 +110,10 @@ const EditLink = () => {
|
||||
|
||||
---
|
||||
|
||||
<BaseLayout class="markdown-content bg-gray-100">
|
||||
<BaseLayout class="markdown-content bg-gray-100" frontmatter={howto}>
|
||||
<Wrapper>
|
||||
<article class="bg-white shadow-lg rounded-lg overflow-hidden">
|
||||
<header class="p-8 bg-gradient-to-r from-orange-200 to-orange-300">
|
||||
<header class="p-8 ">
|
||||
<h1 class="text-4xl font-bold text-gray-800 mb-4">
|
||||
<Translate>{howto.title}</Translate>
|
||||
</h1>
|
||||
@ -122,7 +121,7 @@ const EditLink = () => {
|
||||
<div class="flex gap-2 mb-4">
|
||||
{
|
||||
howto.tags.map((tag) => (
|
||||
<span class="bg-orange-600 text-white text-xs px-3 py-1 rounded-full">
|
||||
<span class="bg-orange-500 text-white text-xs px-3 py-1 rounded-full">
|
||||
<Translate>{tag.toUpperCase()}</Translate>
|
||||
</span>
|
||||
))
|
||||
@ -131,7 +130,7 @@ const EditLink = () => {
|
||||
</header>
|
||||
</article>
|
||||
|
||||
<section class="meta-view bg-white rounded-lg p-4">
|
||||
<section class="meta-view bg-white rounded-lg p-4 mt-4">
|
||||
<ul class="grid grid-cols-2 sm:grid-cols-3 gap-4 mt-8 mb-8">
|
||||
<li>
|
||||
<strong><Translate>Difficulty:</Translate></strong>
|
||||
@ -148,9 +147,7 @@ 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>
|
||||
@ -195,7 +192,7 @@ const EditLink = () => {
|
||||
</div>
|
||||
<a
|
||||
href={HOWTO_FILES_WEB(howto.slug)}
|
||||
class="inline-block py-2 px-4 bg-orange-600 hover:bg-orange-700 text-white rounded-full mb-8"
|
||||
class="inline-block py-2 px-4 bg-orange-500 hover:bg-orange-700 text-white rounded-full mb-8"
|
||||
><Translate>Browse Files</Translate></a
|
||||
>
|
||||
</section>
|
||||
@ -220,19 +217,16 @@ const EditLink = () => {
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="border-t border-gray-300 bg-gray-50 p-8">
|
||||
<h2 class="text-2xl font-bold text-gray-800 mb-6">
|
||||
<Translate>Steps</Translate>
|
||||
</h2>
|
||||
<section class="border-gray-300 p-0 lg:p-6 mt-8">
|
||||
<ol class="space-y-10">
|
||||
{
|
||||
stepsWithFilteredMarkdown.map((step, idx) => (
|
||||
<li
|
||||
id={`step-${idx + 1}`}
|
||||
class="bg-white shadow-sm rounded-lg p-6"
|
||||
class="bg-white shadow-sm rounded-lg p-2 lg:p-6"
|
||||
>
|
||||
<div class="mb-4 flex items-center">
|
||||
<span class="bg-orange-600 text-xl font-bold text-white rounded-full h-10 w-10 flex items-center justify-center mr-3">
|
||||
<span class="bg-orange-500 text-xl font-bold text-white rounded-full h-10 w-10 flex items-center justify-center mr-3">
|
||||
{idx + 1}
|
||||
</span>
|
||||
<h3 class="text-xl font-bold">
|
||||
@ -254,9 +248,8 @@ const EditLink = () => {
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<section class="p-8 bg-white markdown-content"><Resources /></section>
|
||||
<section class="p-8 bg-white 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
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"site": {
|
||||
"title": "Polymech",
|
||||
"base_url": "https://polymech.io/",
|
||||
"title": "Creava",
|
||||
"base_url": "https://creava.org/",
|
||||
"description" : "",
|
||||
"base_path": "/",
|
||||
"trailing_slash": false,
|
||||
@ -59,12 +59,12 @@
|
||||
"metadata": {
|
||||
"country": "Spain",
|
||||
"city": "Barcelona",
|
||||
"author": "Polymech",
|
||||
"author": "Creava",
|
||||
"author_bio": "I am in, if its true",
|
||||
"author_url": "https://polymech.io/",
|
||||
"image": "/images/og-image.png",
|
||||
"description": "Polymech is a plastic prototyping company that offers product design services.",
|
||||
"keywords": "Plastic, Prototyping, Product Design, Opensource"
|
||||
"keywords": "Plastic, Craft, Prototyping, Product Design, Opensource"
|
||||
},
|
||||
"shopify": {
|
||||
"currencySymbol": "",
|
||||
@ -82,7 +82,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"tracking": {
|
||||
"_tracking": {
|
||||
"googleAnalytics": "G-RW6Q6EG3J0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,21 +23,25 @@ This document outlines an architecture designed to support open hardware collabo
|
||||
## 🎯 Audience
|
||||
|
||||
### 🔧 Admins
|
||||
|
||||
- Deploy and maintain FileBrowser, Gitea, and rclone remotes.
|
||||
- Set up secure and scalable upload targets.
|
||||
- Configure sync scripts and ensure error logging.
|
||||
|
||||
### 🔌 Integrators
|
||||
|
||||
- Customize and extend the pipeline for your workflow.
|
||||
- Plug in AI filters, add CI tools, integrate with business systems.
|
||||
- Provide hooks to trigger actions after commit (e.g., notify, publish).
|
||||
|
||||
### 👨💻 Developers
|
||||
|
||||
- Use Git (via Gitea) to manage core repositories.
|
||||
- Review and curate auto-submitted hardware projects.
|
||||
- Develop plugins or filters for specialized file formats (e.g., KiCAD, STEP).
|
||||
|
||||
### 🧰 End-Users (Small Biz / Creators)
|
||||
|
||||
- Download designs directly from FileBrowser.
|
||||
- Upload updated or new projects using rclone (e.g., from Google Drive).
|
||||
- Do **not** need Git, GitHub, or CLI knowledge.
|
||||
@ -103,32 +107,39 @@ graph TD
|
||||
## 🧭 Component Roles
|
||||
|
||||
### 📁 FileBrowser
|
||||
|
||||
- Web-based UI for browsing project files.
|
||||
- Can be read-only or auth-gated.
|
||||
|
||||
### 🔀 rclone
|
||||
|
||||
- CLI sync tool supporting many backends (GDrive, Dropbox, S3, etc).
|
||||
- Used by creators to push their project updates.
|
||||
|
||||
### 👀 Watcher
|
||||
|
||||
- Cron job or `inotify`-based script watching upload folders.
|
||||
- Can filter invalid/malicious uploads.
|
||||
|
||||
### 🧠 AI Filters (Optional)
|
||||
|
||||
- Clean file/folder names.
|
||||
- Auto-fill metadata.
|
||||
- Detect file structure issues.
|
||||
|
||||
### 🔄 Merge and Preprocess
|
||||
|
||||
- Normalize project structure.
|
||||
- Generate missing files (README, manifest).
|
||||
- Validate formats.
|
||||
|
||||
### 🗃️ Git Commit / Push
|
||||
|
||||
- Commits are added with default author (e.g., bot).
|
||||
- Pushed to central Gitea instance.
|
||||
|
||||
### 🌐 Distribution Targets
|
||||
|
||||
- Shopify: sell hardware kits or components.
|
||||
- GitHub Pages: publish docs or showcases.
|
||||
- Discourse: post releases, changelogs, discussions.
|
||||
@ -148,7 +159,6 @@ graph TD
|
||||
|
||||
Let me know if you'd like Docker Compose examples, scripts for watcher/commit, or to integrate more endpoints like email feedback or CI pipelines.
|
||||
|
||||
|
||||
## 🔁 Alternatives
|
||||
|
||||
While FileBrowser + rclone + Gitea forms a minimal, robust stack, other tools can be used depending on your needs.
|
||||
|
||||
@ -4,7 +4,8 @@ import Navigation from "../components/global/Navigation.astro";
|
||||
import Footer from "../components/global/Footer.astro";
|
||||
import { isRTL } from "config/config.js"
|
||||
|
||||
const { item: item, additionalKeywords, ...rest } = Astro.props;
|
||||
const { item, additionalKeywords, ...rest } = Astro.props;
|
||||
const d = 2
|
||||
|
||||
---
|
||||
<html lang={Astro.currentLocale} class="scroll-smooth" dir={isRTL(Astro.currentLocale) ? "rtl" : "ltr"}>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { IHowto } from './howto-model.js';
|
||||
|
||||
export const toJSONLD = (howto: IHowto) => {
|
||||
export const get = (howto: IHowto) => {
|
||||
const jsonLD: any = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "HowTo",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
//import { get as handleRSS } from './rss.js'
|
||||
import { get as handleMerchant } from './merchant.js'
|
||||
import { get as handleJsonLd } from './json-ld.js'
|
||||
|
||||
import { get as handleJsonLdHowto } from './json-ld-howto.js'
|
||||
import type { IComponentNode, IComponentConfig } from '@polymech/commons/'
|
||||
|
||||
export type Handler = (node: IComponentNode, config: IComponentConfig, opts: { url?: string }) => Promise<any>
|
||||
@ -12,9 +12,12 @@ export const registry: Record<string, Handler> = {
|
||||
'json-ld': handleJsonLd
|
||||
}
|
||||
|
||||
export const get = async (type: string, node: IComponentNode, config: IComponentConfig, opts: {
|
||||
export const get = async (type: string, node: any, config: IComponentConfig, opts: {
|
||||
url?: string
|
||||
}) => {
|
||||
if (config.steps) {
|
||||
return handleJsonLdHowto(config)
|
||||
}
|
||||
const handler = registry[type]
|
||||
if (!handler) {
|
||||
return false
|
||||
|
||||
@ -30,4 +30,4 @@ export async function getStaticPaths()
|
||||
}
|
||||
const { page:page, ...rest } = Astro.props
|
||||
---
|
||||
<Layout howto={page.data.item} {...rest}/>
|
||||
<Layout frontmatter={page.data.item} {...rest}/>
|
||||
@ -4,6 +4,8 @@ import { getCollection } from "astro:content"
|
||||
import StoreEntries from "@/components/store/StoreEntries.astro"
|
||||
|
||||
import Howtos from "@/components/cta/CtaHowtos.astro"
|
||||
import KB from "@/components/cta/CtaKB.astro"
|
||||
|
||||
import Library from "@/components/cta/CtaLibrary.astro"
|
||||
import Cta1 from "@/components/cta/CtaOne.astro"
|
||||
|
||||
@ -14,7 +16,7 @@ const locale = Astro.currentLocale || "en"
|
||||
---
|
||||
<BaseLayout>
|
||||
<Howtos />
|
||||
<Library />
|
||||
<KB />
|
||||
<Directory />
|
||||
<section>
|
||||
<div class="py-2 space-y-2">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user