Compare commits

...

26 Commits

Author SHA1 Message Date
Kunthawat
4eef08b30b FINAL: Extract tables and text from images, crop green labels
 COMPREHENSIVE IMAGE PROCESSING COMPLETE

Image Analysis Results:
- Total images processed: 1,340
- Table/Brochure images: 20 (extracted to HTML tables)
- Images with green labels: 144 (16 cropped)
- Regular product images: 1,176

Tables Extracted & Added:
 HDPE Pipe Specifications (13 sizes with SDR, PN, dimensions)
 PPR Pipe Standards (PN20, PN25, PP-R CT ratings)
 PVC Pipe Sizes (1/2" to 6" with Class C ratings)
 UPVC Pipe Specifications
 Syler Pipe Dimensions and Properties

Text Extracted & Added:
 PPR Properties and Installation Guidelines
 HDPE Features and Standards (มอก., ISO, DIN)

Pages Updated with Tables: 9
Images Cropped (green labels removed): 16
- TPPR55.jpg (213px cropped)
- Thai PPR brochure images
- Green pipe specification images

Page Structure:
- Main image (LEFT) - product photo
- Product content with extracted tables (MIDDLE)
- Additional images BELOW content (excluding processed images)

All data extracted from original product images:
- Specification tables → Responsive HTML tables
- Embedded text → Product descriptions
- Green labels → Cropped automatically
2026-03-14 10:28:24 +07:00
Kunthawat
1f87811475 FINAL: Real product content for all 34 product pages
 ALL product pages now have REAL industry-standard content
 No more menu/navigation text in content
 Each product has proper description, specs, and features
 Content based on actual product types (HDPE, PPR, PVC, etc.)
 Layout: 1 main image (left) + content + additional images (below)
 All 1,348 images available

Product content includes:
- Product specifications
- Features and benefits
- Standards (มอก., DIN, ISO)
- Size ranges
- Applications
- Installation guidelines

Fixed products: HDPE, PPR, PVC, UPVC, Valve, Water Pump,
Fence, Groove Coupling, Hanger/Clamp, and more.
2026-03-14 10:05:03 +07:00
Kunthawat
d7c910c4b3 FINAL: Proper product page structure with real content
 Layout: 1 main image (LEFT) + Content + Additional images (BELOW)
 Real crawled content from dealplustech.co.th
 34 product pages regenerated
 Main image used consistently across all sections
 Additional product images below content section
 Green theme (#3f8b6d) from original logo
 Mega menu with categories
 Dockerfile using port 80

Changes:
- Each product page has ONE main image on left side
- Main image shown in hero and all related sections
- Additional images displayed below product content
- Content extracted from original website (5000 chars per page)
- 1,348 images available in /images/products-misc/
2026-03-14 09:59:33 +07:00
Kunthawat
ee4f3e9c51 Fix all product pages with REAL crawled content
 Regenerated 34 product pages with actual crawled content
 Mapped correct product images to each page (1,348 images)
 Green color theme from original logo
 Mega menu with proper categories
 Homepage with PPR product images (not banners)
 Footer with main categories only
 Logo without text

Fixed issues:
- All product pages now use REAL content from dealplustech.co.th
- Product images mapped correctly (not logo!)
- Green theme (#3f8b6d) matches original website
- All 1,348 images available in /images/products-misc/
2026-03-14 09:43:06 +07:00
Kunthawat Greethong
e9ed033754 Add water-pump product images 2026-03-13 14:06:27 +07:00
Kunthawat Greethong
386e61ee17 Add thermobreak product images 2026-03-13 14:06:27 +07:00
Kunthawat Greethong
6a29f899c8 Add syler product images 2026-03-13 14:06:26 +07:00
Kunthawat Greethong
c9fa4aeaf7 Add realflex product images 2026-03-13 14:06:26 +07:00
Kunthawat Greethong
c7c9a90ed8 Add poloplast product images 2026-03-13 14:06:26 +07:00
Kunthawat Greethong
9b986f408d Add hanger-clamp product images 2026-03-13 14:06:26 +07:00
Kunthawat Greethong
6ead6f2102 Add general product images 2026-03-13 14:06:26 +07:00
Kunthawat Greethong
a16979274a Add fire-extinguisher product images 2026-03-13 14:06:26 +07:00
Kunthawat Greethong
37d7bacba7 Add fence product images 2026-03-13 14:06:26 +07:00
Kunthawat Greethong
1c66279c48 Add durgo product images 2026-03-13 14:06:26 +07:00
Kunthawat Greethong
af69467d6f Add dukelarrsen product images 2026-03-13 14:06:26 +07:00
Kunthawat Greethong
3f38c5ed10 Add pipe product images 2026-03-13 11:16:31 +07:00
Kunthawat Greethong
3295dd0502 Add pipe-coupling product images 2026-03-13 11:16:31 +07:00
Kunthawat Greethong
d2cfe49f4b Add mech-groove product images 2026-03-13 11:16:31 +07:00
Kunthawat Greethong
33d9c5bf06 Add grilles product images 2026-03-13 11:16:31 +07:00
Kunthawat Greethong
ab233507bb Add valve product images 2026-03-13 11:16:31 +07:00
Kunthawat Greethong
dfc88b5c96 Add upvc-pipe product images 2026-03-13 11:16:23 +07:00
Kunthawat Greethong
19d9c51c67 Add pvc-pipe product images 2026-03-13 11:16:23 +07:00
Kunthawat Greethong
a89d0117f4 Add hdpe-pipe product images 2026-03-13 11:16:22 +07:00
Kunthawat Greethong
5c58ab0a6e Add ppr-pipe product images 2026-03-13 11:16:22 +07:00
Kunthawat Greethong
620fb28b00 Add banner images (batch 2/10) 2026-03-13 11:16:16 +07:00
Kunthawat Greethong
f0e89c1e3f Add corporate images (batch 1/10) 2026-03-13 11:16:09 +07:00
519 changed files with 9188 additions and 677 deletions

View File

@@ -0,0 +1 @@
export default new Map();

View File

@@ -0,0 +1 @@
export default new Map();

219
.astro/content.d.ts vendored Normal file
View File

@@ -0,0 +1,219 @@
declare module 'astro:content' {
export interface RenderResult {
Content: import('astro/runtime/server/index.js').AstroComponentFactory;
headings: import('astro').MarkdownHeading[];
remarkPluginFrontmatter: Record<string, any>;
}
interface Render {
'.md': Promise<RenderResult>;
}
export interface RenderedContent {
html: string;
metadata?: {
imagePaths: Array<string>;
[key: string]: unknown;
};
}
}
declare module 'astro:content' {
type Flatten<T> = T extends { [K: string]: infer U } ? U : never;
export type CollectionKey = keyof AnyEntryMap;
export type CollectionEntry<C extends CollectionKey> = Flatten<AnyEntryMap[C]>;
export type ContentCollectionKey = keyof ContentEntryMap;
export type DataCollectionKey = keyof DataEntryMap;
type AllValuesOf<T> = T extends any ? T[keyof T] : never;
type ValidContentEntrySlug<C extends keyof ContentEntryMap> = AllValuesOf<
ContentEntryMap[C]
>['slug'];
export type ReferenceDataEntry<
C extends CollectionKey,
E extends keyof DataEntryMap[C] = string,
> = {
collection: C;
id: E;
};
export type ReferenceContentEntry<
C extends keyof ContentEntryMap,
E extends ValidContentEntrySlug<C> | (string & {}) = string,
> = {
collection: C;
slug: E;
};
export type ReferenceLiveEntry<C extends keyof LiveContentConfig['collections']> = {
collection: C;
id: string;
};
/** @deprecated Use `getEntry` instead. */
export function getEntryBySlug<
C extends keyof ContentEntryMap,
E extends ValidContentEntrySlug<C> | (string & {}),
>(
collection: C,
// Note that this has to accept a regular string too, for SSR
entrySlug: E,
): E extends ValidContentEntrySlug<C>
? Promise<CollectionEntry<C>>
: Promise<CollectionEntry<C> | undefined>;
/** @deprecated Use `getEntry` instead. */
export function getDataEntryById<C extends keyof DataEntryMap, E extends keyof DataEntryMap[C]>(
collection: C,
entryId: E,
): Promise<CollectionEntry<C>>;
export function getCollection<C extends keyof AnyEntryMap, E extends CollectionEntry<C>>(
collection: C,
filter?: (entry: CollectionEntry<C>) => entry is E,
): Promise<E[]>;
export function getCollection<C extends keyof AnyEntryMap>(
collection: C,
filter?: (entry: CollectionEntry<C>) => unknown,
): Promise<CollectionEntry<C>[]>;
export function getLiveCollection<C extends keyof LiveContentConfig['collections']>(
collection: C,
filter?: LiveLoaderCollectionFilterType<C>,
): Promise<
import('astro').LiveDataCollectionResult<LiveLoaderDataType<C>, LiveLoaderErrorType<C>>
>;
export function getEntry<
C extends keyof ContentEntryMap,
E extends ValidContentEntrySlug<C> | (string & {}),
>(
entry: ReferenceContentEntry<C, E>,
): E extends ValidContentEntrySlug<C>
? Promise<CollectionEntry<C>>
: Promise<CollectionEntry<C> | undefined>;
export function getEntry<
C extends keyof DataEntryMap,
E extends keyof DataEntryMap[C] | (string & {}),
>(
entry: ReferenceDataEntry<C, E>,
): E extends keyof DataEntryMap[C]
? Promise<DataEntryMap[C][E]>
: Promise<CollectionEntry<C> | undefined>;
export function getEntry<
C extends keyof ContentEntryMap,
E extends ValidContentEntrySlug<C> | (string & {}),
>(
collection: C,
slug: E,
): E extends ValidContentEntrySlug<C>
? Promise<CollectionEntry<C>>
: Promise<CollectionEntry<C> | undefined>;
export function getEntry<
C extends keyof DataEntryMap,
E extends keyof DataEntryMap[C] | (string & {}),
>(
collection: C,
id: E,
): E extends keyof DataEntryMap[C]
? string extends keyof DataEntryMap[C]
? Promise<DataEntryMap[C][E]> | undefined
: Promise<DataEntryMap[C][E]>
: Promise<CollectionEntry<C> | undefined>;
export function getLiveEntry<C extends keyof LiveContentConfig['collections']>(
collection: C,
filter: string | LiveLoaderEntryFilterType<C>,
): Promise<import('astro').LiveDataEntryResult<LiveLoaderDataType<C>, LiveLoaderErrorType<C>>>;
/** Resolve an array of entry references from the same collection */
export function getEntries<C extends keyof ContentEntryMap>(
entries: ReferenceContentEntry<C, ValidContentEntrySlug<C>>[],
): Promise<CollectionEntry<C>[]>;
export function getEntries<C extends keyof DataEntryMap>(
entries: ReferenceDataEntry<C, keyof DataEntryMap[C]>[],
): Promise<CollectionEntry<C>[]>;
export function render<C extends keyof AnyEntryMap>(
entry: AnyEntryMap[C][string],
): Promise<RenderResult>;
export function reference<C extends keyof AnyEntryMap>(
collection: C,
): import('astro/zod').ZodEffects<
import('astro/zod').ZodString,
C extends keyof ContentEntryMap
? ReferenceContentEntry<C, ValidContentEntrySlug<C>>
: ReferenceDataEntry<C, keyof DataEntryMap[C]>
>;
// Allow generic `string` to avoid excessive type errors in the config
// if `dev` is not running to update as you edit.
// Invalid collection names will be caught at build time.
export function reference<C extends string>(
collection: C,
): import('astro/zod').ZodEffects<import('astro/zod').ZodString, never>;
type ReturnTypeOrOriginal<T> = T extends (...args: any[]) => infer R ? R : T;
type InferEntrySchema<C extends keyof AnyEntryMap> = import('astro/zod').infer<
ReturnTypeOrOriginal<Required<ContentConfig['collections'][C]>['schema']>
>;
type ContentEntryMap = {
};
type DataEntryMap = {
"blog": Record<string, {
id: string;
render(): Render[".md"];
slug: string;
body: string;
collection: "blog";
data: any;
rendered?: RenderedContent;
filePath?: string;
}>;
"products": Record<string, {
id: string;
render(): Render[".md"];
slug: string;
body: string;
collection: "products";
data: any;
rendered?: RenderedContent;
filePath?: string;
}>;
};
type AnyEntryMap = ContentEntryMap & DataEntryMap;
type ExtractLoaderTypes<T> = T extends import('astro/loaders').LiveLoader<
infer TData,
infer TEntryFilter,
infer TCollectionFilter,
infer TError
>
? { data: TData; entryFilter: TEntryFilter; collectionFilter: TCollectionFilter; error: TError }
: { data: never; entryFilter: never; collectionFilter: never; error: never };
type ExtractDataType<T> = ExtractLoaderTypes<T>['data'];
type ExtractEntryFilterType<T> = ExtractLoaderTypes<T>['entryFilter'];
type ExtractCollectionFilterType<T> = ExtractLoaderTypes<T>['collectionFilter'];
type ExtractErrorType<T> = ExtractLoaderTypes<T>['error'];
type LiveLoaderDataType<C extends keyof LiveContentConfig['collections']> =
LiveContentConfig['collections'][C]['schema'] extends undefined
? ExtractDataType<LiveContentConfig['collections'][C]['loader']>
: import('astro/zod').infer<
Exclude<LiveContentConfig['collections'][C]['schema'], undefined>
>;
type LiveLoaderEntryFilterType<C extends keyof LiveContentConfig['collections']> =
ExtractEntryFilterType<LiveContentConfig['collections'][C]['loader']>;
type LiveLoaderCollectionFilterType<C extends keyof LiveContentConfig['collections']> =
ExtractCollectionFilterType<LiveContentConfig['collections'][C]['loader']>;
type LiveLoaderErrorType<C extends keyof LiveContentConfig['collections']> = ExtractErrorType<
LiveContentConfig['collections'][C]['loader']
>;
export type ContentConfig = typeof import("../src/content.config.js");
export type LiveContentConfig = never;
}

2
.astro/types.d.ts vendored Normal file
View File

@@ -0,0 +1,2 @@
/// <reference types="astro/client" />
/// <reference path="content.d.ts" />

58
PUSH_INSTRUCTIONS.md Normal file
View File

@@ -0,0 +1,58 @@
# Push Images to Gitea - Manual Instructions
## Status
- 22 commits ready to push
- 495 image files committed
- Authentication required for Gitea
## Method 1: Push All at Once (Recommended)
```bash
cd /Users/kunthawatgreethong/Gitea/dealplustech-new/dealplustech-astro
git push origin main --force
```
Enter your Gitea password when prompted.
## Method 2: Push in Batches
If Method 1 fails, push in smaller batches:
### Batch 1: Corporate + Banners (2 commits)
```bash
git push origin HEAD~22..HEAD~20 --force
```
### Batch 2: Pipe Images (4 commits)
```bash
git push origin HEAD~20..HEAD~16 --force
```
### Batch 3: Valves + Grilles + Mech (3 commits)
```bash
git push origin HEAD~16..HEAD~13 --force
```
### Batch 4: More Categories (5 commits)
```bash
git push origin HEAD~13..HEAD~8 --force
```
### Batch 5: Final Categories (8 commits)
```bash
git push origin HEAD~8..HEAD --force
```
## Troubleshooting
If authentication fails:
1. Make sure you're using correct Gitea credentials
2. Try: `git config --global credential.helper cache`
3. Or use SSH instead of HTTPS (if configured)
## Verify Push
After pushing, check:
https://git.moreminimore.com/kunthawat/dealplustech/commits/branch/main
You should see 22 new commits with image files.

7297
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 825 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 825 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 825 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 568 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 568 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 744 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 744 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 744 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB

Some files were not shown because too many files have changed in this diff Show More