Spaces:
Running
Running
Upload search.js
Browse files- javascript/search.js +221 -182
javascript/search.js
CHANGED
@@ -1,199 +1,238 @@
|
|
1 |
-
document.addEventListener("DOMContentLoaded", async function () {
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
col.className = "col-lg-3 col-md-4 col-sm-6";
|
47 |
-
|
48 |
-
const card = document.createElement("div");
|
49 |
-
card.className = "card h-100";
|
50 |
-
|
51 |
-
let thumbnail = "assets/";
|
52 |
-
if (product.files && product.files.length > 0) {
|
53 |
-
thumbnail += product.files[0];
|
54 |
-
}
|
55 |
-
let thumbHTML = "";
|
56 |
-
if (thumbnail.match(/\.(jpg|jpeg|png|gif)$/i)) {
|
57 |
-
thumbHTML = `<img src="${thumbnail}" class="card-img-top" alt="${product.name}">`;
|
58 |
-
} else {
|
59 |
-
thumbHTML = `<img src="img/placeholder.jpg" class="card-img-top" alt="${product.name}">`;
|
60 |
-
}
|
61 |
-
|
62 |
-
const cardBody = document.createElement("div");
|
63 |
-
cardBody.className = "card-body d-flex flex-column";
|
64 |
-
|
65 |
-
const title = document.createElement("h5");
|
66 |
-
title.className = "card-title";
|
67 |
-
title.innerText = product.name;
|
68 |
-
|
69 |
-
const desc = document.createElement("p");
|
70 |
-
desc.className = "card-text";
|
71 |
-
desc.innerText = product.description;
|
72 |
-
|
73 |
-
const price = document.createElement("p");
|
74 |
-
price.className = "card-text fw-bold";
|
75 |
-
price.innerText = formatRupiah(product.price);
|
76 |
-
|
77 |
-
const detailLink = document.createElement("a");
|
78 |
-
detailLink.href = "product.html?id=" + product.id;
|
79 |
-
detailLink.className = "btn btn-primary btn-lg mt-auto";
|
80 |
-
detailLink.innerText = "Lihat Detail";
|
81 |
-
|
82 |
-
const cartBtn = document.createElement("button");
|
83 |
-
cartBtn.className = "btn btn-success btn-lg mt-2";
|
84 |
-
cartBtn.innerText = "Tambah Keranjang";
|
85 |
-
cartBtn.onclick = async function () {
|
86 |
-
await promptQuantityAndAdd(product.id);
|
87 |
-
};
|
88 |
-
|
89 |
-
card.innerHTML = thumbHTML;
|
90 |
-
cardBody.appendChild(title);
|
91 |
-
cardBody.appendChild(desc);
|
92 |
-
cardBody.appendChild(price);
|
93 |
-
cardBody.appendChild(detailLink);
|
94 |
-
cardBody.appendChild(cartBtn);
|
95 |
-
card.appendChild(cardBody);
|
96 |
-
col.appendChild(card);
|
97 |
-
resultList.appendChild(col);
|
98 |
-
});
|
99 |
-
} else {
|
100 |
-
const messageElem = document.createElement("p");
|
101 |
-
messageElem.textContent = "Produk tidak ditemukan.";
|
102 |
-
messageElem.className = "text-center";
|
103 |
-
resultList.appendChild(messageElem);
|
104 |
-
}
|
105 |
-
}
|
106 |
-
|
107 |
-
if (productQuery && transactionQuery) {
|
108 |
-
const hrElement = document.createElement("hr");
|
109 |
-
resultList.appendChild(hrElement);
|
110 |
-
}
|
111 |
-
|
112 |
-
if (transactionQuery) {
|
113 |
-
const userData = await getUserData();
|
114 |
-
const transactions = userData.transactions || {};
|
115 |
-
|
116 |
-
if (Object.keys(transactions).length === 0) {
|
117 |
-
document.getElementById("transaction-details").innerHTML =
|
118 |
-
"<p>Anda belum melakukan transaksi apapun. Silahkan beli produk terlebih dahulu.</p>";
|
119 |
-
return;
|
120 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
|
122 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
123 |
|
124 |
-
|
125 |
-
|
|
|
|
|
126 |
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
});
|
134 |
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
if (Array.isArray(transaction.products)) {
|
139 |
-
transaction.products.forEach((product) => {
|
140 |
-
total += product.price * product.total;
|
141 |
-
});
|
142 |
-
}
|
143 |
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
160 |
|
161 |
-
|
162 |
-
|
|
|
163 |
|
164 |
-
|
165 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
166 |
|
167 |
-
|
168 |
-
|
169 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
170 |
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
</div>
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
</div>
|
181 |
-
</div>
|
182 |
-
<div class="d-flex justify-content-between align-items-center mt-auto">
|
183 |
-
<div class="transaction-date">
|
184 |
-
Tanggal: ${td[0]} <br> Waktu: ${td[1]}
|
185 |
-
</div>
|
186 |
-
</div>
|
187 |
</div>
|
188 |
-
|
|
|
|
|
189 |
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
});
|
198 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
199 |
});
|
|
|
1 |
+
document.addEventListener("DOMContentLoaded", async function () {
|
2 |
+
const resultList = document.getElementById("result-list");
|
3 |
+
const urlParams = new URLSearchParams(window.location.search);
|
4 |
+
const productQuery = urlParams.get("products");
|
5 |
+
const transactionQuery = urlParams.get("transactions");
|
6 |
+
|
7 |
+
const createHeader = (text) => {
|
8 |
+
const header = document.createElement("h3");
|
9 |
+
header.textContent = text;
|
10 |
+
header.className = "col-12 mt-4";
|
11 |
+
resultList.appendChild(header);
|
12 |
+
};
|
13 |
+
|
14 |
+
if (!productQuery && !transactionQuery) {
|
15 |
+
const messageElem = document.createElement("p");
|
16 |
+
messageElem.textContent = "Tidak menemukan hasil pencarian yang sesuai.";
|
17 |
+
messageElem.className = "text-center";
|
18 |
+
resultList.appendChild(messageElem);
|
19 |
+
return;
|
20 |
+
}
|
21 |
+
|
22 |
+
if (productQuery) {
|
23 |
+
const products = await fetchProductsData();
|
24 |
+
|
25 |
+
const filteredProducts = products.filter((product) => {
|
26 |
+
const lowerQuery = productQuery.toLowerCase();
|
27 |
+
return (
|
28 |
+
product.name.toLowerCase().includes(lowerQuery) ||
|
29 |
+
(product.description &&
|
30 |
+
product.description.toLowerCase().includes(lowerQuery))
|
31 |
+
);
|
32 |
+
});
|
33 |
+
|
34 |
+
if (filteredProducts.length > 0) {
|
35 |
+
createHeader("Produk");
|
36 |
+
filteredProducts.forEach((product) => {
|
37 |
+
const col = document.createElement("div");
|
38 |
+
col.className = "col-lg-3 col-md-4 col-sm-6";
|
39 |
+
|
40 |
+
const card = document.createElement("div");
|
41 |
+
card.className = "card h-100";
|
42 |
+
|
43 |
+
let thumbnail = "assets/";
|
44 |
+
if (product.files && product.files.length > 0) {
|
45 |
+
thumbnail += product.files[0];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
}
|
47 |
+
let thumbHTML = "";
|
48 |
+
if (thumbnail.match(/\.(jpg|jpeg|png|gif)$/i)) {
|
49 |
+
thumbHTML = `<img src="${thumbnail}" class="card-img-top" alt="${product.name}">`;
|
50 |
+
} else {
|
51 |
+
thumbHTML = `<img src="img/placeholder.jpg" class="card-img-top" alt="${product.name}">`;
|
52 |
+
}
|
53 |
+
|
54 |
+
const cardBody = document.createElement("div");
|
55 |
+
cardBody.className = "card-body d-flex flex-column";
|
56 |
+
|
57 |
+
const title = document.createElement("h5");
|
58 |
+
title.className = "card-title";
|
59 |
+
title.innerText = product.name;
|
60 |
+
|
61 |
+
const desc = document.createElement("p");
|
62 |
+
desc.className = "card-text";
|
63 |
+
desc.innerText = product.description;
|
64 |
+
|
65 |
+
const price = document.createElement("p");
|
66 |
+
price.className = "card-text fw-bold";
|
67 |
+
price.innerText = formatRupiah(product.price);
|
68 |
+
|
69 |
+
const detailLink = document.createElement("a");
|
70 |
+
detailLink.href = "product.html?id=" + product.id;
|
71 |
+
detailLink.className = "btn btn-primary btn-lg mt-auto";
|
72 |
+
detailLink.innerText = "Lihat Detail";
|
73 |
+
|
74 |
+
const cartBtn = document.createElement("button");
|
75 |
+
cartBtn.className = "btn btn-success btn-lg mt-2";
|
76 |
+
cartBtn.innerText = "Tambah Keranjang";
|
77 |
+
cartBtn.onclick = async function () {
|
78 |
+
await promptQuantityAndAdd(product.id);
|
79 |
+
};
|
80 |
|
81 |
+
card.innerHTML = thumbHTML;
|
82 |
+
cardBody.appendChild(title);
|
83 |
+
cardBody.appendChild(desc);
|
84 |
+
cardBody.appendChild(price);
|
85 |
+
cardBody.appendChild(detailLink);
|
86 |
+
cardBody.appendChild(cartBtn);
|
87 |
+
card.appendChild(cardBody);
|
88 |
+
col.appendChild(card);
|
89 |
+
resultList.appendChild(col);
|
90 |
+
});
|
91 |
+
} else {
|
92 |
+
const messageElem = document.createElement("p");
|
93 |
+
messageElem.textContent = "Produk tidak ditemukan.";
|
94 |
+
messageElem.className = "text-center";
|
95 |
+
resultList.appendChild(messageElem);
|
96 |
+
}
|
97 |
+
}
|
98 |
|
99 |
+
if (productQuery && transactionQuery) {
|
100 |
+
const hrElement = document.createElement("hr");
|
101 |
+
resultList.appendChild(hrElement);
|
102 |
+
}
|
103 |
|
104 |
+
if (transactionQuery) {
|
105 |
+
const userData = await getUserData();
|
106 |
+
if (userData.transactions) {
|
107 |
+
const entries = Object.entries(userData.transactions).sort((a, b) => {
|
108 |
+
const parseDateFromKey = (key) => {
|
109 |
+
const [year, month, day, hour, minute, second, ms] = key.split("_");
|
110 |
+
return new Date(year, month - 1, day, hour, minute, second, ms);
|
111 |
+
};
|
112 |
+
return parseDateFromKey(b[0]) - parseDateFromKey(a[0]);
|
113 |
+
});
|
114 |
+
|
115 |
+
const filteredTransactions = entries.filter(([key, transaction]) => {
|
116 |
+
const cartItems = transaction.products;
|
117 |
+
let productCount = {};
|
118 |
+
|
119 |
+
cartItems.forEach((product) => {
|
120 |
+
const id = product.id;
|
121 |
+
productCount[id] = (productCount[id] || 0) + 1;
|
122 |
});
|
123 |
|
124 |
+
const td = formatTransactionDate(key);
|
125 |
+
const pm = transaction.payment_method;
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
|
127 |
+
let total = 0;
|
128 |
+
for (let id in productCount) {
|
129 |
+
const prod = products.find((p) => p.id == id);
|
130 |
+
if (prod) {
|
131 |
+
const qty = productCount[id];
|
132 |
+
const subtotal = prod.price * qty;
|
133 |
+
total += subtotal;
|
134 |
+
}
|
135 |
+
}
|
136 |
+
|
137 |
+
return (
|
138 |
+
key.includes(transactionQuery) ||
|
139 |
+
td[0].includes(transactionQuery) ||
|
140 |
+
td[1].includes(transactionQuery) ||
|
141 |
+
pm.includes(transactionQuery) ||
|
142 |
+
total.toString().includes(transactionQuery) ||
|
143 |
+
Object.values(productCount).join(",").includes(transactionQuery)
|
144 |
+
);
|
145 |
+
});
|
146 |
+
|
147 |
+
if (filteredTransactions.length > 0) {
|
148 |
+
createHeader("Transaksi");
|
149 |
|
150 |
+
filteredTransactions.forEach(([transactionKey, transaction]) => {
|
151 |
+
const col = document.createElement("div");
|
152 |
+
col.className = "transactions-body col-lg-4 col-md-6 col-sm-12 mt-4";
|
153 |
|
154 |
+
const card = document.createElement("div");
|
155 |
+
card.className = "card h-100";
|
156 |
+
|
157 |
+
const cardBody = document.createElement("div");
|
158 |
+
cardBody.className = "card-body d-flex flex-column";
|
159 |
+
cardBody.style.position = "relative";
|
160 |
+
|
161 |
+
const td = formatTransactionDate(transactionKey);
|
162 |
+
|
163 |
+
const cartItems = transaction.products;
|
164 |
+
let productCount = {};
|
165 |
+
|
166 |
+
cartItems.forEach((product) => {
|
167 |
+
const id = product.id;
|
168 |
+
productCount[id] = (productCount[id] || 0) + 1;
|
169 |
+
});
|
170 |
+
|
171 |
+
let total = 0;
|
172 |
+
for (let id in productCount) {
|
173 |
+
const prod = products.find((p) => p.id == id);
|
174 |
+
if (prod) {
|
175 |
+
const qty = productCount[id];
|
176 |
+
const subtotal = prod.price * qty;
|
177 |
+
total += subtotal;
|
178 |
+
}
|
179 |
+
}
|
180 |
|
181 |
+
let paymentIcon = "";
|
182 |
+
switch (transaction.payment_method) {
|
183 |
+
case "bank":
|
184 |
+
paymentIcon = "bi-building";
|
185 |
+
break;
|
186 |
+
case "qr":
|
187 |
+
paymentIcon = "bi-qr-code";
|
188 |
+
break;
|
189 |
+
case "card":
|
190 |
+
paymentIcon = "bi-credit-card";
|
191 |
+
break;
|
192 |
+
default:
|
193 |
+
paymentIcon = "bi-currency-dollar";
|
194 |
+
}
|
195 |
|
196 |
+
cardBody.innerHTML = `
|
197 |
+
<div class="payment-icon-bg">
|
198 |
+
<i class="bi ${paymentIcon}" style="font-size: 2.5rem;"></i>
|
199 |
+
<span class="m-2">Metode: ${
|
200 |
+
transaction.payment_method ? transaction.payment_method : "N/A"
|
201 |
+
}</span>
|
202 |
+
</div>
|
203 |
+
<div class="content">
|
204 |
+
<div class="d-flex justify-content-between align-items-center">
|
205 |
+
<div class="transaction-total fw-bold">
|
206 |
+
Total: ${formatRupiah(total)}
|
207 |
</div>
|
208 |
+
</div>
|
209 |
+
<div class="d-flex justify-content-between align-items-center mt-auto">
|
210 |
+
<div class="transaction-date">
|
211 |
+
Tanggal: ${td[0]} <br> Waktu: ${td[1]}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
212 |
</div>
|
213 |
+
</div>
|
214 |
+
</div>
|
215 |
+
`;
|
216 |
|
217 |
+
card.appendChild(cardBody);
|
218 |
+
col.appendChild(card);
|
219 |
+
resultList.appendChild(col);
|
220 |
|
221 |
+
col.addEventListener("click", () => {
|
222 |
+
window.location.href = `transaction.html?date=${transactionKey}`;
|
223 |
+
});
|
224 |
});
|
225 |
+
} else {
|
226 |
+
const messageElem = document.createElement("p");
|
227 |
+
messageElem.textContent = "Transaksi tidak ditemukan.";
|
228 |
+
messageElem.className = "text-center";
|
229 |
+
resultList.appendChild(messageElem);
|
230 |
+
}
|
231 |
+
} else {
|
232 |
+
const messageElem = document.createElement("p");
|
233 |
+
messageElem.textContent = "Anda belum melakukan transaksi apapun.";
|
234 |
+
messageElem.className = "text-center";
|
235 |
+
resultList.appendChild(messageElem);
|
236 |
+
}
|
237 |
+
}
|
238 |
});
|