Commit: 690c1f6

Commit Details

SHA690c1f6ce426c62c29e87ac132dda0f8125192ff
Tree5a67fd55b56735ab4e469c7d06c1c73c4c2b4c20
Author<f69e50@finnacloud.com> 1766368110 +0300
Committer<f69e50@finnacloud.com> 1766368110 +0300
Message
initialize backend structure with controllers, DTOs, and configuration files
GPG Signature
-----BEGIN PGP SIGNATURE-----

iQJSBAABCAA8FiEEWJb139mJI+vZ81KkoAIVSUsXI0oFAmlIo24eHHNvcGhpYS5l
cmFzbGFuQGZpbm5hY2xvdWQuY29tAAoJEKACFUlLFyNKwXYP/RvWx8mxXoZbKEVA
wQFC9UnzcoL/lElB5QMr9opKzRv4uGgFkKMDhbSnqE6NoET5H5VanOFQ9u5a4Khi
9PBTLIEBjbEqA1trC+aTDk3EplVtQYYbSn19CdMSCW7FXJNSg0IiyWKA44iH8Ts0
Xcxh59m6WcwvRDhxQDy6hCXqUa9ISNNk75KRnJS/qRGIEy94DwUYxVfCJpAfzyVu
VmdinE6kZM2GDj8MBTPQTzi6hMf/e9CcAg51tf4oNtd9tnW8QKpTsPsFy434VUDh
Vxtv/oAJ5tuTIprs2BSnyZ6Kb8RDwDdmQyuKjZMUIwZTH/TCE85SZFf5sa5tpYOH
2KekT52ffZgKw/DUtpNosW6qeHgCJlSvwY7BW7M90X5xJuahrKS04lEDBO04cIRn
bg0ayPFTp7Idhl1OuTRhWS6e344g44mJ/9sZK1sXd/0U8OKBbytk35AnCIPCEdSX
8vgjqBR9Wt3A/Kel5j2VcUFDhrAR72a9lJiQHNBicvcVu9Nd41vDnEwUDdNQv6Uc
6omEz3pkVkq+89/eW1KQM8LvrIuGQ/wIUgykvCNSCQ5oba2fjtAXzI+SmxpeCWOz
jTKZOEJyhIQE7uvaUj6/0D2JwlxbMG27fcUN7N3aKv6mSVP7hYnHaUbRLQ+f8/xU
VfU776FkUXS+4CfSooHtu+ioul9O
=ZuqE
-----END PGP SIGNATURE-----

✓ Verified

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

1 <!DOCTYPE html>
2 <html lang="en" xmlns:th="http://www.thymeleaf.org">
3 <head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>Checkout - Payment Link Service</title>
7 <link rel="stylesheet" th:href="@{/css/styles.css}">
8 <style>
9 .checkout-container {
10 max-width: 700px;
11 margin: 2rem auto;
12 padding: 0 1.5rem;
13 }
14 .order-summary {
15 display: none;
16 }
17 .checkout-steps {
18 background: transparent;
19 border-radius: 0;
20 padding: 0;
21 box-shadow: none;
22 border: none;
23 }
24 .step-indicator {
25 display: flex;
26 justify-content: space-between;
27 margin-bottom: 2.5rem;
28 position: relative;
29 max-width: 400px;
30 margin-left: auto;
31 margin-right: auto;
32 }
33 .step-indicator::before {
34 content: '';
35 position: absolute;
36 top: 15px;
37 left: 0;
38 right: 0;
39 height: 2px;
40 background: var(--border-color);
41 z-index: 0;
42 }
43 .step {
44 display: flex;
45 flex-direction: column;
46 align-items: center;
47 position: relative;
48 z-index: 1;
49 }
50 .step-number {
51 width: 32px;
52 height: 32px;
53 font-size: 0.9rem;
54 border: 2px solid var(--border-color);
55 border-radius: 50%;
56 display: flex;
57 align-items: center;
58 justify-content: center;
59 font-weight: 700;
60 margin-bottom: 0.5rem;
61 transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
62 box-shadow: none;
63 background: var(--card-bg);
64 position: relative;
65 z-index: 1;
66 color: var(--text-color);
67 }
68 .step.active .step-number {
69 transform: none;
70 box-shadow: none;
71 background: var(--text-color);
72 border-color: var(--text-color);
73 color: white;
74 }
75 .step.active .step-label {
76 color: var(--text-color);
77 }
78 .step.completed .step-number {
79 background: #4ade80;
80 border-color: #4ade80;
81 box-shadow: none;
82 }
83 .order-summary {
84 background: transparent;
85 border-radius: 0;
86 padding: 0;
87 box-shadow: none;
88 height: fit-content;
89 position: sticky;
90 top: 2rem;
91 border: none;
92 }
93 .form-section h3, .order-summary h3 {
94 font-size: 1rem;
95 font-weight: 500;
96 margin-bottom: 1.5rem;
97 color: var(--text-color);
98 text-transform: uppercase;
99 letter-spacing: 0.1em;
100 border-bottom: none;
101 padding-bottom: 0;
102 }
103 .form-group label {
104 font-size: 0.85rem;
105 font-weight: 500;
106 margin-bottom: 0.5rem;
107 display: block;
108 color: var(--text-color);
109 }
110 input[type="text"],
111 input[type="email"],
112 input[type="tel"],
113 select {
114 width: 100%;
115 padding: 0.75rem;
116 border: 1px solid var(--border-color);
117 border-radius: 4px;
118 font-size: 0.9rem;
119 transition: border-color 0.2s;
120 background: var(--card-bg);
121 }
122 input:focus, select:focus {
123 outline: none;
124 border-color: var(--text-color);
125 }
126 .btn {
127 padding: 0.875rem 1.5rem;
128 border-radius: 4px;
129 font-weight: 500;
130 font-size: 0.9rem;
131 cursor: pointer;
132 transition: all 0.2s;
133 border: 1px solid transparent;
134 }
135 .btn-success {
136 background: var(--text-color);
137 color: white;
138 }
139 .btn-success:hover {
140 opacity: 0.9;
141 transform: none;
142 box-shadow: none;
143 }
144 .step-actions .btn:not(.btn-success) {
145 background: transparent;
146 border: 1px solid var(--border-color);
147 color: var(--text-color);
148 }
149 .step-actions .btn:not(.btn-success):hover {
150 background: var(--bg-color);
151 border-color: var(--text-color);
152 }
153 .summary-item {
154 border-bottom: 1px solid var(--border-color);
155 margin-bottom: 1rem;
156 padding-bottom: 1rem;
157 }
158 .summary-total {
159 border-top: 2px solid var(--border-color);
160 }
161 @media (max-width: 968px) {
162 .checkout-container {
163 grid-template-columns: 1fr;
164 gap: 3rem;
165 }
166 .order-summary {
167 position: relative;
168 top: 0;
169 order: 1;
170 padding: 0;
171 margin-top: 2rem;
172 border-top: 1px solid var(--border-color);
173 padding-top: 2rem;
174 }
175 .step-actions {
176 flex-direction: column-reverse;
177 gap: 1rem;
178 }
179 .step-actions button {
180 width: 100%;
181 }
182 }
183 </style>
184 </head>
185 <body>
186 <header>
187 <nav class="navbar container">
188 <a th:href="@{/}" class="navbar-brand">
189 <h1>Webshop</h1>
190 </a>
191 <div class="navbar-actions">
192 <a th:href="@{/cart}" class="cart-button" aria-label="Cart">
193 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="9" cy="21" r="1"></circle><circle cx="20" cy="21" r="1"></circle><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path></svg>
194 <span id="cartCount" class="cart-badge" style="display: none;">0</span>
195 </a>
196 </div>
197 </nav>
198 </header>
199
200 <main class="container">
201 <div class="checkout-container">
202 <div class="checkout-steps">
203 <div class="step-indicator">
204 <div class="step active" data-step="1">
205 <div class="step-number">1</div>
206 <div class="step-label">Customer Info</div>
207 </div>
208 <div class="step" data-step="2">
209 <div class="step-number">2</div>
210 <div class="step-label">Shipping</div>
211 </div>
212 <div class="step" data-step="3">
213 <div class="step-number">3</div>
214 <div class="step-label">Review</div>
215 </div>
216 </div>
217
218 <div id="checkoutContent">
219 <div class="loading">Loading checkout...</div>
220 </div>
221 </div>
222
223 <div class="order-summary" id="orderSummary">
224 <h3 style="margin-bottom: 1.5rem;">Order Summary</h3>
225 <div id="summaryContent">
226 <div class="loading">Loading...</div>
227 </div>
228 </div>
229 </div>
230 </main>
231
232 <!-- Notification Container -->
233 <div id="notificationContainer" class="notification-container"></div>
234
235 <script th:src="@{/js/notifications.js}"></script>
236 <script th:src="@{/js/csrf.js}"></script>
237 <script th:src="@{/js/checkout.js}"></script>
238 </body>
239 </html>
240