spoko-design-system 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.astro/data-store.json +1 -1
- package/.astro/settings.json +1 -1
- package/.claude/settings.local.json +11 -1
- package/.github/workflows/code-quality.yml +51 -0
- package/.github/workflows/sonarcloud.yml +51 -0
- package/.prettierignore +15 -0
- package/.prettierrc +25 -0
- package/.vscode/extensions.json +0 -1
- package/.vscode/settings.json +0 -4
- package/CHANGELOG.md +14 -0
- package/README.md +19 -3
- package/astro.config.mjs +0 -2
- package/eslint.config.js +64 -0
- package/icon.config.ts +32 -2
- package/package.json +14 -9
- package/sonar-project.properties +19 -0
- package/src/components/Category/CategoriesCarousel.astro +2 -3
- package/src/components/Category/CategoryDetails.astro +4 -5
- package/src/components/Faq.astro +1 -2
- package/src/components/Header/Header.astro +33 -33
- package/src/components/Headline.vue +24 -4
- package/src/components/Product/ProductLink.astro +7 -12
- package/src/components/ProductTile.astro +1 -2
- package/src/layouts/Layout.astro +0 -3
- package/src/layouts/MainLayout.astro +0 -3
- package/src/pages/components/buttons.mdx +0 -1
- package/src/pages/components/hand-drive.mdx +0 -27
- package/src/pages/index.astro +170 -39
- package/src/utils/category/getMainCategoryList.ts +8 -17
- package/src/utils/product/getPriceFormatted.ts +6 -9
- package/src/utils/product/getProductChecklist.ts +1 -2
- package/src/utils/text/formatLocaleNumber.ts +2 -3
- package/uno-config/index.ts +13 -19
- package/.astro/icon.d.ts +0 -11909
- package/astro-i18next.config.mjs +0 -18
- package/astro-i18next.config.ts +0 -11
- package/public/locales/en/translation.json +0 -13
- package/public/locales/pl/translation.json +0 -13
|
@@ -69,32 +69,32 @@ import Search from "astro-pagefind/components/Search";
|
|
|
69
69
|
@apply font-textlight text-base;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
.pagefind-ui__search-input {
|
|
73
|
-
height: 40px
|
|
72
|
+
.pagefind-ui .pagefind-ui__search-input {
|
|
73
|
+
height: 40px;
|
|
74
74
|
border: 0;
|
|
75
|
-
@apply rounded-none sm:rounded-3xl
|
|
75
|
+
@apply rounded-none sm:rounded-3xl w-full;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
.pagefind-ui__result-excerpt,
|
|
79
|
-
.pagefind-ui__button {
|
|
80
|
-
font-size: 14px
|
|
78
|
+
.pagefind-ui .pagefind-ui__result-excerpt,
|
|
79
|
+
.pagefind-ui .pagefind-ui__button {
|
|
80
|
+
font-size: 14px;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
.pagefind-ui__filter-name {
|
|
84
|
-
font-size: 12px
|
|
83
|
+
.pagefind-ui .pagefind-ui__filter-name {
|
|
84
|
+
font-size: 12px;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
.pagefind-ui__drawer:not(.pagefind-ui__hidden) {
|
|
87
|
+
.pagefind-ui .pagefind-ui__drawer:not(.pagefind-ui__hidden) {
|
|
88
88
|
@apply p-4;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
.pagefind-ui__result-link {
|
|
91
|
+
.pagefind-ui .pagefind-ui__result-link {
|
|
92
92
|
color: var(--pagefind-ui-primary);
|
|
93
93
|
font-family: vw_headlight;
|
|
94
94
|
font-size: 1rem;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
.pagefind-ui__result-link::before {
|
|
97
|
+
.pagefind-ui .pagefind-ui__result-link::before {
|
|
98
98
|
top: 0;
|
|
99
99
|
bottom: 0;
|
|
100
100
|
left: 0;
|
|
@@ -103,107 +103,107 @@ import Search from "astro-pagefind/components/Search";
|
|
|
103
103
|
position: absolute;
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
.pagefind-ui__result-excerpt {
|
|
106
|
+
.pagefind-ui .pagefind-ui__result-excerpt {
|
|
107
107
|
color: var(--pagefind-ui-text);
|
|
108
108
|
order: 3;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
.pagefind-ui__drawer {
|
|
111
|
+
.pagefind-ui .pagefind-ui__drawer {
|
|
112
112
|
@apply bg-white md:fixed shadow-lg rounded-b-lg border-t border-t-transparent overflow-auto top-17 md:max-w-[calc(100vw-10%)] max-h-[calc(100vh-10%)] gap-[30px];
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
.pagefind-ui__search-clear {
|
|
115
|
+
.pagefind-ui .pagefind-ui__search-clear {
|
|
116
116
|
height: 38px;
|
|
117
117
|
top: 0;
|
|
118
118
|
@apply sm:rounded-3xl;
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
.pagefind-ui__search-input {
|
|
121
|
+
.pagefind-ui .pagefind-ui__search-input {
|
|
122
122
|
font-size: 1rem;
|
|
123
123
|
font-weight: 400;
|
|
124
124
|
padding: 0 2.5rem 2px;
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
.pagefind-ui__form::before {
|
|
127
|
+
.pagefind-ui .pagefind-ui__form::before {
|
|
128
128
|
top: 14px;
|
|
129
129
|
left: 16px;
|
|
130
130
|
width: 14px;
|
|
131
131
|
height: 14px;
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
.pagefind-ui__result {
|
|
134
|
+
.pagefind-ui .pagefind-ui__result {
|
|
135
135
|
padding: 0.875rem 0;
|
|
136
136
|
gap: 1rem;
|
|
137
137
|
@apply relative;
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
.pagefind-ui__filter-block {
|
|
140
|
+
.pagefind-ui .pagefind-ui__filter-block {
|
|
141
141
|
padding: 0.875rem 0;
|
|
142
142
|
border-width: 1px;
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
.pagefind-ui__filter-group {
|
|
145
|
+
.pagefind-ui .pagefind-ui__filter-group {
|
|
146
146
|
gap: 0.5rem;
|
|
147
147
|
padding-top: 0.875rem;
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
.pagefind-ui__filter-value {
|
|
150
|
+
.pagefind-ui .pagefind-ui__filter-value {
|
|
151
151
|
gap: 10px;
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
.pagefind-ui__filter-checkbox {
|
|
154
|
+
.pagefind-ui .pagefind-ui__filter-checkbox {
|
|
155
155
|
border-radius: 3px;
|
|
156
156
|
margin-top: 1px;
|
|
157
157
|
min-width: calc(16px * var(--pagefind-ui-scale));
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
.pagefind-ui__result-image {
|
|
160
|
+
.pagefind-ui .pagefind-ui__result-image {
|
|
161
161
|
@apply drop-shadow-sm w-full h-full object-contain rounded-none;
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
.pagefind-ui__filter-panel {
|
|
164
|
+
.pagefind-ui .pagefind-ui__filter-panel {
|
|
165
165
|
@apply hidden;
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
-
.pagefind-ui__filter-label {
|
|
168
|
+
.pagefind-ui .pagefind-ui__filter-label {
|
|
169
169
|
font-size: 0.9rem;
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
.pagefind-ui__button {
|
|
172
|
+
.pagefind-ui .pagefind-ui__button {
|
|
173
173
|
font-weight: 400;
|
|
174
174
|
height: 40px;
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
-
.pagefind-ui__result-tag {
|
|
177
|
+
.pagefind-ui .pagefind-ui__result-tag {
|
|
178
178
|
background: inherit;
|
|
179
179
|
padding: 0;
|
|
180
180
|
color: #9ca3af;
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
.pagefind-ui__result-thumb {
|
|
183
|
+
.pagefind-ui .pagefind-ui__result-thumb {
|
|
184
184
|
max-width: 120px;
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
.pagefind-ui__result-tags {
|
|
187
|
+
.pagefind-ui .pagefind-ui__result-tags {
|
|
188
188
|
margin-top: 0.4rem;
|
|
189
189
|
order: 2;
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
.pagefind-ui__filter-name::after {
|
|
192
|
+
.pagefind-ui .pagefind-ui__filter-name::after {
|
|
193
193
|
color: var(--pagefind-ui-primary);
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
-
.pagefind-ui__result-title {
|
|
196
|
+
.pagefind-ui .pagefind-ui__result-title {
|
|
197
197
|
font-size: inherit;
|
|
198
198
|
line-height: 1;
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
-
.pagefind-ui__filter-panel,
|
|
202
|
-
.pagefind-ui__results-area {
|
|
201
|
+
.pagefind-ui .pagefind-ui__filter-panel,
|
|
202
|
+
.pagefind-ui .pagefind-ui__results-area {
|
|
203
203
|
margin-top: 0;
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
-
.pagefind-ui__message {
|
|
206
|
+
.pagefind-ui .pagefind-ui__message {
|
|
207
207
|
padding: 0.875rem 0;
|
|
208
208
|
}
|
|
209
209
|
|
|
@@ -23,7 +23,7 @@ const props = defineProps({
|
|
|
23
23
|
default: 'regular'
|
|
24
24
|
},
|
|
25
25
|
underline: {
|
|
26
|
-
type: Boolean,
|
|
26
|
+
type: [Boolean, String] as PropType<boolean | 'center'>,
|
|
27
27
|
required: false,
|
|
28
28
|
default: false
|
|
29
29
|
}
|
|
@@ -61,8 +61,8 @@ const typographyClass = getTypographyClass()
|
|
|
61
61
|
</script>
|
|
62
62
|
|
|
63
63
|
<template>
|
|
64
|
-
<component :is="props.as" class="mb-2.5
|
|
65
|
-
:class="`${typographyClass} ${props.textSize ? `text-${props.textSize}` : 'text-xl'} ${props.underline ? 'headline--underline' : ''}`">
|
|
64
|
+
<component :is="props.as" class="mb-2.5 leading-none"
|
|
65
|
+
:class="`${typographyClass} ${props.textSize ? `text-${props.textSize}` : 'text-xl'} ${props.underline === true ? 'headline--underline' : ''} ${props.underline === 'center' ? 'headline--underline-center block text-center' : 'flex sm:block md:flex items-center'}`">
|
|
66
66
|
<slot />
|
|
67
67
|
</component>
|
|
68
68
|
</template>
|
|
@@ -82,7 +82,27 @@ const typographyClass = getTypographyClass()
|
|
|
82
82
|
@apply content-empty absolute left-0 bottom-px h-px;
|
|
83
83
|
width: 95%;
|
|
84
84
|
max-width: 255px;
|
|
85
|
-
background-color: #64748b
|
|
85
|
+
background-color: #64748b;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.headline--underline-center {
|
|
90
|
+
@apply relative pb-4;
|
|
91
|
+
|
|
92
|
+
&:before {
|
|
93
|
+
@apply content-empty absolute left-1/2 bottom-px h-px;
|
|
94
|
+
width: 95%;
|
|
95
|
+
max-width: 255px;
|
|
96
|
+
background-color: #64748b;
|
|
97
|
+
transform: translateX(-50%);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
&:after {
|
|
101
|
+
@apply content-empty absolute bottom-0;
|
|
102
|
+
height: 3px;
|
|
103
|
+
width: 55px;
|
|
104
|
+
background-color: var(--clr-primary-400);
|
|
105
|
+
left: calc(50% - min(47.5%, 127.5px));
|
|
86
106
|
}
|
|
87
107
|
}
|
|
88
108
|
</style>
|
|
@@ -27,7 +27,6 @@ import { getProductUrl } from "@utils/product/getProductUrl";
|
|
|
27
27
|
import { getShopProductUrl } from "@utils/product/getShopProductUrl";
|
|
28
28
|
import { getProductTranslation } from "@utils/product/getProductTranslation";
|
|
29
29
|
import { getImageUrl } from '@utils/getImageUrl';
|
|
30
|
-
import i18next, { t } from "i18next";
|
|
31
30
|
import { ProductImage, ProductNumber, removeSemicolon, getPriceFormatted } from "spoko-design-system";
|
|
32
31
|
|
|
33
32
|
// Użycie productObject jeśli przekazane, inaczej pobranie produktu na podstawie productId
|
|
@@ -40,18 +39,14 @@ const thumb = product ? (
|
|
|
40
39
|
: await getImageUrl(product.photo || "", `'ProductLink' ${product.number}`)
|
|
41
40
|
) : "";
|
|
42
41
|
|
|
43
|
-
//
|
|
44
|
-
const productTranslation =
|
|
45
|
-
? null
|
|
46
|
-
: productId ? await getProductTranslation(productId, product?.number || "") : null;
|
|
42
|
+
// Product translation removed - using English only
|
|
43
|
+
const productTranslation = productId ? await getProductTranslation(productId, product?.number || "") : null;
|
|
47
44
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const productName = product.name || 'NO NAME';
|
|
45
|
+
const productName = product ? (
|
|
46
|
+
isShopProduct
|
|
47
|
+
? product.name_en || product.name
|
|
48
|
+
: productTranslation?.name || product.name
|
|
49
|
+
) : 'NO NAME';
|
|
55
50
|
|
|
56
51
|
const nameFormatted = removeSemicolon(productName.toString());
|
|
57
52
|
---
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
const { productObject, locale, index } = Astro.props;
|
|
3
3
|
import Image from "./Image.astro"
|
|
4
4
|
import ProductNumber from "./Product/ProductNumber.astro"
|
|
5
|
-
import { t } from "i18next";
|
|
6
5
|
---
|
|
7
6
|
|
|
8
7
|
{ productObject &&
|
|
@@ -36,7 +35,7 @@ import { t } from "i18next";
|
|
|
36
35
|
{ productObject.name }
|
|
37
36
|
</a>
|
|
38
37
|
|
|
39
|
-
<ProductNumber productNumber={productObject.number} copyDisabled={false} buttonTexts={{ copy:
|
|
38
|
+
<ProductNumber productNumber={productObject.number} copyDisabled={false} buttonTexts={{ copy: 'Copy', copied: 'Copied' }} />
|
|
40
39
|
|
|
41
40
|
{ index !== null &&
|
|
42
41
|
( <meta itemprop="position" content={String(index)} />
|
package/src/layouts/Layout.astro
CHANGED
|
@@ -3,11 +3,8 @@ import HeadCommon from "./partials/HeadCommon.astro";
|
|
|
3
3
|
import FooterCommon from "./partials/FooterCommon.astro";
|
|
4
4
|
import HeadSEO from "../layouts/partials/HeadSEO.astro";
|
|
5
5
|
import * as CONFIG from "../config";
|
|
6
|
-
import { t, changeLanguage } from "i18next";
|
|
7
6
|
import "../styles/main.css";
|
|
8
7
|
import Copyright from "../components/Copyright.astro";
|
|
9
|
-
const locale = "en";
|
|
10
|
-
changeLanguage(locale);
|
|
11
8
|
const { content = {} } = Astro.props;
|
|
12
9
|
const canonicalURL = new URL(Astro.url.pathname, Astro.site).toString();
|
|
13
10
|
---
|
|
@@ -5,11 +5,8 @@ import Header from "../components/Header/Header.astro";
|
|
|
5
5
|
import PageContent from "../components/PageContent.astro";
|
|
6
6
|
import LeftSidebar from "../components/LeftSidebar.astro";
|
|
7
7
|
import * as CONFIG from "../config";
|
|
8
|
-
import { t, changeLanguage } from "i18next";
|
|
9
8
|
import "../styles/main.css";
|
|
10
9
|
import Copyright from "../components/Copyright.astro";
|
|
11
|
-
const locale = "en";
|
|
12
|
-
changeLanguage(locale);
|
|
13
10
|
const { content = {} } = Astro.props;
|
|
14
11
|
const currentPage = Astro.url.pathname;
|
|
15
12
|
const canonicalURL = new URL(Astro.url.pathname, Astro.site).toString();
|
|
@@ -68,33 +68,6 @@ import HandDrive from 'spoko-design-system/src/components/HandDrive.astro'
|
|
|
68
68
|
/>
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
-
## API Integration
|
|
72
|
-
|
|
73
|
-
The component is designed to work seamlessly with API data:
|
|
74
|
-
|
|
75
|
-
```js
|
|
76
|
-
// API Response Format
|
|
77
|
-
{
|
|
78
|
-
"hand_drive": 1, // Original number (legacy)
|
|
79
|
-
"hand_drive_type": "lhd", // Clean string value
|
|
80
|
-
"hand_drive_text": "Left-Hand Drive" // Translated text
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Component Usage
|
|
84
|
-
<HandDrive
|
|
85
|
-
handDrive={partData.hand_drive_type}
|
|
86
|
-
text={partData.hand_drive_text}
|
|
87
|
-
/>
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### API Call Example
|
|
91
|
-
```js
|
|
92
|
-
const response = await fetch('/api/parts/6R106150282V?locale=en&with_translations=1');
|
|
93
|
-
const partData = await response.json();
|
|
94
|
-
|
|
95
|
-
// partData.hand_drive_type = "lhd"
|
|
96
|
-
// partData.hand_drive_text = "Left-Hand Drive"
|
|
97
|
-
```
|
|
98
71
|
|
|
99
72
|
## Design Principles
|
|
100
73
|
|
package/src/pages/index.astro
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
---
|
|
2
|
-
import { changeLanguage } from "i18next";
|
|
3
2
|
import { Icon } from "astro-icon/components";
|
|
4
3
|
import { SITE } from "../config";
|
|
5
4
|
import Jumbotron from "../components/Jumbotron.astro";
|
|
@@ -14,19 +13,19 @@ const navItems = [
|
|
|
14
13
|
title: "Core",
|
|
15
14
|
description: "Base colors, typography, shadows etc.",
|
|
16
15
|
url: "/core/introduction",
|
|
17
|
-
icon: "
|
|
16
|
+
icon: "streamline-freehand-color:database",
|
|
18
17
|
},
|
|
19
18
|
{
|
|
20
19
|
title: "Components",
|
|
21
20
|
description: "The building blocks for our UI.",
|
|
22
21
|
url: "/components/buttons",
|
|
23
|
-
icon: "
|
|
22
|
+
icon: "streamline-freehand-color:module-building-blocks",
|
|
24
23
|
},
|
|
25
24
|
{
|
|
26
25
|
title: "Patterns",
|
|
27
26
|
description: "Common patterns for building interfaces.",
|
|
28
27
|
url: "/patterns/introduction",
|
|
29
|
-
icon: "
|
|
28
|
+
icon: "streamline-freehand-color:layouts-array-1",
|
|
30
29
|
},
|
|
31
30
|
];
|
|
32
31
|
---
|
|
@@ -75,6 +74,69 @@ const navItems = [
|
|
|
75
74
|
}
|
|
76
75
|
</div>
|
|
77
76
|
</nav>
|
|
77
|
+
|
|
78
|
+
<!-- Features Section -->
|
|
79
|
+
<section class="py-16 px-4 max-w-5xl mx-auto">
|
|
80
|
+
<div class="text-center mb-12">
|
|
81
|
+
<Headline as="h2" textSize="3xl" underline="center" class="text-gray-900 mb-6">
|
|
82
|
+
Why Spoko Design System?
|
|
83
|
+
</Headline>
|
|
84
|
+
<p class="text-lg text-gray-600 max-w-2xl mx-auto">
|
|
85
|
+
A modern, comprehensive design system built with Astro and Vue, featuring consistent components and patterns for rapid development.
|
|
86
|
+
</p>
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
|
|
90
|
+
<div class="text-center p-6 bg-white rounded-lg shadow-sm border border-gray-100">
|
|
91
|
+
<Headline as="h3" textSize="xl" underline={false} class="mb-3 text-gray-900 flex items-center justify-center">
|
|
92
|
+
<Icon name="simple-icons:astro" aria-hidden="true" class="text-3xl text-blue-400 mr-3" />
|
|
93
|
+
Astro-Powered
|
|
94
|
+
</Headline>
|
|
95
|
+
<p class="text-gray-600">Built with <a href="https://astro.build/" target="_blank" rel="noopener noreferrer" class="text-blue-600 hover:text-blue-800 underline transition-colors">Astro</a> for lightning-fast performance and seamless integration with modern frameworks.</p>
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
<div class="text-center p-6 bg-white rounded-lg shadow-sm border border-gray-100">
|
|
99
|
+
<Headline as="h3" textSize="xl" underline={false} class="mb-3 text-gray-900 flex items-center justify-center">
|
|
100
|
+
<Icon name="streamline-freehand-color:data-transfer-document-module" aria-hidden="true" class="text-3xl text-blue-400 mr-3" />
|
|
101
|
+
Rich Components
|
|
102
|
+
</Headline>
|
|
103
|
+
<p class="text-gray-600">20+ production-ready components including buttons, modals, carousels, and specialized automotive elements.</p>
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
<div class="text-center p-6 bg-white rounded-lg shadow-sm border border-gray-100">
|
|
107
|
+
<Headline as="h3" textSize="xl" underline={false} class="mb-3 text-gray-900 flex items-center justify-center">
|
|
108
|
+
<Icon name="vscode-icons:file-type-unocss" aria-hidden="true" class="text-3xl text-blue-400 mr-3" />
|
|
109
|
+
UnoCSS Styling
|
|
110
|
+
</Headline>
|
|
111
|
+
<p class="text-gray-600">Atomic CSS approach with <a href="https://unocss.dev/" target="_blank" rel="noopener noreferrer" class="text-blue-600 hover:text-blue-800 underline transition-colors">UnoCSS</a> for flexible, maintainable styling and consistent design tokens.</p>
|
|
112
|
+
</div>
|
|
113
|
+
|
|
114
|
+
<div class="text-center p-6 bg-white rounded-lg shadow-sm border border-gray-100">
|
|
115
|
+
<Headline as="h3" textSize="xl" underline={false} class="mb-3 text-gray-900 flex items-center justify-center">
|
|
116
|
+
<Icon name="vscode-icons:file-type-vue" aria-hidden="true" class="text-3xl text-blue-400 mr-3" />
|
|
117
|
+
Vue Integration
|
|
118
|
+
</Headline>
|
|
119
|
+
<p class="text-gray-600">Seamless <a href="https://vuejs.org/" target="_blank" rel="noopener noreferrer" class="text-blue-600 hover:text-blue-800 underline transition-colors">Vue 3</a> component integration with TypeScript support for interactive elements.</p>
|
|
120
|
+
</div>
|
|
121
|
+
|
|
122
|
+
<div class="text-center p-6 bg-white rounded-lg shadow-sm border border-gray-100">
|
|
123
|
+
<Headline as="h3" textSize="xl" underline={false} class="mb-3 text-gray-900 flex items-center justify-center">
|
|
124
|
+
<Icon name="streamline-freehand-color:design-process-drawing-board" aria-hidden="true" class="text-3xl text-blue-400 mr-3" />
|
|
125
|
+
Design Patterns
|
|
126
|
+
</Headline>
|
|
127
|
+
<p class="text-gray-600">Proven patterns and layouts for common use cases, from landing pages to product catalogs.</p>
|
|
128
|
+
</div>
|
|
129
|
+
|
|
130
|
+
<div class="text-center p-6 bg-white rounded-lg shadow-sm border border-gray-100">
|
|
131
|
+
<Headline as="h3" textSize="xl" underline={false} class="mb-3 text-gray-900 flex items-center justify-center">
|
|
132
|
+
<Icon name="streamline-freehand-color:app-window-source-code" aria-hidden="true" class="text-3xl text-blue-400 mr-3" />
|
|
133
|
+
Developer Ready
|
|
134
|
+
</Headline>
|
|
135
|
+
<p class="text-gray-600">Complete documentation, TypeScript support, and easy npm installation for quick project setup.</p>
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
</section>
|
|
139
|
+
|
|
78
140
|
<div
|
|
79
141
|
class="mt-12 py-20 bg-blue-darker bg-vw text-white flex items-center justify-center relative"
|
|
80
142
|
>
|
|
@@ -86,44 +148,113 @@ const navItems = [
|
|
|
86
148
|
</Quote>
|
|
87
149
|
</div>
|
|
88
150
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
<div>
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
151
|
+
<!-- Download & Examples Section -->
|
|
152
|
+
<section class="py-16 px-4 max-w-6xl mx-auto">
|
|
153
|
+
<div class="grid lg:grid-cols-2 gap-8 md:gap-12">
|
|
154
|
+
|
|
155
|
+
<!-- Download Section -->
|
|
156
|
+
<div class="text-center">
|
|
157
|
+
<Headline underline as="h2" class="text-gray-900 mb-8" textSize="3xl">
|
|
158
|
+
<Icon name="streamline-freehand-color:archive-box" aria-hidden="true" class="text-3xl text-blue-400 mr-3" />
|
|
159
|
+
Get Started
|
|
160
|
+
</Headline>
|
|
161
|
+
|
|
162
|
+
<!-- Installation Commands -->
|
|
163
|
+
<div class="bg-gray-900 rounded-lg p-6 mb-6 text-left space-y-4">
|
|
164
|
+
<div>
|
|
165
|
+
<p class="text-gray-400 text-sm mb-2">Install via npm:</p>
|
|
166
|
+
<code class="text-green-400 font-mono text-lg">npm install spoko-design-system</code>
|
|
167
|
+
</div>
|
|
168
|
+
<div>
|
|
169
|
+
<p class="text-gray-400 text-sm mb-2">Or with pnpm (recommended):</p>
|
|
170
|
+
<code class="text-blue-400 font-mono text-lg">pnpm add spoko-design-system</code>
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
|
|
174
|
+
<!-- Download Links -->
|
|
175
|
+
<div class="flex justify-center gap-6 mb-6">
|
|
176
|
+
<a href="https://www.npmjs.com/package/spoko-design-system"
|
|
177
|
+
target="_blank"
|
|
178
|
+
rel="noopener noreferrer"
|
|
179
|
+
class="flex items-center gap-3 bg-red-600 hover:bg-red-700 text-white px-6 py-3 rounded-lg transition-colors">
|
|
180
|
+
<Icon name="mdi:npm" class="text-3xl" />
|
|
181
|
+
<span class="font-semibold">npm Package</span>
|
|
182
|
+
</a>
|
|
183
|
+
<a href="https://github.com/polo-blue/sds"
|
|
184
|
+
target="_blank"
|
|
185
|
+
rel="noopener noreferrer"
|
|
186
|
+
class="flex items-center gap-3 bg-gray-800 hover:bg-gray-900 text-white px-6 py-3 rounded-lg transition-colors">
|
|
187
|
+
<Icon name="mdi:github" class="text-2xl" />
|
|
188
|
+
<span class="font-semibold">Source Code</span>
|
|
189
|
+
</a>
|
|
190
|
+
</div>
|
|
191
|
+
|
|
192
|
+
<p class="text-gray-600 text-sm">
|
|
193
|
+
TypeScript support included • Complete documentation • Production ready
|
|
194
|
+
</p>
|
|
100
195
|
</div>
|
|
101
|
-
</div>
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
<div>
|
|
105
|
-
<Headline underline as="div" class="mx-auto text-gray-900" textSize="3xl">Examples:</Headline>
|
|
106
|
-
<ul class="flex flex-wrap text-2xl pt-6 lg:(py-4 gap-4) text-left justify-center lg:justify-start w-full">
|
|
107
|
-
<li class="leading-5 me-6 mb-4 lg:mb-0 flex-shrink-0">
|
|
108
|
-
<a href="https://catalog.polo.blue" class="example-link whitespace-nowrap" target="_blank"> catalog.polo.blue</a>
|
|
109
|
-
</li>
|
|
110
|
-
<li class="leading-5 me-6 mb-4 lg:mb-0 flex-shrink-0">
|
|
111
|
-
<a href="https://polo.blue" class="example-link whitespace-nowrap" target="_blank"> polo.blue</a>
|
|
112
|
-
</li>
|
|
113
|
-
<li class="leading-5 me-6 mb-4 lg:mb-0 flex-shrink-0">
|
|
114
|
-
<a href="https://spoko.space" class="example-link whitespace-nowrap" target="_blank"> spoko.space</a>
|
|
115
|
-
</li>
|
|
116
|
-
<li class="leading-5 me-6 mb-4 lg:mb-0 flex-shrink-0">
|
|
117
|
-
<a href="https://sale.polo.blue/" class="example-link whitespace-nowrap" target="_blank">sale.polo.blue</a>
|
|
118
|
-
</li>
|
|
119
|
-
<li class="leading-5 me-6 mb-4 lg:mb-0 flex-shrink-0">
|
|
120
|
-
<a href="https://polo6r.pl" class="example-link whitespace-nowrap" target="_blank">polo6r.pl</a>
|
|
121
|
-
</li>
|
|
122
|
-
</ul>
|
|
123
|
-
</div>
|
|
124
196
|
|
|
197
|
+
<!-- Examples Section -->
|
|
198
|
+
<div class="text-center">
|
|
199
|
+
<Headline underline as="h2" class="text-gray-900 mb-8" textSize="3xl">
|
|
200
|
+
<Icon name="streamline-freehand-color:app-window-source-code" aria-hidden="true" class="text-3xl text-blue-400 mr-3" />
|
|
201
|
+
Live Examples
|
|
202
|
+
</Headline>
|
|
125
203
|
|
|
126
|
-
|
|
204
|
+
<!-- Example Sites Grid -->
|
|
205
|
+
<div class="grid gap-4 mb-6">
|
|
206
|
+
<a href="https://catalog.polo.blue"
|
|
207
|
+
target="_blank"
|
|
208
|
+
rel="noopener noreferrer"
|
|
209
|
+
class="flex items-center justify-between p-4 bg-white border border-gray-200 rounded-lg hover:border-blue-400 hover:shadow-md transition-all group">
|
|
210
|
+
<div class="text-left">
|
|
211
|
+
<h4 class="font-semibold text-gray-900 group-hover:text-blue-600">catalog.polo.blue</h4>
|
|
212
|
+
<p class="text-sm text-gray-600">Car parts catalog</p>
|
|
213
|
+
</div>
|
|
214
|
+
<Icon name="lucide:link" class="text-gray-400 group-hover:text-blue-400" />
|
|
215
|
+
</a>
|
|
216
|
+
|
|
217
|
+
<a href="https://polo.blue"
|
|
218
|
+
target="_blank"
|
|
219
|
+
rel="noopener noreferrer"
|
|
220
|
+
class="flex items-center justify-between p-4 bg-white border border-gray-200 rounded-lg hover:border-blue-400 hover:shadow-md transition-all group">
|
|
221
|
+
<div class="text-left">
|
|
222
|
+
<h4 class="font-semibold text-gray-900 group-hover:text-blue-600">polo.blue</h4>
|
|
223
|
+
<p class="text-sm text-gray-600">Polo 6R DIY workshop & guides</p>
|
|
224
|
+
</div>
|
|
225
|
+
<Icon name="lucide:link" class="text-gray-400 group-hover:text-blue-400" />
|
|
226
|
+
</a>
|
|
227
|
+
|
|
228
|
+
<a href="https://sale.polo.blue/"
|
|
229
|
+
target="_blank"
|
|
230
|
+
rel="noopener noreferrer"
|
|
231
|
+
class="flex items-center justify-between p-4 bg-white border border-gray-200 rounded-lg hover:border-blue-400 hover:shadow-md transition-all group">
|
|
232
|
+
<div class="text-left">
|
|
233
|
+
<h4 class="font-semibold text-gray-900 group-hover:text-blue-600">sale.polo.blue</h4>
|
|
234
|
+
<p class="text-sm text-gray-600">Used car parts marketplace</p>
|
|
235
|
+
</div>
|
|
236
|
+
<Icon name="lucide:link" class="text-gray-400 group-hover:text-blue-400" />
|
|
237
|
+
</a>
|
|
238
|
+
|
|
239
|
+
<a href="https://polo6r.pl"
|
|
240
|
+
target="_blank"
|
|
241
|
+
rel="noopener noreferrer"
|
|
242
|
+
class="flex items-center justify-between p-4 bg-white border border-gray-200 rounded-lg hover:border-blue-400 hover:shadow-md transition-all group">
|
|
243
|
+
<div class="text-left">
|
|
244
|
+
<h4 class="font-semibold text-gray-900 group-hover:text-blue-600">polo6r.pl</h4>
|
|
245
|
+
<p class="text-sm text-gray-600">Polo V Manual</p>
|
|
246
|
+
</div>
|
|
247
|
+
<Icon name="lucide:link" class="text-gray-400 group-hover:text-blue-400" />
|
|
248
|
+
</a>
|
|
249
|
+
</div>
|
|
250
|
+
|
|
251
|
+
<p class="text-gray-600 text-sm">
|
|
252
|
+
See the design system in action across different project types
|
|
253
|
+
</p>
|
|
254
|
+
</div>
|
|
255
|
+
|
|
256
|
+
</div>
|
|
257
|
+
</section>
|
|
127
258
|
</div>
|
|
128
259
|
<script is:inline></script>
|
|
129
260
|
</Layout>
|
|
@@ -1,31 +1,22 @@
|
|
|
1
1
|
import type { CatObject } from "@types/index";
|
|
2
2
|
|
|
3
|
-
import i18next, { t } from "i18next";
|
|
4
3
|
import { getApiCategories } from "@utils/api/getCategories";
|
|
5
4
|
import { getSortedCategories } from "@utils/category/getSortedCategories";
|
|
6
5
|
|
|
7
6
|
// Retrieve main categories:
|
|
8
7
|
export const getMainCategoryList = async (locale: string = 'en'): Promise<CatObject[]> => {
|
|
9
|
-
// Set the selected language
|
|
10
|
-
await i18next.changeLanguage(locale);
|
|
11
|
-
|
|
12
8
|
// Fetch categories from API
|
|
13
9
|
const categories = await getApiCategories();
|
|
14
10
|
|
|
15
|
-
//
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
: ''
|
|
21
|
-
|
|
22
|
-
if (!desc) {
|
|
23
|
-
console.warn('No category description', category.slug, i18next.language);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return { ...category, name, desc };
|
|
11
|
+
// Use category data directly (English only)
|
|
12
|
+
const processedCategories = categories.map((category) => {
|
|
13
|
+
return {
|
|
14
|
+
...category,
|
|
15
|
+
name: category.name || category.slug,
|
|
16
|
+
desc: category.desc || ''
|
|
17
|
+
};
|
|
27
18
|
});
|
|
28
19
|
|
|
29
20
|
// Sort and return processed categories
|
|
30
|
-
return
|
|
21
|
+
return processedCategories.sort(getSortedCategories);
|
|
31
22
|
};
|
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
import i18next from "i18next";
|
|
2
|
-
|
|
3
1
|
export const getPriceFormatted = (product: any) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
if (i18next.language === 'pl') {
|
|
8
|
-
return new Intl.NumberFormat('pl-PL', { style: 'currency', currency: 'PLN' }).format(product.price_pln, )
|
|
2
|
+
// Default to EUR formatting for English-only design system
|
|
3
|
+
if (product.price_eur) {
|
|
4
|
+
return new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(product.price_eur)
|
|
9
5
|
}
|
|
10
|
-
|
|
11
|
-
return '
|
|
6
|
+
if (product.price_pln) {
|
|
7
|
+
return new Intl.NumberFormat('pl-PL', { style: 'currency', currency: 'PLN' }).format(product.price_pln)
|
|
12
8
|
}
|
|
9
|
+
return 'no price'
|
|
13
10
|
}
|
|
14
11
|
|
|
15
12
|
|