Commit: e6d1548

Commit Details

SHAe6d1548c463d8763fb5547ff07a35c521f15c296
Tree2d2b62527861022ccf13eb205ea2bf7c0e4013fd
Author<f69e50@finnacloud.com> 1766442769 +0300
Committer<f69e50@finnacloud.com> 1766442769 +0300
Message
add initial test workflow file
GPG Signature
-----BEGIN PGP SIGNATURE-----

iQJSBAABCAA8FiEEWJb139mJI+vZ81KkoAIVSUsXI0oFAmlJxxEeHHNvcGhpYS5l
cmFzbGFuQGZpbm5hY2xvdWQuY29tAAoJEKACFUlLFyNKb7YP/2QctdaPuHu4+vFn
fh0Opgqt1brKy9JQxV9JZ9tF5XA+rWVi6pyIZK4lywX+a4er+h29sQY7TEHZt9Xn
meAyRUhPbRPmIpRJMMCgstfILUpjNMkMcPE80kJfpp6+ZmLtO8vC4TnW3ATCK1tv
XISV00T4ajCAhZUmYTveNsvSiMMv/Tq4sF9Is4ix+JN7O/lSLseRtuUE1Vv7T7nY
citxLPwR42Eb/1CYhy0JbRYXP816cbe6dGeDeiDZp7EHKx5D8VAqULKRsAL19tSX
hup8N7owBXieuzNQ4RyaDfDJAfNoN3o9pFeD6vQPq8s7x6AloN625g58p0ssxfK+
CGhR0YHR7atR0pEens22p7g2dVJ7NsrKqDBE3TTeUOpfXfjOwqpVh1Bn/v7a2Vg9
o9mhIClSOLfYv2SXJ06+fn8l6oc70nLJkBfcTevmeF//Z9yGH7TXZNUcedxuBbFg
xfEHeJibTamiE3Z1SfHW1YLwe7QqbBogCIxq4RrpYtN15a65vT5HxyLHDJDGG20V
7z34QJhKXIni/AIGscZqx2kE/C42KSD2fBvqvA4YnPwEUQyMvnSSDSKuJ6flXPTv
RsPZMdNsWWWyJ8P/NTo0Y/PPwA/28p9pX064H2lHFNvSEzUYJdKyQXNV3pGWYAvc
PR8Z+nHfbK/EF5jOVJ8+erXzzXUN
=COmA
-----END PGP SIGNATURE-----

✓ Verified

File: src/main/resources/templates/index.html

1 <!DOCTYPE html>
2 <html lang="en" xmlns:th="http://www.thymeleaf.org">
3 <head>
4 <th:block th:replace="~{fragments/header :: head-content}"></th:block>
5 <title>Webshop - Payment Link Service</title>
6 <style>
7 .page-header {
8 margin-bottom: 3rem;
9 text-align: center;
10 }
11 .page-header h2 {
12 font-size: 2.5rem;
13 font-weight: 800;
14 color: var(--text-color);
15 margin-bottom: 0.5rem;
16 letter-spacing: -0.02em;
17 }
18 .page-header p {
19 color: var(--text-light);
20 font-size: 1.1rem;
21 font-weight: 400;
22 }
23
24 /* Region Selector Modal */
25 .region-modal {
26 position: fixed;
27 top: 0;
28 left: 0;
29 width: 100%;
30 height: 100%;
31 background: rgba(0, 0, 0, 0.85);
32 display: flex;
33 align-items: center;
34 justify-content: center;
35 z-index: 10000;
36 backdrop-filter: blur(5px);
37 }
38 .region-modal-content {
39 background: var(--card-bg);
40 border-radius: 20px;
41 padding: 2rem;
42 max-width: 500px;
43 width: 90%;
44 max-height: 85vh;
45 display: flex;
46 flex-direction: column;
47 box-shadow: 0 20px 60px rgba(0,0,0,0.3);
48 }
49 .region-modal-header {
50 text-align: center;
51 margin-bottom: 1.5rem;
52 flex-shrink: 0;
53 }
54 .region-modal-header h2 {
55 font-size: 1.75rem;
56 margin-bottom: 0.5rem;
57 color: var(--text-color);
58 }
59 .region-modal-header p {
60 color: var(--text-light);
61 font-size: 1rem;
62 }
63 .region-modal-body {
64 flex-shrink: 0;
65 display: flex;
66 flex-direction: column;
67 }
68 .region-selector {
69 display: flex;
70 flex-direction: column;
71 }
72
73 /* Fixed height container for region list */
74 .region-list-container {
75 height: 400px;
76 position: relative;
77 display: flex;
78 flex-direction: column;
79 }
80
81 /* Search Input */
82 .region-search-container {
83 position: relative;
84 margin-bottom: 1rem;
85 flex-shrink: 0;
86 }
87 .region-search-icon {
88 position: absolute;
89 left: 1rem;
90 top: 50%;
91 transform: translateY(-50%);
92 color: var(--text-light);
93 pointer-events: none;
94 display: flex;
95 align-items: center;
96 }
97 .region-search-input {
98 width: 100%;
99 padding: 0.875rem 1rem 0.875rem 3rem;
100 border: 2px solid var(--border-color);
101 border-radius: 12px;
102 font-size: 1rem;
103 background: var(--card-bg);
104 color: var(--text-color);
105 transition: all 0.3s ease;
106 }
107 .region-search-input:focus {
108 outline: none;
109 border-color: var(--primary-color);
110 box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1);
111 }
112 .region-search-input:focus + .region-search-icon {
113 color: var(--primary-color);
114 }
115 .region-search-input::placeholder {
116 color: var(--text-light);
117 }
118
119 /* Region List */
120 .region-list {
121 display: flex;
122 flex-direction: column;
123 gap: 0.5rem;
124 overflow-y: auto;
125 padding-right: 0.5rem;
126 flex: 1;
127 }
128
129 /* Region Option - List Style */
130 .region-option {
131 display: flex;
132 align-items: center;
133 gap: 1rem;
134 padding: 1rem 1.25rem;
135 border: 2px solid var(--border-color);
136 background: var(--card-bg);
137 border-radius: 12px;
138 cursor: pointer;
139 transition: all 0.2s ease;
140 }
141 .region-option:hover {
142 border-color: var(--primary-color);
143 background: rgba(52, 152, 219, 0.05);
144 transform: translateX(4px);
145 }
146 .region-option:active {
147 transform: translateX(4px) scale(0.98);
148 }
149 .region-icon {
150 flex-shrink: 0;
151 width: 2.5rem;
152 display: flex;
153 align-items: center;
154 justify-content: center;
155 color: var(--primary-color);
156 }
157 .region-icon svg {
158 width: 24px;
159 height: 24px;
160 }
161 .region-flag-img {
162 width: 32px;
163 height: auto;
164 border-radius: 4px;
165 box-shadow: 0 1px 3px rgba(0,0,0,0.1);
166 }
167 .region-info {
168 flex: 1;
169 min-width: 0;
170 }
171 .region-name {
172 font-weight: 600;
173 color: var(--text-color);
174 margin-bottom: 0.125rem;
175 font-size: 0.95rem;
176 }
177 .region-details {
178 font-size: 0.8rem;
179 color: var(--text-light);
180 }
181 .region-arrow {
182 color: var(--text-light);
183 flex-shrink: 0;
184 display: flex;
185 align-items: center;
186 transition: transform 0.2s ease, color 0.2s ease;
187 }
188 .region-arrow svg {
189 width: 20px;
190 height: 20px;
191 }
192 .region-option:hover .region-arrow {
193 transform: translateX(4px);
194 color: var(--primary-color);
195 }
196
197 /* No Results */
198 .no-results {
199 position: absolute;
200 top: 0;
201 left: 0;
202 right: 0;
203 bottom: 0;
204 display: flex;
205 flex-direction: column;
206 align-items: center;
207 justify-content: center;
208 text-align: center;
209 padding: 2rem 1rem;
210 color: var(--text-light);
211 }
212 .no-results p {
213 font-size: 1rem;
214 font-weight: 500;
215 margin-bottom: 0.5rem;
216 }
217 .no-results small {
218 font-size: 0.875rem;
219 opacity: 0.8;
220 }
221
222 /* Custom Scrollbar for Region List */
223 .region-list::-webkit-scrollbar {
224 width: 6px;
225 }
226 .region-list::-webkit-scrollbar-track {
227 background: transparent;
228 }
229 .region-list::-webkit-scrollbar-thumb {
230 background: var(--border-color);
231 border-radius: 3px;
232 }
233 .region-list::-webkit-scrollbar-thumb:hover {
234 background: var(--text-light);
235 }
236 .region-modal-footer {
237 text-align: center;
238 padding-top: 1.5rem;
239 border-top: 1px solid var(--border-color);
240 flex-shrink: 0;
241 margin-top: 1rem;
242 }
243 .region-modal-footer small {
244 color: var(--text-light);
245 font-size: 0.85rem;
246 }
247
248 /* Pagination */
249 .pagination {
250 display: flex;
251 justify-content: center;
252 align-items: center;
253 gap: 0.5rem;
254 margin: 2rem 0;
255 flex-wrap: wrap;
256 }
257 .pagination button {
258 padding: 0.5rem 1rem;
259 border: 2px solid var(--border-color);
260 background: var(--card-bg);
261 color: var(--text-color);
262 border-radius: 8px;
263 cursor: pointer;
264 font-weight: 500;
265 transition: all 0.3s ease;
266 }
267 .pagination button:hover:not(:disabled) {
268 border-color: var(--primary-color);
269 background: var(--primary-color);
270 color: white;
271 }
272 .pagination button:disabled {
273 opacity: 0.5;
274 cursor: not-allowed;
275 }
276 .pagination button.active {
277 background: var(--primary-color);
278 color: white;
279 border-color: var(--primary-color);
280 }
281 .pagination .page-info {
282 padding: 0.5rem 1rem;
283 color: var(--text-light);
284 }
285 </style>
286 </head>
287 <body>
288 <th:block th:replace="~{fragments/header :: navbar}"></th:block>
289
290 <!-- Region Selector Modal -->
291 <div id="regionSelectorModal" class="region-modal" style="display: none;">
292 <div class="region-modal-content">
293 <div class="region-modal-header">
294 <h2>Welcome!</h2>
295 <p>Please select your region to continue</p>
296 </div>
297 <div class="region-modal-body">
298 <div id="regionSelector" class="region-selector">
299 <div class="loading">Loading regions...</div>
300 </div>
301 </div>
302 <div class="region-modal-footer">
303 <small>We'll show you prices in your local currency and content in your language</small>
304 </div>
305 </div>
306 </div>
307
308 <main class="container">
309 <div class="page-header">
310 <h2>Products</h2>
311 <p>Browse our selection of products</p>
312 <div style="margin-top: 1rem;">
313 <button class="btn-secondary" onclick="showRegionSelector()" style="padding: 0.5rem 1rem; font-size: 0.9rem;">
314 Change Region: <span id="currentRegion">Loading...</span>
315 </button>
316 </div>
317 </div>
318
319 <div class="loading" id="loading">Loading products...</div>
320 <div class="error" id="error" style="display: none;"></div>
321
322 <!-- Pagination Controls -->
323 <div id="paginationTop" class="pagination" style="display: none;"></div>
324
325 <div class="products-grid" id="productsGrid"></div>
326
327 <!-- Pagination Controls -->
328 <div id="paginationBottom" class="pagination" style="display: none;"></div>
329
330 <!-- Product Modal -->
331 <div id="productModal" class="modal">
332 <div class="modal-content">
333 <button class="close" onclick="closeModal()" aria-label="Close">&times;</button>
334 <div id="modalContent"></div>
335 </div>
336 </div>
337 </main>
338
339 <!-- Notification Container -->
340 <div id="notificationContainer" class="notification-container"></div>
341
342 <script th:src="@{/js/notifications.js}"></script>
343 <script th:src="@{/js/csrf.js}"></script>
344 <script th:src="@{/js/app.js}"></script>
345 </body>
346 </html>
347
348