Compare commits

...

16 Commits

Author SHA1 Message Date
louiscklaw
7c1ac6b546 feat: add new CarousellMe routes for OffersMade and MyProfile pages with corresponding API integrations and UI components 2025-06-20 03:15:15 +08:00
louiscklaw
53b498d881 feat: implement Hotel Service Wi-Fi intro page with Swiper slider and HTML content display 2025-06-20 02:04:49 +08:00
louiscklaw
d865fca058 feat: enhance CarousellMe UI with updated filter button styling, end of list indicator, and improved content padding 2025-06-20 01:40:35 +08:00
louiscklaw
871313449e "fix: update CAROUSELL_ME_SETTINGS path to remove redundant tabs prefix for consistency" 2025-06-19 23:20:01 +08:00
louiscklaw
76840a8e1b feat: add comprehensive ServiceMenu and MainTabs components with hotel service listings, QR code access, and user profile settings integration 2025-06-19 23:06:51 +08:00
louiscklaw
a68cb01585 feat: add new SVG icons for MainTabs including air conditioning, alert, assistance, baggage, and banking symbols 2025-06-19 18:51:59 +08:00
louiscklaw
d6b36a0ca6 feat: add getButtonSvg API to fetch button SVG file as Promise 2025-06-19 18:51:43 +08:00
louiscklaw
360da364ff feat: add CarousellMe feature with profile, listings and reviews components 2025-06-19 17:45:45 +08:00
louiscklaw
1fdf10c0da feat: add requirement doc for importing demo page from old projects (REQ0190) 2025-06-19 17:10:54 +08:00
louiscklaw
c0d8d0cd05 feat: add react-i18next and react-star-ratings packages with dependencies update and typescript upgrade 2025-06-19 17:10:15 +08:00
louiscklaw
b923410f99 feat: add react-i18next package for internationalization support 2025-06-19 17:10:03 +08:00
louiscklaw
65f9b83c9f feat: add react-star-ratings package for star rating component 2025-06-19 17:09:07 +08:00
louiscklaw
d8166d8a3d feat: upgrade typescript from 4.9.3 to 5.8.3 2025-06-19 17:08:28 +08:00
louiscklaw
f59a382d8f feat: update payment route paths to use centralized PATHS constants and add missing dummy pay page route 2025-06-19 16:41:48 +08:00
louiscklaw
c4f8a6902c feat: implement payment flow for event joining including success/failure pages and navigation 2025-06-19 16:21:11 +08:00
louiscklaw
7b230d4f8b feat: add 99_references folder to workspace paths 2025-06-19 16:20:45 +08:00
194 changed files with 6507 additions and 412 deletions

View File

@@ -6,10 +6,39 @@ tags: mobile, payment
frontend page to handle party-user pay join event
edit page T.B.A.
## User flow
```mermaid
graph TD
a["user trigger paid request"]
b["redirect user to payment gateway"]
c["payment success, redirect user to payment success page"]
d["payment failed, show user"]
e["redirect user back to event_detail page"]
a --> b --payment ok --> c --> e
b --payment failed --> d
d --> e
```
## Test
- assume user already login
| steps | description |
| ----- | --------------------------------------------------- |
| 1 | user enter event detail page |
| 2 | user press join button |
| 3 | app redirect to payment gateway page |
| 4 | user choose pay |
| 5 | payment success, redirect back to event_detail page |
| end | test done |
## TODO
T.B.A.
## sources
T.B.A.

View File

@@ -0,0 +1,19 @@
---
tags: mobile, carousell, restaurant-cms
---
# REQ0188 import page from old projects
import demo page from old projects
edit page T.B.A.
## TODO
## sources
T.B.A.
## branch
develop/requirements/REQ0190

View File

@@ -10,6 +10,12 @@
"jsonRecursiveSort": false,
"jsonSortOrder": "{\"*\": \"lexical\"}",
"overrides": [
{
"files": "src/pages/MainTabs/index.tsx",
"options": {
"printWidth": 240
}
},
{
"files": "src/App.tsx",
"options": {

View File

@@ -36,6 +36,7 @@
"react-confetti": "^6.4.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.57.0",
"react-i18next": "^15.5.3",
"react-iconly": "^2.2.10",
"react-leaflet": "^4.2.1",
"react-markdown": "^10.1.0",
@@ -44,10 +45,12 @@
"react-router": "^5.3.4",
"react-router-dom": "^5.3.4",
"react-spinners": "^0.17.0",
"react-star-ratings": "^2.3.0",
"react-use": "^17.6.0",
"react-virtuoso": "^4.13.0",
"reselect": "^4.0.0",
"sass": "^1.59.3",
"swiper": "^9.1.1",
"swiper": "^11.2.8",
"use-sound": "^5.0.0",
"zod": "^3.25.56"
},
@@ -60,12 +63,13 @@
"@types/react-dom": "^18.0.11",
"@types/react-router": "^5.1.20",
"@types/react-router-dom": "^5.3.3",
"@types/react-star-ratings": "^2.3.3",
"@vitejs/plugin-react": "^3.1.0",
"husky": "^8.0.3",
"lint-staged": "^13.2.0",
"prettier": "^3.5.3",
"prettier-plugin-sort-json": "^4.1.1",
"typescript": "^4.9.3",
"typescript": "^5.8.3",
"vite": "^4.2.0"
}
},
@@ -395,12 +399,10 @@
}
},
"node_modules/@babel/runtime": {
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz",
"integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==",
"dependencies": {
"regenerator-runtime": "^0.13.11"
},
"version": "7.27.6",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz",
"integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
@@ -1326,6 +1328,16 @@
"@types/react-router": "*"
}
},
"node_modules/@types/react-star-ratings": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/@types/react-star-ratings/-/react-star-ratings-2.3.3.tgz",
"integrity": "sha512-8vLqJG1uRA2SmYBBMPWpv6QWHLvZ/a3XmELCIf4xh4VFXT7QkkrcthiLSMjQ4ibDiUtYYpyLB0JoR1lBHSHA2A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/slice-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-4.0.0.tgz",
@@ -1831,6 +1843,12 @@
"node": ">=10"
}
},
"node_modules/classnames": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
"integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==",
"license": "MIT"
},
"node_modules/clean-stack": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
@@ -2056,9 +2074,9 @@
}
},
"node_modules/decode-named-character-reference": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz",
"integrity": "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==",
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz",
"integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==",
"license": "MIT",
"dependencies": {
"character-entities": "^2.0.0"
@@ -2714,6 +2732,15 @@
"integrity": "sha512-iARIBPgcQrwtEr+tALF+rapJ8qSc+Set2GJQl7xT1MQzWaVkFebdJhR3alVlSiUf5U7nAANKuj3aWpwerocD5w==",
"license": "MIT"
},
"node_modules/html-parse-stringify": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
"integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
"license": "MIT",
"dependencies": {
"void-elements": "3.1.0"
}
},
"node_modules/html-url-attributes": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz",
@@ -2760,6 +2787,38 @@
"integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==",
"license": "BSD-3-Clause"
},
"node_modules/i18next": {
"version": "25.2.1",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-25.2.1.tgz",
"integrity": "sha512-+UoXK5wh+VlE1Zy5p6MjcvctHXAhRwQKCxiJD8noKZzIXmnAX8gdHX5fLPA3MEVxEN4vbZkQFy8N0LyD9tUqPw==",
"funding": [
{
"type": "individual",
"url": "https://locize.com"
},
{
"type": "individual",
"url": "https://locize.com/i18next.html"
},
{
"type": "individual",
"url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.27.1"
},
"peerDependencies": {
"typescript": "^5"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/immediate": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
@@ -4653,6 +4712,32 @@
"react": "^16.8.0 || ^17 || ^18 || ^19"
}
},
"node_modules/react-i18next": {
"version": "15.5.3",
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.5.3.tgz",
"integrity": "sha512-ypYmOKOnjqPEJZO4m1BI0kS8kWqkBNsKYyhVUfij0gvjy9xJNoG/VcGkxq5dRlVwzmrmY1BQMAmpbbUBLwC4Kw==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.27.6",
"html-parse-stringify": "^3.0.1"
},
"peerDependencies": {
"i18next": ">= 23.2.3",
"react": ">= 16.8.0",
"typescript": "^5"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
},
"typescript": {
"optional": true
}
}
},
"node_modules/react-iconly": {
"version": "2.2.10",
"resolved": "https://registry.npmjs.org/react-iconly/-/react-iconly-2.2.10.tgz",
@@ -4793,6 +4878,31 @@
"react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/react-star-ratings": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/react-star-ratings/-/react-star-ratings-2.3.0.tgz",
"integrity": "sha512-34Z/oFNDRRn4ZcX7F3t9ccnpo7SQ32gD/vsusQOBc6B6vlqaGR6tke1/Yx3jTDjemKRSmXqhKgpPTR7/JAXq6A==",
"license": "BSD-3-Clause",
"dependencies": {
"classnames": "^2.2.1",
"prop-types": "^15.6.0",
"react": "^16.1.0"
}
},
"node_modules/react-star-ratings/node_modules/react": {
"version": "16.14.0",
"resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz",
"integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==",
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/react-universal-interface": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz",
@@ -4828,6 +4938,16 @@
"react-dom": "*"
}
},
"node_modules/react-virtuoso": {
"version": "4.13.0",
"resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.13.0.tgz",
"integrity": "sha512-XHv2Fglpx80yFPdjZkV9d1baACKghg/ucpDFEXwaix7z0AfVQj+mF6lM+YQR6UC/TwzXG2rJKydRMb3+7iV3PA==",
"license": "MIT",
"peerDependencies": {
"react": ">=16 || >=17 || >= 18 || >= 19",
"react-dom": ">=16 || >=17 || >= 18 || >=19"
}
},
"node_modules/reactcss": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz",
@@ -4870,11 +4990,6 @@
"optional": true,
"peer": true
},
"node_modules/regenerator-runtime": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
},
"node_modules/remark-parse": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz",
@@ -5196,11 +5311,6 @@
"node": ">= 10.x"
}
},
"node_modules/ssr-window": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-4.0.2.tgz",
"integrity": "sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ=="
},
"node_modules/stack-generator": {
"version": "2.0.10",
"resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.10.tgz",
@@ -5323,18 +5433,18 @@
}
},
"node_modules/style-to-js": {
"version": "1.1.16",
"resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.16.tgz",
"integrity": "sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw==",
"version": "1.1.17",
"resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.17.tgz",
"integrity": "sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA==",
"license": "MIT",
"dependencies": {
"style-to-object": "1.0.8"
"style-to-object": "1.0.9"
}
},
"node_modules/style-to-object": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz",
"integrity": "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==",
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.9.tgz",
"integrity": "sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw==",
"license": "MIT",
"dependencies": {
"inline-style-parser": "0.2.4"
@@ -5380,9 +5490,9 @@
}
},
"node_modules/swiper": {
"version": "9.1.1",
"resolved": "https://registry.npmjs.org/swiper/-/swiper-9.1.1.tgz",
"integrity": "sha512-D1zArOwI6XCXCYBULPA4jTxpqp5SQtvntjinbXNZwXzj6P3KS51zSWuMarCLXq5oRISay4nX+TuShpxz8qhtbw==",
"version": "11.2.8",
"resolved": "https://registry.npmjs.org/swiper/-/swiper-11.2.8.tgz",
"integrity": "sha512-S5FVf6zWynPWooi7pJ7lZhSUe2snTzqLuUzbd5h5PHUOhzgvW0bLKBd2wv0ixn6/5o9vwc/IkQT74CRcLJQzeg==",
"funding": [
{
"type": "patreon",
@@ -5393,9 +5503,7 @@
"url": "http://opencollective.com/swiper"
}
],
"dependencies": {
"ssr-window": "^4.0.2"
},
"license": "MIT",
"engines": {
"node": ">= 4.7.0"
}
@@ -5568,16 +5676,17 @@
}
},
"node_modules/typescript": {
"version": "4.9.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
"dev": true,
"version": "5.8.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
"devOptional": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=4.2.0"
"node": ">=14.17"
}
},
"node_modules/unified": {
@@ -5836,6 +5945,15 @@
"fsevents": "~2.3.2"
}
},
"node_modules/void-elements": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
"integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/wait-for-expect": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/wait-for-expect/-/wait-for-expect-3.0.1.tgz",
@@ -6216,12 +6334,9 @@
}
},
"@babel/runtime": {
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz",
"integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==",
"requires": {
"regenerator-runtime": "^0.13.11"
}
"version": "7.27.6",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz",
"integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q=="
},
"@babel/template": {
"version": "7.22.5",
@@ -6954,6 +7069,15 @@
"@types/react-router": "*"
}
},
"@types/react-star-ratings": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/@types/react-star-ratings/-/react-star-ratings-2.3.3.tgz",
"integrity": "sha512-8vLqJG1uRA2SmYBBMPWpv6QWHLvZ/a3XmELCIf4xh4VFXT7QkkrcthiLSMjQ4ibDiUtYYpyLB0JoR1lBHSHA2A==",
"dev": true,
"requires": {
"@types/react": "*"
}
},
"@types/slice-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-4.0.0.tgz",
@@ -7301,6 +7425,11 @@
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
"dev": true
},
"classnames": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
"integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="
},
"clean-stack": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
@@ -7463,9 +7592,9 @@
}
},
"decode-named-character-reference": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz",
"integrity": "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==",
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz",
"integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==",
"requires": {
"character-entities": "^2.0.0"
}
@@ -7925,6 +8054,14 @@
"resolved": "https://registry.npmjs.org/howler/-/howler-2.2.4.tgz",
"integrity": "sha512-iARIBPgcQrwtEr+tALF+rapJ8qSc+Set2GJQl7xT1MQzWaVkFebdJhR3alVlSiUf5U7nAANKuj3aWpwerocD5w=="
},
"html-parse-stringify": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
"integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
"requires": {
"void-elements": "3.1.0"
}
},
"html-url-attributes": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz",
@@ -7952,6 +8089,15 @@
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz",
"integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw=="
},
"i18next": {
"version": "25.2.1",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-25.2.1.tgz",
"integrity": "sha512-+UoXK5wh+VlE1Zy5p6MjcvctHXAhRwQKCxiJD8noKZzIXmnAX8gdHX5fLPA3MEVxEN4vbZkQFy8N0LyD9tUqPw==",
"peer": true,
"requires": {
"@babel/runtime": "^7.27.1"
}
},
"immediate": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
@@ -9191,6 +9337,15 @@
"integrity": "sha512-RbEks3+cbvTP84l/VXGUZ+JMrKOS8ykQCRYdm5aYsxnDquL0vspsyNhGRO7pcH6hsZqWlPOjLye7rJqdtdAmlg==",
"requires": {}
},
"react-i18next": {
"version": "15.5.3",
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.5.3.tgz",
"integrity": "sha512-ypYmOKOnjqPEJZO4m1BI0kS8kWqkBNsKYyhVUfij0gvjy9xJNoG/VcGkxq5dRlVwzmrmY1BQMAmpbbUBLwC4Kw==",
"requires": {
"@babel/runtime": "^7.27.6",
"html-parse-stringify": "^3.0.1"
}
},
"react-iconly": {
"version": "2.2.10",
"resolved": "https://registry.npmjs.org/react-iconly/-/react-iconly-2.2.10.tgz",
@@ -9282,6 +9437,28 @@
"integrity": "sha512-L/8HTylaBmIWwQzIjMq+0vyaRXuoAevzWoD35wKpNTxxtYXWZp+xtgkfD7Y4WItuX0YvdxMPU79+7VhhmbmuTQ==",
"requires": {}
},
"react-star-ratings": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/react-star-ratings/-/react-star-ratings-2.3.0.tgz",
"integrity": "sha512-34Z/oFNDRRn4ZcX7F3t9ccnpo7SQ32gD/vsusQOBc6B6vlqaGR6tke1/Yx3jTDjemKRSmXqhKgpPTR7/JAXq6A==",
"requires": {
"classnames": "^2.2.1",
"prop-types": "^15.6.0",
"react": "^16.1.0"
},
"dependencies": {
"react": {
"version": "16.14.0",
"resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz",
"integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2"
}
}
}
},
"react-universal-interface": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz",
@@ -9309,6 +9486,12 @@
"tslib": "^2.1.0"
}
},
"react-virtuoso": {
"version": "4.13.0",
"resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.13.0.tgz",
"integrity": "sha512-XHv2Fglpx80yFPdjZkV9d1baACKghg/ucpDFEXwaix7z0AfVQj+mF6lM+YQR6UC/TwzXG2rJKydRMb3+7iV3PA==",
"requires": {}
},
"reactcss": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz",
@@ -9343,11 +9526,6 @@
"optional": true,
"peer": true
},
"regenerator-runtime": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
},
"remark-parse": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz",
@@ -9570,11 +9748,6 @@
"integrity": "sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==",
"dev": true
},
"ssr-window": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-4.0.2.tgz",
"integrity": "sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ=="
},
"stack-generator": {
"version": "2.0.10",
"resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.10.tgz",
@@ -9673,17 +9846,17 @@
"dev": true
},
"style-to-js": {
"version": "1.1.16",
"resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.16.tgz",
"integrity": "sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw==",
"version": "1.1.17",
"resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.17.tgz",
"integrity": "sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA==",
"requires": {
"style-to-object": "1.0.8"
"style-to-object": "1.0.9"
}
},
"style-to-object": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz",
"integrity": "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==",
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.9.tgz",
"integrity": "sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw==",
"requires": {
"inline-style-parser": "0.2.4"
}
@@ -9717,12 +9890,9 @@
"dev": true
},
"swiper": {
"version": "9.1.1",
"resolved": "https://registry.npmjs.org/swiper/-/swiper-9.1.1.tgz",
"integrity": "sha512-D1zArOwI6XCXCYBULPA4jTxpqp5SQtvntjinbXNZwXzj6P3KS51zSWuMarCLXq5oRISay4nX+TuShpxz8qhtbw==",
"requires": {
"ssr-window": "^4.0.2"
}
"version": "11.2.8",
"resolved": "https://registry.npmjs.org/swiper/-/swiper-11.2.8.tgz",
"integrity": "sha512-S5FVf6zWynPWooi7pJ7lZhSUe2snTzqLuUzbd5h5PHUOhzgvW0bLKBd2wv0ixn6/5o9vwc/IkQT74CRcLJQzeg=="
},
"tar": {
"version": "6.1.13",
@@ -9852,10 +10022,10 @@
"dev": true
},
"typescript": {
"version": "4.9.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
"dev": true
"version": "5.8.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
"devOptional": true
},
"unified": {
"version": "11.0.5",
@@ -10003,6 +10173,11 @@
}
}
},
"void-elements": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
"integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w=="
},
"wait-for-expect": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/wait-for-expect/-/wait-for-expect-3.0.1.tgz",

View File

@@ -34,6 +34,7 @@
"react-confetti": "^6.4.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.57.0",
"react-i18next": "^15.5.3",
"react-iconly": "^2.2.10",
"react-leaflet": "^4.2.1",
"react-markdown": "^10.1.0",
@@ -42,10 +43,12 @@
"react-router": "^5.3.4",
"react-router-dom": "^5.3.4",
"react-spinners": "^0.17.0",
"react-star-ratings": "^2.3.0",
"react-use": "^17.6.0",
"react-virtuoso": "^4.13.0",
"reselect": "^4.0.0",
"sass": "^1.59.3",
"swiper": "^9.1.1",
"swiper": "^11.2.8",
"use-sound": "^5.0.0",
"zod": "^3.25.56"
},
@@ -59,12 +62,13 @@
"@types/react-dom": "^18.0.11",
"@types/react-router": "^5.1.20",
"@types/react-router-dom": "^5.3.3",
"@types/react-star-ratings": "^2.3.3",
"@vitejs/plugin-react": "^3.1.0",
"husky": "^8.0.3",
"lint-staged": "^13.2.0",
"prettier": "^3.5.3",
"prettier-plugin-sort-json": "^4.1.1",
"typescript": "^4.9.3",
"typescript": "^5.8.3",
"vite": "^4.2.0"
},
"eslintConfig": {

View File

@@ -68,6 +68,11 @@ import MemberProfile from './pages/MemberProfile';
import OrderDetail from './pages/OrderDetail';
import DummyPayPage from './pages/DummyEventPayPage';
import DummyEventPayPage from './pages/DummyEventPayPage';
import PaymentSuccess from './pages/PaymentSuccess';
import PaymentFailed from './pages/PaymentFailed';
import settings from './pages/tabs/carousell_me/settings';
import HotelWelcomeTour from './pages/HotelWelcomeTour';
import HotelServiceWifi from './pages/HotelIntro';
setupIonicReact();
@@ -133,17 +138,23 @@ const IonicApp: React.FC<IonicAppProps> = ({ darkMode, schedule, setIsLoggedIn,
<Route exact={true} path={PATHS.PRIVACY_AGREEMENT} component={PrivacyAgreement} />
{/* Event and profile detail pages */}
<Route exact={true} path="/dummy_pay_page" component={DummyPayPage} />
<Route exact={true} path="/event_detail/:id" component={EventDetail} />
<Route exact={true} path={PATHS.DUMMY_EVENT_PAY_PAGE} component={DummyEventPayPage} />
<Route exact={true} path={PATHS.DUMMY_PAY_PAGE} component={DummyPayPage} />
<Route exact={true} path={PATHS.PAYMENT_SUCCESS} component={PaymentSuccess} />
<Route exact={true} path={PATHS.PAYMENT_FAILED} component={PaymentFailed} />
<Route exact={true} path="/profile/:id" component={MemberProfile} />
{/* component make the ":id" available in the "OrderDetail" */}
<Route exact={true} path="/order_detail/:id" component={OrderDetail} />
<Route exact={true} path="/helloworld" component={Helloworld} />
<Route exact={true} path={PATHS.DUMMY_EVENT_PAY_PAGE} component={DummyEventPayPage} />
<Route path={PATHS.HOTEL_WELCOME_TOUR} component={HotelWelcomeTour} exact={true} />
{/* <Route path={PATHS.HOTEL_SERVICE_INTRO} component={HotelServiceIntro} exact={true} /> */}
{/* tabs/hotel_service_intro */}
<Route
path="/logout"
@@ -153,9 +164,9 @@ const IonicApp: React.FC<IonicAppProps> = ({ darkMode, schedule, setIsLoggedIn,
/>
{/* PartyUser */}
<Route path={PATHS.PARTY_USER_SIGN_IN} component={PartyUserLogin} />
<Route exact={true} path={PATHS.PARTY_USER_SIGN_IN} component={PartyUserLogin} />
<Route exact={true} path={PATHS.NOT_IMPLEMENTED} component={NotImplemented} />
<Route exact={true} path={PATHS.CAROUSELL_ME_SETTINGS} component={settings} />
<Route path="/" component={HomeOrTutorial} exact />
</IonRouterOutlet>

View File

@@ -15,16 +15,19 @@ const PATHS = {
PRIVACY_AGREEMENT: '/privacy_agreement',
SIGN_IN: '/mylogin',
// event detail
getEventDetailPath: (eventId: string) => `/event_detail/${eventId}`,
// Order-related routes
ORDER_DETAIL: '/order_detail/:id',
getOrderDetail: (id: string) => `/order_detail/${id}`,
// Tab navigation routes
TAB_NOT_IMPLEMENTED: '/tabs/not_implemented',
EVENT_LIST: `/tabs/events`,
MESSAGE_LIST: `/tabs/messages`,
EVENT_LIST: '/tabs/events',
MESSAGE_LIST: '/tabs/messages',
NEARBY_LIST: '/tabs/nearby',
ORDERS_LIST: '/tabs/orders',
FAVOURITES_LIST: `/tabs/favourites`,
FAVOURITES_LIST: '/tabs/favourites',
PROFILE: '/tabs/my_profile',
// partyUser
@@ -32,6 +35,9 @@ const PATHS = {
PARTY_USER_SIGN_UP: '/partyUserSignUp',
DUMMY_EVENT_PAY_PAGE: '/DummyEventPayPage',
DUMMY_PAY_PAGE: 'dummy_pay_page',
PAYMENT_SUCCESS: '/payment_success',
PAYMENT_FAILED: '/payment_failed',
//
TABS_DEBUG: '/tabs/debug',
@@ -96,5 +102,17 @@ const PATHS = {
DEMO_SLIDING_PROFILE: '/demo-sliding-profile',
DEMO_STICKY_BOTTOM_SHEET_EXAMPLE: '/demo-sticky-bottom-sheet-example',
DEMO_STORAGE_EXAMPLE: '/demo-storage-example',
//
CAROUSELL_ME: '/tabs/carousell_me',
CAROUSELL_ME_QR: '/tabs/carousell_me/qr_page',
CAROUSELL_ME_SETTINGS: '/carousell_me/settings',
CAROUSELL_ME_INSIGHTS: '/tabs/carousell_me/insights',
CAROUSELL_ME_OFFERS_MADE: '/tabs/carousell_me/OffersMade',
CAROUSELL_ME_MY_PROFILE: '/tabs/carousell_me/my_profile',
//
HOTEL_WELCOME_TOUR: '/hotel_service_intro',
HOTEL_INTRO: '/tabs/hotel_intro',
HOTEL_SERVICE_WIFI: '/tabs/hotel_service_wifi',
};
export default PATHS;

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 12H18" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 18V6" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 439 B

View File

@@ -0,0 +1,10 @@
import React from 'react';
import buttonSvg from './buttonSvg.svg';
function getButtonSvg(): Promise<string> {
return new Promise((res, rej) => {
res(buttonSvg);
});
}
export default getButtonSvg;

View File

@@ -0,0 +1,49 @@
import React from 'react';
import getTestSvg from './getTestSvg';
async function getCategory(): Promise<any> {
let list = [
{ name: 'Following', avatar: '' },
{ name: 'Computers & Tech', avatar: '' },
{ name: "Women's Fashion", avatar: '' },
{ name: "Men's Fashion", avatar: '' },
{ name: 'Beauty & Personal Care', avatar: '' },
{ name: 'Free Items', avatar: '' },
{ name: 'Audio', avatar: '' },
{ name: 'Furniture & Home Living', avatar: '' },
{ name: 'Babies & Kids', avatar: '' },
{ name: 'Health & Nutrition', avatar: '' },
{ name: 'Food & Drinks', avatar: '' },
{ name: 'Tickets & Vouchers', avatar: '' },
{ name: 'Auto Accessories', avatar: '' },
{ name: 'Community', avatar: '' },
{ name: 'Looking For', avatar: '' },
{ name: 'Announcements', avatar: '' },
{ name: 'Services', avatar: '' },
{ name: 'Mobile Phones & Gadgets', avatar: '' },
{ name: 'Property', avatar: '' },
{ name: 'Cars', avatar: '' },
{ name: 'Luxury', avatar: '' },
{ name: 'Video Gaming', avatar: '' },
{ name: 'Photography', avatar: '' },
{ name: 'TV & Home Appliances', avatar: '' },
{ name: 'Hobbies & Toys', avatar: '' },
{ name: 'Sports', avatar: '' },
{ name: 'Equipment', avatar: '' },
{ name: 'Pet Supplies', avatar: '' },
{ name: 'Motorbikes', avatar: '' },
{ name: 'Jobs', avatar: '' },
{ name: 'Preorders', avatar: '' },
{ name: 'Everything Else', avatar: '' },
];
for (var i = 0; i < list.length; i++) {
list[i].avatar = await getTestSvg();
}
return new Promise((res, rej) => {
res(list);
});
}
export default getCategory;

View File

@@ -0,0 +1,95 @@
import React from 'react';
const contentMd = `
全館Wi-Fiをご利用いただけます。無料
■ID: helloworld Life
■Password: 0362751510
LYNKED HOTELでは、
全客室・宴会場の一部に
有線LAN接続によるインターネット
接続環境を開業時より
導入しておりましたが、
さらなる利便性向上を図るため、
このたび、ロビー・客室フロアに無線LAN
アクセスポイントを設置し、
各客室内でもWi-Fi接続による
インターネットを利用できる
環境を構築いたしました。
より快適なWi-Fi接続サービスによる
無料のインターネット接続を
ご利用いただけます。
■ ご利用いただける端末
・LAN / 無線LANWi-Fi規格アダプタ内蔵PC
・WindowsXP以上、Mac OSX以上のOSを搭載したPC
・無線LANWi-Fi規格対応のiOS機器iPhone・iPad等
・無線LANWi-Fi規格のAndroid機器スマートフォン・タブレットPC等
■ Wi-Fi接続サービスの規格・接続
IEEE802.11 n/b/gの規格に準拠しており、同時使用が可能です。
ネットアクセスポイントにつきましては、各ホテルSSIDをフロントにてご案内いたします。
■ 各ホテル内でインターネット接続サービスが可能なエリア
・全客室内有線LAN・Wi-Fi接続
・フロント前ロビーWi-Fi接続
・各宴会場有線LAN接続
■ ご注意
※有線・無線LANを通してインターネット接続サービスを無料でご利用いただけます。
※Wi-Fi接続サービスは、ホテルのSSIDが発出されている場所でご利用になれますが、場所により電波の届かないエリア、もしくは電波が弱くご利用が難しい場合もあります。
※ご利用に際してのセキュリティ設定は、お客様ご自身の責任において行っていただくようにお願いいたします。
※本サービスのご利用・予期せぬ停止や不良が原因となり発生した損失や損害については、ホテルは一切の責任は負いかねますので、予めご了承ください。
※ネット対戦ゲーム、大容量ファイルの送受信など、回線を長時間占有してのご利用は、他のお客様のご迷惑となりますので、ご遠慮ください。
`.trim();
function getContentMarkdown(): Promise<string> {
return new Promise((res, rej) => {
res(contentMd);
});
}
export default getContentMarkdown;

View File

@@ -0,0 +1,76 @@
import React from 'react';
import getUnsplashRandomImage from './getUnsplashRandomImage';
const ContentMd = `幫個忙,睇埋落去先啦....
🈺 視乎難度收費,或者你比個 budget plan 諗下都得
Charge subject to difficulties with the task(s), or bring your budget plan to me...
💁‍♂️ 服務內容
- 代寫程式 ... ( html/javascript/python coding commission)
- 簡易 個人 / 公司網站 / 靜態網站 製作 (static/pwa webpage)
- 網店 / 網購平台製作, 網址 / 域名註冊,網站發佈 (deploy)
- 手機應用程式 (expo/ionic/android)
- 任何自定義 / 量身定做方案, 其他 IT 相關解決方案 (solution / AI)
- Wordpress 公司/個人網頁
- 網上資料搜集 scraping/harvesting/crawing
- source code 想知點解咁寫開聲問,唔明講到你明
- 補習 / 指導
- 如需補習/備課的話,請給我看看所需要課堂資料或者問題,
- 我對你個人資料沒有興趣,你大可以將個人資料屏蔽先 send 比我
- 世界這麼大,我只是想知道你遇到什麽問題,謝謝
- 寫bot (請先 PM 我, 要睇睇目的先答做唔做.... book場/搶飛 唔洗問 😊)
💬 吹水閒偈/諮詢攞下意見免費 😊 (睇心情 / 難度答 😂)
Please DM / PM consultation for free ( But no guaranteed answer... depends... )
👋 髒話說在前面 ( Salutations being said in front ) :
- 一般黎講,我會維持對客人應有嘅禮貌同埋尊重 (a.k.a. 互相尊重, implicatively 講左D乜請自己諗... )
- 同一時間我嘅禮貎都只會展示俾對我有禮貌嘅人睇。
- 我就是我本人,不是中介,由對接到做嘅都係我,有懷疑者不用找我 👋 👋 。
- 我唔係你肚入面條蟲,我唔會知你心入面有乜 requirement ... 最簡單係叫你比份 requirements/pdf 我,如果你覺得比個原始 file 我係好難接受嘅話(前題係當然你可以預先 blur 敏感資料),唔使搵我👋 👋
多謝你睇到喱度,我知我好長氣,若然仲有興趣搵我做野的話,
第一句同我講 “Hi, 寶達邨的豬~”,我會講整個購物體驗應該會對你有利 😊...
完...
🍖 Some demo:
- some site demos:
https://louiscklaw.github.io/work
若果想做 opencv/machine learning 野,可到此 post
https://www.carousell.com.hk/p/1338018892/
🔖 Tags:
#reactjs #nodejs #nextjs #typescript #programming #python #html #css #coding #vue #expo #frontend #backend #laravel #github #bot #vba #docker #opencv #mobile-app #LLM #GPT #huggingface #llama #ollama #debug #figma #ICT #opensource #processing #flow-field #網站 #爬蟲 #scraping #RPA #ABAP #FYP #STEM #project #tkinter #shopping-cart #網頁製作 #公司網站 #網店 #整網頁 #一對一教學 #私補 #私教 #補習 #教材 #代編程 #定制程序代寫 #internship #intern #colab #jupyter #raspberry-pi #arduino #openai-gym #gymnasium #app-inventor #microbit #團購 #賭波 #賭馬 #股票 #六合彩 #港股工具 #股票工具 #求助 #28car #智慧轉型
#switch2 #switch-2 #adidas #airpods-pro-2 #babymonster #celine #chanel #chiikawa #coach #crybaby #dear jane #dior #fujifilm #fujifilm #goyard #hermes #hermes #ipad #iphone #jellycat #labubu #loewe #longchamp #lululemon #lululemon #lv #macbook #minecraft #pokemon #prada #ps4 #ps5 #rolex #samsung #sony #lego #metal-build #yoga #hottoys #riize #roblox #part-time #街馬-2025 #Blackpink演唱會 #淘佳佳 #i-am-gloria
# updated: 2025-06-16
`.trim();
const userJson = {
avatar: getUnsplashRandomImage({ keyword: 'hotel' }),
name: 'louis_coding',
since: 'Joined 4 years ago',
verified: true,
rating: 5.0,
total_comment: 37,
};
const productSample = {
category: { main: 'Services', sub_cat: ['Learning & Enrichment', 'Enrichment & Tuition'] },
avatar: getUnsplashRandomImage({ keyword: 'hotel' }),
title: '#html #css #開發 #指導 ',
price: 30,
content: ContentMd,
user: userJson,
};
function getFreshFinds(): Promise<any> {
return new Promise((res, rej) => {
res([productSample, productSample, productSample, productSample, productSample, productSample]);
});
}
export default getFreshFinds;

View File

@@ -0,0 +1,119 @@
import React from 'react';
const testHtml = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.asscent-color1 { color: #800000 }
.text-deep-grey {color: rgb(0,0,0)}
.text-grey {color: rgb(0,0,0, 0.6)}
.text-smoothing {opacity: 0.8}
h1 { font-size: 1.2rem}
h2 { font-size: 1.1rem}
h3 { font-size: 1rem}
h4 { font-size: 0.8rem}
h5 { font-size: 0.7rem}
h6 { font-size: 0.6rem}
.quote {
background-color: rgba(231, 76, 60, 0.05);
padding: 1rem; border-radius: 5px;
border-left: 5px solid #800000;
width: 90%;
margin: 1rem auto;
line-height:2rem;
}
</style>
</head>
<body style="padding: 0; margin: 0; box-sizing: border-box;" class="text-smoothing">
<div class="text-grey" style="font-size: 0.8rem; text-align: center">
全館Wi-Fiをご利用いただけます。無料
</div>
<div class="quote">
<div>■ ID: hello_user</div>
<div>■ Password: my-best-password</div>
</div>
<h3 class="asscent-color1">HELLOWORLD HOTELでは、</h3>
<p>全客室・宴会場の一部に</p>
<p>有線LAN接続によるインターネット</p>
<p>接続環境を開業時より</p>
<p>導入しておりましたが、</p>
<p>さらなる利便性向上を図るため、</p>
<p>このたび、ロビー・客室フロアに無線LAN</p>
<p>アクセスポイントを設置し、</p>
<p>各客室内でもWi-Fi接続による</p>
<p>インターネットを利用できる</p>
<p>環境を構築いたしました。</p>
<p>より快適なWi-Fi接続サービスによる</p>
<p>無料のインターネット接続を</p>
<p>ご利用いただけます。</p>
<h4 class="asscent-color1">■ ご利用いただける端末</h4>
<p>・LAN / 無線LANWi-Fi規格アダプタ内蔵PC</p>
<p>・WindowsXP以上、Mac OSX以上のOSを搭載したPC</p>
<p>・無線LANWi-Fi規格対応のiOS機器iPhone・iPad等</p>
<p>・無線LANWi-Fi規格のAndroid機器スマートフォン・タブレットPC等</p>
<h4 class="asscent-color1">■ Wi-Fi接続サービスの規格・接続</h4>
<p>IEEE802.11 n/b/gの規格に準拠しており、同時使用が可能です。</p>
<p>ネットアクセスポイントにつきましては、各ホテルSSIDをフロントにてご案内いたします。</p>
<h4 class="asscent-color1">■ 各ホテル内でインターネット接続サービスが可能なエリア</h4>
<p>・全客室内有線LAN・Wi-Fi接続</p>
<p>・フロント前ロビーWi-Fi接続</p>
<p>・各宴会場有線LAN接続</p>
<h4 class="asscent-color1">■ ご注意</h4>
<p>※有線・無線LANを通してインターネット接続サービスを無料でご利用いただけます。</p>
<p>※Wi-Fi接続サービスは、ホテルのSSIDが発出されている場所でご利用になれますが、場所により電波の届かないエリア、もしくは電波が弱くご利用が難しい場合もあります。</p>
<p>※ご利用に際してのセキュリティ設定は、お客様ご自身の責任において行っていただくようにお願いいたします。</p>
<p>※本サービスのご利用・予期せぬ停止や不良が原因となり発生した損失や損害については、ホテルは一切の責任は負いかねますので、予めご了承ください。</p>
<p>※ネット対戦ゲーム、大容量ファイルの送受信など、回線を長時間占有してのご利用は、他のお客様のご迷惑となりますので、ご遠慮ください。</p>
<h1>待進變果沒致友環健問水法代人苦天。📅📍🎻</h1>
<h2>待進變果沒致友環健問水法代人苦天。📅📍🎻</h2>
<h3>待進變果沒致友環健問水法代人苦天。📅📍🎻</h3>
<h4>待進變果沒致友環健問水法代人苦天。📅📍🎻</h4>
<h5>待進變果沒致友環健問水法代人苦天。📅📍🎻</h5>
<h6>待進變果沒致友環健問水法代人苦天。📅📍🎻</h6>
<p>
業立臺四即文善公作有往,等怕準命小電個。
査今聞光洋後化外財強主職。
🌲🔯🍣💵 🐪👫🐈📅📍🎻💼 🐣🍖🐻📩🍨. 🎇👬💨
</p>
<h1>Lorem Ipsum: Usage, Common examples, Translation, Variants and technical information📅📍🎻</h1>
<h2>Lorem Ipsum: Usage, Common examples, Translation, Variants and technical information📅📍🎻</h2>
<h3>Lorem Ipsum: Usage, Common examples, Translation, Variants and technical information📅📍🎻</h3>
<h4>Lorem Ipsum: Usage, Common examples, Translation, Variants and technical information📅📍🎻</h4>
<h5>Lorem Ipsum: Usage, Common examples, Translation, Variants and technical information📅📍🎻</h5>
<h6>Lorem Ipsum: Usage, Common examples, Translation, Variants and technical information📅📍🎻</h6>
<p>
Lorem Ipsum: Usage, Common examples, Translation, Variants and technical information
Essay: Lorem Ipsum--when, and when not to use it
🌲🔯🍣💵 🐪👫🐈📅📍🎻💼 🐣🍖🐻📩🍨. 🎇👬💨
</p>
<p>📤🏮👀🍮 💃👪👦🌀🌶📈 🍵📊💓🐧🎢👃 🍕🌛🔎🔋🎣🍃 🎡👩📔🍈💭 🎣👅🔽📟📑💋</p>
</body>
</html>`.trim();
function getHtmlContent(): Promise<string> {
return new Promise((res, rej) => {
res(testHtml);
});
}
export default getHtmlContent;

View File

@@ -0,0 +1,76 @@
import React from 'react';
import getUnsplashRandomImage from './getUnsplashRandomImage';
const ContentMd = `幫個忙,睇埋落去先啦....
🈺 視乎難度收費,或者你比個 budget plan 諗下都得
Charge subject to difficulties with the task(s), or bring your budget plan to me...
💁‍♂️ 服務內容
- 代寫程式 ... ( html/javascript/python coding commission)
- 簡易 個人 / 公司網站 / 靜態網站 製作 (static/pwa webpage)
- 網店 / 網購平台製作, 網址 / 域名註冊,網站發佈 (deploy)
- 手機應用程式 (expo/ionic/android)
- 任何自定義 / 量身定做方案, 其他 IT 相關解決方案 (solution / AI)
- Wordpress 公司/個人網頁
- 網上資料搜集 scraping/harvesting/crawing
- source code 想知點解咁寫開聲問,唔明講到你明
- 補習 / 指導
- 如需補習/備課的話,請給我看看所需要課堂資料或者問題,
- 我對你個人資料沒有興趣,你大可以將個人資料屏蔽先 send 比我
- 世界這麼大,我只是想知道你遇到什麽問題,謝謝
- 寫bot (請先 PM 我, 要睇睇目的先答做唔做.... book場/搶飛 唔洗問 😊)
💬 吹水閒偈/諮詢攞下意見免費 😊 (睇心情 / 難度答 😂)
Please DM / PM consultation for free ( But no guaranteed answer... depends... )
👋 髒話說在前面 ( Salutations being said in front ) :
- 一般黎講,我會維持對客人應有嘅禮貌同埋尊重 (a.k.a. 互相尊重, implicatively 講左D乜請自己諗... )
- 同一時間我嘅禮貎都只會展示俾對我有禮貌嘅人睇。
- 我就是我本人,不是中介,由對接到做嘅都係我,有懷疑者不用找我 👋 👋 。
- 我唔係你肚入面條蟲,我唔會知你心入面有乜 requirement ... 最簡單係叫你比份 requirements/pdf 我,如果你覺得比個原始 file 我係好難接受嘅話(前題係當然你可以預先 blur 敏感資料),唔使搵我👋 👋
多謝你睇到喱度,我知我好長氣,若然仲有興趣搵我做野的話,
第一句同我講 “Hi, 寶達邨的豬~”,我會講整個購物體驗應該會對你有利 😊...
完...
🍖 Some demo:
- some site demos:
https://louiscklaw.github.io/work
若果想做 opencv/machine learning 野,可到此 post
https://www.carousell.com.hk/p/1338018892/
🔖 Tags:
#reactjs #nodejs #nextjs #typescript #programming #python #html #css #coding #vue #expo #frontend #backend #laravel #github #bot #vba #docker #opencv #mobile-app #LLM #GPT #huggingface #llama #ollama #debug #figma #ICT #opensource #processing #flow-field #網站 #爬蟲 #scraping #RPA #ABAP #FYP #STEM #project #tkinter #shopping-cart #網頁製作 #公司網站 #網店 #整網頁 #一對一教學 #私補 #私教 #補習 #教材 #代編程 #定制程序代寫 #internship #intern #colab #jupyter #raspberry-pi #arduino #openai-gym #gymnasium #app-inventor #microbit #團購 #賭波 #賭馬 #股票 #六合彩 #港股工具 #股票工具 #求助 #28car #智慧轉型
#switch2 #switch-2 #adidas #airpods-pro-2 #babymonster #celine #chanel #chiikawa #coach #crybaby #dear jane #dior #fujifilm #fujifilm #goyard #hermes #hermes #ipad #iphone #jellycat #labubu #loewe #longchamp #lululemon #lululemon #lv #macbook #minecraft #pokemon #prada #ps4 #ps5 #rolex #samsung #sony #lego #metal-build #yoga #hottoys #riize #roblox #part-time #街馬-2025 #Blackpink演唱會 #淘佳佳 #i-am-gloria
# updated: 2025-06-16
`.trim();
const userJson = {
avatar: getUnsplashRandomImage({ keyword: 'hotel' }),
name: 'louis_coding',
since: 'Joined 4 years ago',
verified: true,
rating: 5.0,
total_comment: 37,
};
const productSample = {
category: { main: 'Services', sub_cat: ['Learning & Enrichment', 'Enrichment & Tuition'] },
avatar: getUnsplashRandomImage({ keyword: 'hotel' }),
title: '#html #css #開發 #指導 ',
price: 30,
content: ContentMd,
user: userJson,
};
function getProductList(): Promise<any> {
return new Promise((res, rej) => {
res([productSample, productSample, productSample, productSample, productSample, productSample]);
});
}
export default getProductList;

View File

@@ -0,0 +1,14 @@
import React from 'react';
function getSegments(): Promise<any> {
return new Promise((res, rej) => {
res([
{ name: 'Top picks', slug: 'top-picks' },
{ name: 'Free items', slug: 'free-items' },
{ name: 'Following', slug: 'following' },
{ name: 'Nearby', slug: 'nearby' },
]);
});
}
export default getSegments;

View File

@@ -0,0 +1,33 @@
import React from 'react';
function getSuggestedCategory(): Promise<string[]> {
return new Promise((res, rej) => {
res([
'代做',
'cisco',
'm1',
'pro',
'顯示器支架',
'kfc',
'nas',
'la',
'prairie',
'vr',
'代做',
'cisco',
'm1',
'pro',
'顯示器支架',
'kfc',
'nas',
'la',
'prairie',
'vr',
'顯示器支架',
'kfc',
'nas',
]);
});
}
export default getSuggestedCategory;

View File

@@ -0,0 +1,97 @@
import React from 'react';
import airConditioningCoolingHeatTemperatureSvgrepoComSvg from './svgs/air-conditioning-cooling-heat-temperature-svgrepo-com.svg';
import alertAttentionCautionDangerousWarningSvgrepoComSvg from './svgs/alert-attention-caution-dangerous-warning-svgrepo-com.svg';
import alertBellCallMessageSignSvgrepoComSvg from './svgs/alert-bell-call-message-sign-svgrepo-com.svg';
import assistanceBusinessPersonReceptionServiceSvgrepoComSvg from './svgs/assistance-business-person-reception-service-svgrepo-com.svg';
import bagBaggageLuggageSuitcaseTravelSvgrepoComSvg from './svgs/bag-baggage-luggage-suitcase-travel-svgrepo-com.svg';
import baggageBellhopHotelServiceWaiterSvgrepoComSvg from './svgs/baggage-bellhop-hotel-service-waiter-svgrepo-com.svg';
import bagHolidayJourneySuitcaseVacationSvgrepoComSvg from './svgs/bag-holiday-journey-suitcase-vacation-svgrepo-com.svg';
import bankingFinancialMoneyPaymentTransactionSvgrepoComSvg from './svgs/banking-financial-money-payment-transaction-svgrepo-com.svg';
import barCafeChairClubStoolSvgrepoComSvg from './svgs/bar-cafe-chair-club-stool-svgrepo-com.svg';
import bathBathroomCottonTextileTowelSvgrepoComSvg from './svgs/bath-bathroom-cotton-textile-towel-svgrepo-com.svg';
import bathroomBathtubBubbleFoamWaterSvgrepoComSvg from './svgs/bathroom-bathtub-bubble-foam-water-svgrepo-com.svg';
import bathroomFaucetRoomSinkWashSvgrepoComSvg from './svgs/bathroom-faucet-room-sink-wash-svgrepo-com.svg';
import bedFurnitureInteriorPillowRest2SvgrepoComSvg from './svgs/bed-furniture-interior-pillow-rest-2-svgrepo-com.svg';
import bedFurnitureInteriorPillowRest3SvgrepoComSvg from './svgs/bed-furniture-interior-pillow-rest-3-svgrepo-com.svg';
import bedFurnitureInteriorPillowRestSvgrepoComSvg from './svgs/bed-furniture-interior-pillow-rest-svgrepo-com.svg';
import bookCatalogDocumentGuidebookInstructionSvgrepoComSvg from './svgs/book-catalog-document-guidebook-instruction-svgrepo-com.svg';
import businessFinanceMoneySavingWalletSvgrepoComSvg from './svgs/business-finance-money-saving-wallet-svgrepo-com.svg';
import cafeCardFoodMenuVintageSvgrepoComSvg from './svgs/cafe-card-food-menu-vintage-svgrepo-com.svg';
import cafeCupDrinkMugTeaSvgrepoComSvg from './svgs/cafe-cup-drink-mug-tea-svgrepo-com.svg';
import calendarDateDayMonthTimeSvgrepoComSvg from './svgs/calendar-date-day-month-time-svgrepo-com.svg';
import cappuccinoCoffeeCupDrinkEspresso2SvgrepoComSvg from './svgs/cappuccino-coffee-cup-drink-espresso-2-svgrepo-com.svg';
import cappuccinoCoffeeCupDrinkEspressoSvgrepoComSvg from './svgs/cappuccino-coffee-cup-drink-espresso-svgrepo-com.svg';
import cardCreditCurrencyFinanceMoneySvgrepoComSvg from './svgs/card-credit-currency-finance-money-svgrepo-com.svg';
import cardDoorKeyLockSecuritySvgrepoComSvg from './svgs/card-door-key-lock-security-svgrepo-com.svg';
import chairComfortableDecorationGardenTerraceSvgrepoComSvg from './svgs/chair-comfortable-decoration-garden-terrace-svgrepo-com.svg';
import cleanClothingLaundryWashingWindSvgrepoComSvg from './svgs/clean-clothing-laundry-washing-wind-svgrepo-com.svg';
import comfortableFabricFootwearShoeSlipperSvgrepoComSvg from './svgs/comfortable-fabric-footwear-shoe-slipper-svgrepo-com.svg';
import couponEntertainmentEventPaperTicketSvgrepoComSvg from './svgs/coupon-entertainment-event-paper-ticket-svgrepo-com.svg';
import doorElevatorEntranceFloorLiftSvgrepoComSvg from './svgs/door-elevator-entrance-floor-lift-svgrepo-com.svg';
import doorEnterEntryExitOpenSvgrepoComSvg from './svgs/door-enter-entry-exit-open-svgrepo-com.svg';
import doorEntranceHandleKeySecuritySvgrepoComSvg from './svgs/door-entrance-handle-key-security-svgrepo-com.svg';
import doorKeyLockRoomSecuritySvgrepoComSvg from './svgs/door-key-lock-room-security-svgrepo-com.svg';
import electronicInternetScreenTechnologyTelevisionSvgrepoComSvg from './svgs/electronic-internet-screen-technology-television-svgrepo-com.svg';
import holidayHotelJourneyServiceTravel2SvgrepoComSvg from './svgs/holiday-hotel-journey-service-travel-2-svgrepo-com.svg';
import holidayHotelJourneyServiceTravelSvgrepoComSvg from './svgs/holiday-hotel-journey-service-travel-svgrepo-com.svg';
import holidayHotelMotelSignTravelSvgrepoComSvg from './svgs/holiday-hotel-motel-sign-travel-svgrepo-com.svg';
import holidayJourneyLuggageSuitcaseVacation2SvgrepoComSvg from './svgs/holiday-journey-luggage-suitcase-vacation-2-svgrepo-com.svg';
import hotelLocationMapPinTravelSvgrepoComSvg from './svgs/hotel-location-map-pin-travel-svgrepo-com.svg';
const svgList = [
airConditioningCoolingHeatTemperatureSvgrepoComSvg,
alertAttentionCautionDangerousWarningSvgrepoComSvg,
alertBellCallMessageSignSvgrepoComSvg,
assistanceBusinessPersonReceptionServiceSvgrepoComSvg,
bagBaggageLuggageSuitcaseTravelSvgrepoComSvg,
baggageBellhopHotelServiceWaiterSvgrepoComSvg,
bagHolidayJourneySuitcaseVacationSvgrepoComSvg,
bankingFinancialMoneyPaymentTransactionSvgrepoComSvg,
barCafeChairClubStoolSvgrepoComSvg,
bathBathroomCottonTextileTowelSvgrepoComSvg,
bathroomBathtubBubbleFoamWaterSvgrepoComSvg,
bathroomFaucetRoomSinkWashSvgrepoComSvg,
bedFurnitureInteriorPillowRest2SvgrepoComSvg,
bedFurnitureInteriorPillowRest3SvgrepoComSvg,
bedFurnitureInteriorPillowRestSvgrepoComSvg,
bookCatalogDocumentGuidebookInstructionSvgrepoComSvg,
businessFinanceMoneySavingWalletSvgrepoComSvg,
cafeCardFoodMenuVintageSvgrepoComSvg,
cafeCupDrinkMugTeaSvgrepoComSvg,
calendarDateDayMonthTimeSvgrepoComSvg,
cappuccinoCoffeeCupDrinkEspresso2SvgrepoComSvg,
cappuccinoCoffeeCupDrinkEspressoSvgrepoComSvg,
cardCreditCurrencyFinanceMoneySvgrepoComSvg,
cardDoorKeyLockSecuritySvgrepoComSvg,
chairComfortableDecorationGardenTerraceSvgrepoComSvg,
cleanClothingLaundryWashingWindSvgrepoComSvg,
comfortableFabricFootwearShoeSlipperSvgrepoComSvg,
couponEntertainmentEventPaperTicketSvgrepoComSvg,
doorElevatorEntranceFloorLiftSvgrepoComSvg,
doorEnterEntryExitOpenSvgrepoComSvg,
doorEntranceHandleKeySecuritySvgrepoComSvg,
doorKeyLockRoomSecuritySvgrepoComSvg,
electronicInternetScreenTechnologyTelevisionSvgrepoComSvg,
holidayHotelJourneyServiceTravel2SvgrepoComSvg,
holidayHotelJourneyServiceTravelSvgrepoComSvg,
holidayHotelMotelSignTravelSvgrepoComSvg,
holidayJourneyLuggageSuitcaseVacation2SvgrepoComSvg,
hotelLocationMapPinTravelSvgrepoComSvg,
];
function getRandomInt(max: number) {
return Math.floor(Math.random() * max);
}
function getTestSvg(): Promise<string> {
let { length } = svgList;
let randomIdx = getRandomInt(length - 1);
console.log({ findme: svgList[randomIdx] });
return new Promise((res, rej) => {
res(svgList[randomIdx]);
});
}
export default getTestSvg;

View File

@@ -0,0 +1,38 @@
import React from 'react';
import getUnsplashRandomImage from './getUnsplashRandomImage';
const ContentMd = `helloworld `.trim();
const userJson = {
avatar: getUnsplashRandomImage({ keyword: 'hotel' }),
name: 'louis_coding',
since: 'Joined 4 years ago',
verified: true,
rating: 5.0,
total_comment: 37,
};
const productSample = {
category: { main: 'Services', sub_cat: ['Learning & Enrichment', 'Enrichment & Tuition'] },
avatar: getUnsplashRandomImage({ keyword: 'hotel' }),
title: '#html #css #開發 #指導 ',
price: 30,
content: ContentMd,
user: userJson,
};
function getTopPicks(): Promise<any> {
return new Promise((res, rej) => {
res([
productSample,
productSample,
productSample,
productSample,
productSample,
productSample,
productSample,
]);
});
}
export default getTopPicks;

View File

@@ -0,0 +1,60 @@
import React from 'react';
function getTopSearches(): Promise<string[]> {
return new Promise((res, rej) => {
res([
'blackpink',
'ps5',
'blackpink 演唱會',
'chanel',
'iphone',
'陳奕迅演唱會',
'hermes',
'海港城coupon',
'利是封',
'ipad',
'apple watch',
'dior',
'celine',
'迪士尼門票',
'lv',
'nike',
'張敬軒',
'gucci',
'lego',
'ps4',
'loewe',
'casetify',
'單車',
'eason 演唱會',
'rolex',
'slam dunk',
'airpods pro',
'coach',
'電視',
'bearbrick',
'雪櫃',
'mc',
'prada',
'samsung',
'dyson',
'burberry',
'張敬軒演唱會',
'pokemon',
'ikea',
'linabell',
'dunk low',
'陳奕迅',
'balenciaga',
'梳化',
'mirror',
'sony',
'麻雀',
'tory burch',
'marshall',
'行李箱',
]);
});
}
export default getTopSearches;

View File

@@ -0,0 +1,11 @@
import React from 'react';
function getRandomInt(max: number) {
return Math.floor(Math.random() * max);
}
function getUnsplashRandomImage({ keyword }: { keyword: string }) {
return `https://media.karousell.com/media/photos/profiles/2025/02/05/louis_coding_1738774979_f1598e0b.jpg`;
}
export default getUnsplashRandomImage;

View File

@@ -0,0 +1,76 @@
import React from 'react';
import getUnsplashRandomImage from './getUnsplashRandomImage';
const ContentMd = `幫個忙,睇埋落去先啦....
🈺 視乎難度收費,或者你比個 budget plan 諗下都得
Charge subject to difficulties with the task(s), or bring your budget plan to me...
💁‍♂️ 服務內容
- 代寫程式 ... ( html/javascript/python coding commission)
- 簡易 個人 / 公司網站 / 靜態網站 製作 (static/pwa webpage)
- 網店 / 網購平台製作, 網址 / 域名註冊,網站發佈 (deploy)
- 手機應用程式 (expo/ionic/android)
- 任何自定義 / 量身定做方案, 其他 IT 相關解決方案 (solution / AI)
- Wordpress 公司/個人網頁
- 網上資料搜集 scraping/harvesting/crawing
- source code 想知點解咁寫開聲問,唔明講到你明
- 補習 / 指導
- 如需補習/備課的話,請給我看看所需要課堂資料或者問題,
- 我對你個人資料沒有興趣,你大可以將個人資料屏蔽先 send 比我
- 世界這麼大,我只是想知道你遇到什麽問題,謝謝
- 寫bot (請先 PM 我, 要睇睇目的先答做唔做.... book場/搶飛 唔洗問 😊)
💬 吹水閒偈/諮詢攞下意見免費 😊 (睇心情 / 難度答 😂)
Please DM / PM consultation for free ( But no guaranteed answer... depends... )
👋 髒話說在前面 ( Salutations being said in front ) :
- 一般黎講,我會維持對客人應有嘅禮貌同埋尊重 (a.k.a. 互相尊重, implicatively 講左D乜請自己諗... )
- 同一時間我嘅禮貎都只會展示俾對我有禮貌嘅人睇。
- 我就是我本人,不是中介,由對接到做嘅都係我,有懷疑者不用找我 👋 👋 。
- 我唔係你肚入面條蟲,我唔會知你心入面有乜 requirement ... 最簡單係叫你比份 requirements/pdf 我,如果你覺得比個原始 file 我係好難接受嘅話(前題係當然你可以預先 blur 敏感資料),唔使搵我👋 👋
多謝你睇到喱度,我知我好長氣,若然仲有興趣搵我做野的話,
第一句同我講 “Hi, 寶達邨的豬~”,我會講整個購物體驗應該會對你有利 😊...
完...
🍖 Some demo:
- some site demos:
https://louiscklaw.github.io/work
若果想做 opencv/machine learning 野,可到此 post
https://www.carousell.com.hk/p/1338018892/
🔖 Tags:
#reactjs #nodejs #nextjs #typescript #programming #python #html #css #coding #vue #expo #frontend #backend #laravel #github #bot #vba #docker #opencv #mobile-app #LLM #GPT #huggingface #llama #ollama #debug #figma #ICT #opensource #processing #flow-field #網站 #爬蟲 #scraping #RPA #ABAP #FYP #STEM #project #tkinter #shopping-cart #網頁製作 #公司網站 #網店 #整網頁 #一對一教學 #私補 #私教 #補習 #教材 #代編程 #定制程序代寫 #internship #intern #colab #jupyter #raspberry-pi #arduino #openai-gym #gymnasium #app-inventor #microbit #團購 #賭波 #賭馬 #股票 #六合彩 #港股工具 #股票工具 #求助 #28car #智慧轉型
#switch2 #switch-2 #adidas #airpods-pro-2 #babymonster #celine #chanel #chiikawa #coach #crybaby #dear jane #dior #fujifilm #fujifilm #goyard #hermes #hermes #ipad #iphone #jellycat #labubu #loewe #longchamp #lululemon #lululemon #lv #macbook #minecraft #pokemon #prada #ps4 #ps5 #rolex #samsung #sony #lego #metal-build #yoga #hottoys #riize #roblox #part-time #街馬-2025 #Blackpink演唱會 #淘佳佳 #i-am-gloria
# updated: 2025-06-16
`.trim();
const userJson = {
avatar: getUnsplashRandomImage({ keyword: 'hotel' }),
name: 'louis_coding',
since: 'Joined 4 years ago',
verified: true,
rating: 5.0,
total_comment: 37,
};
const productSample = {
category: { main: 'Services', sub_cat: ['Learning & Enrichment', 'Enrichment & Tuition'] },
avatar: getUnsplashRandomImage({ keyword: 'hotel' }),
title: '#html #css #開發 #指導 ',
price: 30,
content: ContentMd,
user: userJson,
};
function getYourDailyPicks(): Promise<any> {
return new Promise((res, rej) => {
res([productSample, productSample, productSample, productSample, productSample, productSample]);
});
}
export default getYourDailyPicks;

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#ffd599;}.cls-2{fill:#6d6daa;}.cls-3{fill:#c9c1f5;}.cls-4{fill:#eef5fd;}</style></defs><title/><rect class="cls-1" height="20" rx="2" ry="2" width="28" x="2" y="6"/><path class="cls-2" d="M28,27H4a3,3,0,0,1-3-3V8A3,3,0,0,1,4,5H28a3,3,0,0,1,3,3V24A3,3,0,0,1,28,27ZM4,7A1,1,0,0,0,3,8V24a1,1,0,0,0,1,1H28a1,1,0,0,0,1-1V8a1,1,0,0,0-1-1Z"/><path class="cls-3" d="M8,20H24a2,2,0,0,1,2,2v4a0,0,0,0,1,0,0H6a0,0,0,0,1,0,0V22A2,2,0,0,1,8,20Z"/><path class="cls-2" d="M26,27H6a1,1,0,0,1-1-1V22a3,3,0,0,1,3-3H24a3,3,0,0,1,3,3v4A1,1,0,0,1,26,27ZM7,25H25V22a1,1,0,0,0-1-1H8a1,1,0,0,0-1,1Z"/><rect class="cls-4" height="4" rx="2" ry="2" width="10" x="16" y="10"/><path class="cls-2" d="M24,15H18a3,3,0,0,1,0-6h6a3,3,0,0,1,0,6Zm-6-4a1,1,0,0,0,0,2h6a1,1,0,0,0,0-2Z"/><path class="cls-2" d="M21,15a1,1,0,0,1-1-1V10a1,1,0,0,1,2,0v4A1,1,0,0,1,21,15Z"/></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#ffd599;}.cls-2{fill:#6d6daa;}.cls-3{fill:#eef5fd;}</style></defs><title/><polygon class="cls-1" points="30 30 25 30 24 26 8 26 7 30 2 30 6 2 26 2 30 30"/><path class="cls-2" d="M30,31H25a1,1,0,0,1-1-.76L23.22,27H8.78L8,30.24A1,1,0,0,1,7,31H2a1,1,0,0,1-.76-.34,1,1,0,0,1-.23-.8l4-28A1,1,0,0,1,6,1H26a1,1,0,0,1,1,.86l4,28a1,1,0,0,1-.23.8A1,1,0,0,1,30,31Zm-4.22-2h3.07L25.13,3H6.87L3.15,29H6.22L7,25.76A1,1,0,0,1,8,25H24a1,1,0,0,1,1,.76Z"/><circle class="cls-3" cx="16" cy="14" r="6"/><path class="cls-2" d="M16,21a7,7,0,1,1,7-7A7,7,0,0,1,16,21ZM16,9a5,5,0,1,0,5,5A5,5,0,0,0,16,9Z"/><path class="cls-2" d="M12,19a1,1,0,0,1-.71-.29,1,1,0,0,1,0-1.42l8.06-8.06a1,1,0,1,1,1.42,1.42l-8.06,8.06A1,1,0,0,1,12,19Z"/></svg>

After

Width:  |  Height:  |  Size: 941 B

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#798bc6;}.cls-2{fill:#6d6daa;}.cls-3{fill:#d6b5b0;}.cls-4{fill:#ff9797;}.cls-5{fill:#ffc661;}</style></defs><title/><rect class="cls-1" height="10" width="4" x="14" y="6"/><path class="cls-2" d="M18,17H14a1,1,0,0,1-1-1V6a1,1,0,0,1,1-1h4a1,1,0,0,1,1,1V16A1,1,0,0,1,18,17Zm-3-2h2V7H15Z"/><rect class="cls-3" height="4" width="28" x="2" y="26"/><path class="cls-2" d="M30,31H2a1,1,0,0,1-1-1V26a1,1,0,0,1,1-1H30a1,1,0,0,1,1,1v4A1,1,0,0,1,30,31ZM3,29H29V27H3Z"/><path class="cls-4" d="M16,10h0A12,12,0,0,1,28,22v4a0,0,0,0,1,0,0H4a0,0,0,0,1,0,0V22A12,12,0,0,1,16,10Z"/><path class="cls-2" d="M28,27H4a1,1,0,0,1-1-1V22a13,13,0,0,1,26,0v4A1,1,0,0,1,28,27ZM5,25H27V22A11,11,0,0,0,5,22Z"/><rect class="cls-5" height="4" width="10" x="11" y="2"/><path class="cls-2" d="M21,7H11a1,1,0,0,1-1-1V2a1,1,0,0,1,1-1H21a1,1,0,0,1,1,1V6A1,1,0,0,1,21,7ZM12,5h8V3H12Z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#eef5fd;}.cls-2{fill:#6d6daa;}.cls-3{fill:#d6b5b0;}.cls-4{fill:#ff9797;}.cls-5{fill:#f4dab7;}</style></defs><title/><path class="cls-1" d="M20,20H12a6,6,0,0,0-6,6v4H26V26A6,6,0,0,0,20,20Z"/><path class="cls-2" d="M26,31H6a1,1,0,0,1-1-1V26a7,7,0,0,1,7-7h8a7,7,0,0,1,7,7v4A1,1,0,0,1,26,31ZM7,29H25V26a5,5,0,0,0-5-5H12a5,5,0,0,0-5,5Z"/><path class="cls-3" d="M16,2h0a7,7,0,0,1,7,7v8.2A2.8,2.8,0,0,1,20.2,20H11.8A2.8,2.8,0,0,1,9,17.2V9a7,7,0,0,1,7-7Z"/><path class="cls-2" d="M20.2,21H11.8A3.8,3.8,0,0,1,8,17.2V9A8,8,0,0,1,24,9v8.2A3.8,3.8,0,0,1,20.2,21ZM16,3a6,6,0,0,0-6,6v8.2A1.81,1.81,0,0,0,11.8,19h8.4A1.81,1.81,0,0,0,22,17.2V9A6,6,0,0,0,16,3Z"/><path class="cls-4" d="M20,20H19l-3,2-2,2.15V30H26V26A6,6,0,0,0,20,20Z"/><path class="cls-2" d="M26,31H14a1,1,0,0,1-1-1V24.16a1,1,0,0,1,.27-.68l2-2.16.18-.15,3-2A1,1,0,0,1,19,19h1a7,7,0,0,1,7,7v4A1,1,0,0,1,26,31ZM15,29H25V26a5,5,0,0,0-5-5h-.7l-2.65,1.77L15,24.55Z"/><polygon class="cls-5" points="13 12.82 13 20 16 22 19 20 19 12.82 13 12.82"/><path class="cls-2" d="M16,23a1,1,0,0,1-.55-.16l-3-2A1,1,0,0,1,12,20V12.82a1,1,0,0,1,1-1h6a1,1,0,0,1,1,1V20a1,1,0,0,1-.45.84l-3,2A1,1,0,0,1,16,23Zm-2-3.53,2,1.33,2-1.33V13.82H14Z"/><path class="cls-2" d="M17,27a1,1,0,0,1-1-1V25a1,1,0,0,1,2,0v1A1,1,0,0,1,17,27Z"/><rect class="cls-5" height="4" rx="2" ry="2" width="16" x="8" y="9.42"/><path class="cls-2" d="M22,14.42H10a3,3,0,0,1,0-6H22a3,3,0,0,1,0,6Zm-12-4a1,1,0,0,0,0,2H22a1,1,0,0,0,0-2Z"/><path class="cls-5" d="M13.14,5.19h5.72A2.64,2.64,0,0,1,21.5,7.83V12a5.24,5.24,0,0,1-5.24,5.24h-.51A5.24,5.24,0,0,1,10.5,12V7.83A2.64,2.64,0,0,1,13.14,5.19Z"/><path class="cls-2" d="M16.26,18.19h-.52A6.25,6.25,0,0,1,9.5,12V7.83a3.65,3.65,0,0,1,3.64-3.64h5.72A3.65,3.65,0,0,1,22.5,7.83V12A6.25,6.25,0,0,1,16.26,18.19Zm-3.12-12A1.64,1.64,0,0,0,11.5,7.83V12a4.24,4.24,0,0,0,4.24,4.24h.52A4.24,4.24,0,0,0,20.5,12V7.83a1.64,1.64,0,0,0-1.64-1.64Z"/><path class="cls-3" d="M22.7,7a7,7,0,0,0-9.12-4.55,8.66,8.66,0,0,0,2.65,3.21A7.85,7.85,0,0,0,20.9,7.21,7.65,7.65,0,0,0,22.7,7Z"/><path class="cls-2" d="M20.9,8.21a8.89,8.89,0,0,1-5.27-1.75,9.72,9.72,0,0,1-3-3.59,1,1,0,0,1,0-.81,1,1,0,0,1,.58-.56A8,8,0,0,1,23.66,6.7,1,1,0,0,1,22.94,8,8.5,8.5,0,0,1,20.9,8.21ZM15.11,3.07a6.87,6.87,0,0,0,1.71,1.77A6.82,6.82,0,0,0,21.3,6.2,6.05,6.05,0,0,0,15.11,3.07Z"/><path class="cls-3" d="M16,2A7,7,0,0,0,9,8.31a8.11,8.11,0,0,0,1.21.09,8,8,0,0,0,6-2.75,8.84,8.84,0,0,0,1.85-3.33A6.76,6.76,0,0,0,16,2Z"/><path class="cls-2" d="M10.24,9.4a8.89,8.89,0,0,1-1.36-.1A1,1,0,0,1,8,8.21,8,8,0,0,1,18.38,1.36,1,1,0,0,1,19,2.61,10,10,0,0,1,17,6.32,8.89,8.89,0,0,1,10.24,9.4Zm0-2A6.78,6.78,0,0,0,15.48,5,8.06,8.06,0,0,0,16.74,3c-.24,0-.49,0-.74,0A6,6,0,0,0,10.21,7.4Z"/></svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#6d6daa;}.cls-2{fill:#d6b5b0;}.cls-3{fill:#ffd599;}.cls-4{fill:#ff9797;}.cls-5{fill:#91e085;}</style></defs><title/><path class="cls-1" d="M30,27H8a1,1,0,0,1-1-.88L4.12,3H2A1,1,0,0,1,2,1H5a1,1,0,0,1,1,.88L8.88,25H30a1,1,0,0,1,0,2Z"/><circle class="cls-2" cx="27" cy="28" r="2"/><path class="cls-1" d="M27,31a3,3,0,1,1,3-3A3,3,0,0,1,27,31Zm0-4a1,1,0,1,0,1,1A1,1,0,0,0,27,27Z"/><circle class="cls-2" cx="12" cy="28" r="2"/><path class="cls-1" d="M12,31a3,3,0,1,1,3-3A3,3,0,0,1,12,31Zm0-4a1,1,0,1,0,1,1A1,1,0,0,0,12,27Z"/><rect class="cls-3" height="20" width="20" x="10" y="6"/><path class="cls-1" d="M30,27H10a1,1,0,0,1-1-1V6a1,1,0,0,1,1-1H30a1,1,0,0,1,1,1V26A1,1,0,0,1,30,27ZM11,25H29V7H11Z"/><rect class="cls-4" height="12" width="12" x="14" y="10"/><path class="cls-1" d="M26,23H14a1,1,0,0,1-1-1V10a1,1,0,0,1,1-1H26a1,1,0,0,1,1,1V22A1,1,0,0,1,26,23ZM15,21H25V11H15Z"/><rect class="cls-5" height="12" width="4" x="18" y="10"/><path class="cls-1" d="M22,23H18a1,1,0,0,1-1-1V10a1,1,0,0,1,1-1h4a1,1,0,0,1,1,1V22A1,1,0,0,1,22,23Zm-3-2h2V11H19Z"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#6d6daa;}.cls-2{fill:#f4dab7;}.cls-3{fill:#96d7ff;}.cls-4{fill:#ffd599;}</style></defs><title/><path class="cls-1" d="M27,11.6H5a1,1,0,0,1-1-1V4A1,1,0,0,1,5,3H27a1,1,0,0,1,1,1v6.6A1,1,0,0,1,27,11.6ZM6,9.6H26V5H6Z"/><rect class="cls-2" height="4" width="14" x="9" y="2"/><path class="cls-1" d="M23,7H9A1,1,0,0,1,8,6V2A1,1,0,0,1,9,1H23a1,1,0,0,1,1,1V6A1,1,0,0,1,23,7ZM10,5H22V3H10Z"/><rect class="cls-3" height="20" width="28" x="2" y="10"/><path class="cls-1" d="M30,31H2a1,1,0,0,1-1-1V10A1,1,0,0,1,2,9H30a1,1,0,0,1,1,1V30A1,1,0,0,1,30,31ZM3,29H29V11H3Z"/><rect class="cls-4" height="20" width="6" x="2" y="10"/><path class="cls-1" d="M8,31H2a1,1,0,0,1-1-1V10A1,1,0,0,1,2,9H8a1,1,0,0,1,1,1V30A1,1,0,0,1,8,31ZM3,29H7V11H3Z"/><rect class="cls-4" height="20" width="6" x="24" y="10"/><path class="cls-1" d="M30,31H24a1,1,0,0,1-1-1V10a1,1,0,0,1,1-1h6a1,1,0,0,1,1,1V30A1,1,0,0,1,30,31Zm-5-2h4V11H25Z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#eef5fd;}.cls-2{fill:#6d6daa;}.cls-3{fill:#ff9797;}.cls-4{fill:#f4dab7;}</style></defs><title/><path class="cls-1" d="M20,20H12a6,6,0,0,0-6,6v4H26V26A6,6,0,0,0,20,20Z"/><path class="cls-2" d="M26,31H6a1,1,0,0,1-1-1V26a7,7,0,0,1,7-7h8a7,7,0,0,1,7,7v4A1,1,0,0,1,26,31ZM7,29H25V26a5,5,0,0,0-5-5H12a5,5,0,0,0-5,5Z"/><path class="cls-3" d="M20,20H19l-3,2-2,2.15V30H26V26A6,6,0,0,0,20,20Z"/><path class="cls-2" d="M26,31H14a1,1,0,0,1-1-1V24.16a1,1,0,0,1,.27-.68l2-2.16.18-.15,3-2A1,1,0,0,1,19,19h1a7,7,0,0,1,7,7v4A1,1,0,0,1,26,31ZM15,29H25V26a5,5,0,0,0-5-5h-.7l-2.65,1.77L15,24.55Z"/><polygon class="cls-4" points="13 12.82 13 20 16 22 19 20 19 12.82 13 12.82"/><path class="cls-2" d="M16,23a1,1,0,0,1-.55-.16l-3-2A1,1,0,0,1,12,20V12.82a1,1,0,0,1,1-1h6a1,1,0,0,1,1,1V20a1,1,0,0,1-.45.84l-3,2A1,1,0,0,1,16,23Zm-2-3.53,2,1.33,2-1.33V13.82H14Z"/><path class="cls-2" d="M17,27a1,1,0,0,1-1-1V25a1,1,0,0,1,2,0v1A1,1,0,0,1,17,27Z"/><rect class="cls-1" height="4" width="11" x="10.5" y="2"/><path class="cls-2" d="M21.5,7h-11a1,1,0,0,1-1-1V2a1,1,0,0,1,1-1h11a1,1,0,0,1,1,1V6A1,1,0,0,1,21.5,7Zm-10-2h9V3h-9Z"/><rect class="cls-4" height="4" rx="2" ry="2" width="16" x="8" y="10.42"/><path class="cls-2" d="M22,15.42H10a3,3,0,0,1,0-6H22a3,3,0,0,1,0,6Zm-12-4a1,1,0,0,0,0,2H22a1,1,0,0,0,0-2Z"/><path class="cls-4" d="M13.14,6.19h5.72A2.64,2.64,0,0,1,21.5,8.83V13a5.24,5.24,0,0,1-5.24,5.24h-.51A5.24,5.24,0,0,1,10.5,13V8.83a2.64,2.64,0,0,1,2.64-2.64Z"/><path class="cls-2" d="M16.26,19.19h-.52A6.25,6.25,0,0,1,9.5,13V8.83a3.65,3.65,0,0,1,3.64-3.64h5.72A3.65,3.65,0,0,1,22.5,8.83V13A6.25,6.25,0,0,1,16.26,19.19Zm-3.12-12A1.64,1.64,0,0,0,11.5,8.83V13a4.24,4.24,0,0,0,4.24,4.24h.52A4.24,4.24,0,0,0,20.5,13V8.83a1.64,1.64,0,0,0-1.64-1.64Z"/><rect class="cls-3" height="3" width="11" x="10.5" y="6"/><path class="cls-2" d="M21.5,10h-11a1,1,0,0,1-1-1V6a1,1,0,0,1,1-1h11a1,1,0,0,1,1,1V9A1,1,0,0,1,21.5,10Zm-10-2h9V7h-9Z"/></svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#91e085;}.cls-2{fill:#6d6daa;}.cls-3{fill:#798bc6;}.cls-4{fill:#ffd599;}.cls-5{fill:#d6b5b0;}.cls-6{fill:#eef5fd;}</style></defs><title/><rect class="cls-1" height="4" width="20" x="6" y="2"/><path class="cls-2" d="M26,7H6A1,1,0,0,1,5,6V2A1,1,0,0,1,6,1H26a1,1,0,0,1,1,1V6A1,1,0,0,1,26,7ZM7,5H25V3H7Z"/><rect class="cls-3" height="6" width="16" x="8" y="6"/><path class="cls-2" d="M24,13H8a1,1,0,0,1-1-1V6A1,1,0,0,1,8,5H24a1,1,0,0,1,1,1v6A1,1,0,0,1,24,13ZM9,11H23V7H9Z"/><rect class="cls-4" height="18" width="12" x="10" y="12"/><path class="cls-2" d="M22,31H10a1,1,0,0,1-1-1V12a1,1,0,0,1,1-1H22a1,1,0,0,1,1,1V30A1,1,0,0,1,22,31ZM11,29H21V13H11Z"/><rect class="cls-5" height="18" width="4" x="10" y="12"/><path class="cls-2" d="M14,31H10a1,1,0,0,1-1-1V12a1,1,0,0,1,1-1h4a1,1,0,0,1,1,1V30A1,1,0,0,1,14,31Zm-3-2h2V13H11Z"/><circle class="cls-6" cx="18" cy="16.06" r="1.5"/><path class="cls-2" d="M18,18.56a2.5,2.5,0,1,1,2.5-2.5A2.5,2.5,0,0,1,18,18.56Zm0-3a.5.5,0,0,0-.5.5.5.5,0,1,0,1,0A.5.5,0,0,0,18,15.56Z"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#d6b5b0;}.cls-2{fill:#6d6daa;}.cls-3{fill:#ffd599;}</style></defs><title/><rect class="cls-1" height="6" rx="3" ry="3" width="20" x="6" y="2"/><path class="cls-2" d="M23,9H9A4,4,0,0,1,9,1H23a4,4,0,0,1,0,8ZM9,3A2,2,0,0,0,9,7H23a2,2,0,0,0,0-4Z"/><rect class="cls-3" height="4" width="6" x="13" y="8"/><path class="cls-2" d="M19,13H13a1,1,0,0,1-1-1V8a1,1,0,0,1,1-1h6a1,1,0,0,1,1,1v4A1,1,0,0,1,19,13Zm-5-2h4V9H14Z"/><path class="cls-2" d="M16,31a1,1,0,0,1-1-1V12a1,1,0,0,1,2,0V30A1,1,0,0,1,16,31Z"/><polygon class="cls-3" points="24 30 8 30 10 26 16 26 22 26 24 30"/><path class="cls-2" d="M24,31H8a1,1,0,0,1-.89-1.45l2-4A1,1,0,0,1,10,25H22a1,1,0,0,1,.89.55l2,4A1,1,0,0,1,24,31ZM9.62,29H22.38l-1-2H10.62Z"/><path class="cls-2" d="M23,15H20a1,1,0,0,1-.89-.55l-1-2a1,1,0,0,1,1.78-.9L20.62,13H23a1,1,0,0,1,0,2Z"/></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#96d7ff;}.cls-2{fill:#6d6daa;}.cls-3{fill:#798bc6;}.cls-4{fill:#eef5fd;}</style></defs><title/><path class="cls-1" d="M19,6h0a4,4,0,0,1,4,4v9a0,0,0,0,1,0,0H19a0,0,0,0,1,0,0V6A0,0,0,0,1,19,6Z"/><path class="cls-2" d="M23,20H19a1,1,0,0,1-1-1V6a1,1,0,0,1,1-1,5,5,0,0,1,5,5v9A1,1,0,0,1,23,20Zm-3-2h2V10a3,3,0,0,0-2-2.83Z"/><circle class="cls-3" cx="4" cy="10" r="2"/><path class="cls-2" d="M4,13a3,3,0,1,1,3-3A3,3,0,0,1,4,13ZM4,9a1,1,0,1,0,1,1A1,1,0,0,0,4,9Z"/><circle class="cls-3" cx="28" cy="10" r="2"/><path class="cls-2" d="M28,13a3,3,0,1,1,3-3A3,3,0,0,1,28,13Zm0-4a1,1,0,1,0,1,1A1,1,0,0,0,28,9Z"/><path class="cls-2" d="M26,11H6A1,1,0,0,1,6,9H26a1,1,0,0,1,0,2Z"/><path class="cls-4" d="M11,6h8a0,0,0,0,1,0,0V26a0,0,0,0,1,0,0H9a0,0,0,0,1,0,0V8A2,2,0,0,1,11,6Z"/><path class="cls-2" d="M19,27H9a1,1,0,0,1-1-1V8a3,3,0,0,1,3-3h8a1,1,0,0,1,1,1V26A1,1,0,0,1,19,27Zm-9-2h8V7H11a1,1,0,0,0-1,1Z"/><rect class="cls-1" height="4" width="10" x="9" y="22"/><path class="cls-2" d="M19,27H9a1,1,0,0,1-1-1V22a1,1,0,0,1,1-1H19a1,1,0,0,1,1,1v4A1,1,0,0,1,19,27Zm-9-2h8V23H10Z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#eef5fd;}.cls-2{fill:#6d6daa;}.cls-3{fill:#d6b5b0;}.cls-4{fill:#ffc661;}</style></defs><title/><path class="cls-1" d="M3,16H29a0,0,0,0,1,0,0v6a4,4,0,0,1-4,4H7a4,4,0,0,1-4-4V16A0,0,0,0,1,3,16Z"/><path class="cls-2" d="M25,27H7a5,5,0,0,1-5-5V16a1,1,0,0,1,1-1H29a1,1,0,0,1,1,1v6A5,5,0,0,1,25,27ZM4,17v5a3,3,0,0,0,3,3H25a3,3,0,0,0,3-3V17Z"/><rect class="cls-3" height="3" width="28" x="2" y="13"/><path class="cls-2" d="M30,17H2a1,1,0,0,1-1-1V13a1,1,0,0,1,1-1H30a1,1,0,0,1,1,1v3A1,1,0,0,1,30,17ZM3,15H29V14H3Z"/><rect class="cls-3" height="4" width="4" x="7" y="26"/><path class="cls-2" d="M11,31H7a1,1,0,0,1-1-1V26a1,1,0,0,1,1-1h4a1,1,0,0,1,1,1v4A1,1,0,0,1,11,31ZM8,29h2V27H8Z"/><rect class="cls-3" height="4" width="4" x="21" y="26"/><path class="cls-2" d="M25,31H21a1,1,0,0,1-1-1V26a1,1,0,0,1,1-1h4a1,1,0,0,1,1,1v4A1,1,0,0,1,25,31Zm-3-2h2V27H22Z"/><path class="cls-2" d="M26,14a1,1,0,0,1-1-1V4.5a1.5,1.5,0,0,0-3,0V6a1,1,0,0,1-2,0V4.5a3.5,3.5,0,0,1,7,0V13A1,1,0,0,1,26,14Z"/><path class="cls-4" d="M21,6h0a2.5,2.5,0,0,1,2.5,2.5V9a0,0,0,0,1,0,0h-5a0,0,0,0,1,0,0V8.5A2.5,2.5,0,0,1,21,6Z"/><path class="cls-2" d="M23.5,10h-5a1,1,0,0,1-1-1V8.5a3.5,3.5,0,0,1,7,0V9A1,1,0,0,1,23.5,10ZM19.59,8h2.82a1.49,1.49,0,0,0-2.82,0Z"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#ffd599;}.cls-2{fill:#6d6daa;}.cls-3{fill:#eef5fd;}.cls-4{fill:#c9c1f5;}.cls-5{fill:#ff9797;}</style></defs><title/><rect class="cls-1" height="4" width="28" x="2" y="16"/><path class="cls-2" d="M30,21H2a1,1,0,0,1-1-1V16a1,1,0,0,1,1-1H30a1,1,0,0,1,1,1v4A1,1,0,0,1,30,21ZM3,19H29V17H3Z"/><path class="cls-3" d="M4,20A11.88,11.88,0,0,0,16,30,11.88,11.88,0,0,0,28,20Z"/><path class="cls-2" d="M16,31A12.89,12.89,0,0,1,3,20.13a1,1,0,0,1,.24-.79A1,1,0,0,1,4,19H28a1,1,0,0,1,.75.34,1,1,0,0,1,.24.79A12.89,12.89,0,0,1,16,31ZM5.21,21A11,11,0,0,0,16,29a11,11,0,0,0,10.79-8Z"/><rect class="cls-4" height="7" width="3" x="14.5" y="9"/><path class="cls-2" d="M17.5,17h-3a1,1,0,0,1-1-1V9a1,1,0,0,1,1-1h3a1,1,0,0,1,1,1v7A1,1,0,0,1,17.5,17Zm-2-2h1V10h-1Z"/><path class="cls-5" d="M16,2h0a3,3,0,0,1,3,3V9a0,0,0,0,1,0,0H13a0,0,0,0,1,0,0V5A3,3,0,0,1,16,2Z"/><path class="cls-2" d="M19,10H13a1,1,0,0,1-1-1V5a4,4,0,0,1,8,0V9A1,1,0,0,1,19,10ZM14,8h4V5a2,2,0,0,0-4,0Z"/><path class="cls-5" d="M8,12H8a2,2,0,0,1,2,2v2a0,0,0,0,1,0,0H6a0,0,0,0,1,0,0V14A2,2,0,0,1,8,12Z"/><path class="cls-2" d="M10,17H6a1,1,0,0,1-1-1V14a3,3,0,0,1,6,0v2A1,1,0,0,1,10,17ZM7,15H9V14a1,1,0,0,0-2,0Z"/><path class="cls-5" d="M24,12h0a2,2,0,0,1,2,2v2a0,0,0,0,1,0,0H22a0,0,0,0,1,0,0V14A2,2,0,0,1,24,12Z"/><path class="cls-2" d="M26,17H22a1,1,0,0,1-1-1V14a3,3,0,0,1,6,0v2A1,1,0,0,1,26,17Zm-3-2h2V14a1,1,0,0,0-2,0Z"/></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#ffd599;}.cls-2{fill:#6d6daa;}.cls-3{fill:#d6b5b0;}.cls-4{fill:#f4dab7;}.cls-5{fill:#ff9797;}</style></defs><title/><rect class="cls-1" height="20" width="4" x="2" y="6"/><path class="cls-2" d="M6,27H2a1,1,0,0,1-1-1V6A1,1,0,0,1,2,5H6A1,1,0,0,1,7,6V26A1,1,0,0,1,6,27ZM3,25H5V7H3Z"/><rect class="cls-1" height="10" width="4" x="26" y="16"/><path class="cls-2" d="M30,27H26a1,1,0,0,1-1-1V16a1,1,0,0,1,1-1h4a1,1,0,0,1,1,1V26A1,1,0,0,1,30,27Zm-3-2h2V17H27Z"/><rect class="cls-3" height="4" width="20" x="6" y="18"/><path class="cls-2" d="M26,23H6a1,1,0,0,1-1-1V18a1,1,0,0,1,1-1H26a1,1,0,0,1,1,1v4A1,1,0,0,1,26,23ZM7,21H25V19H7Z"/><path class="cls-4" d="M6,13H28a2,2,0,0,1,2,2v3a0,0,0,0,1,0,0H6a0,0,0,0,1,0,0V13A0,0,0,0,1,6,13Z"/><path class="cls-2" d="M30,19H6a1,1,0,0,1-1-1V13a1,1,0,0,1,1-1H28a3,3,0,0,1,3,3v3A1,1,0,0,1,30,19ZM7,17H29V15a1,1,0,0,0-1-1H7Z"/><path class="cls-5" d="M6,10h5a3,3,0,0,1,3,3v0a0,0,0,0,1,0,0H6a0,0,0,0,1,0,0V10A0,0,0,0,1,6,10Z"/><path class="cls-2" d="M14,14H6a1,1,0,0,1-1-1V10A1,1,0,0,1,6,9h5a4,4,0,0,1,4,4A1,1,0,0,1,14,14ZM7,12h5.73A2,2,0,0,0,11,11H7Z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#ffd599;}.cls-2{fill:#6d6daa;}.cls-3{fill:#d6b5b0;}.cls-4{fill:#f4dab7;}.cls-5{fill:#ff9797;}</style></defs><title/><path class="cls-1" d="M7.5,6h17a4,4,0,0,1,4,4V20a0,0,0,0,1,0,0H3.5a0,0,0,0,1,0,0V10A4,4,0,0,1,7.5,6Z"/><path class="cls-2" d="M28.5,21H3.5a1,1,0,0,1-1-1V10a5,5,0,0,1,5-5h17a5,5,0,0,1,5,5V20A1,1,0,0,1,28.5,21Zm-24-2h23V10a3,3,0,0,0-3-3H7.5a3,3,0,0,0-3,3Z"/><rect class="cls-3" height="3" width="28" x="2" y="20"/><path class="cls-2" d="M30,24H2a1,1,0,0,1-1-1V20a1,1,0,0,1,1-1H30a1,1,0,0,1,1,1v3A1,1,0,0,1,30,24ZM3,22H29V21H3Z"/><path class="cls-4" d="M5.54,14H26.46a2,2,0,0,1,2,2v4a0,0,0,0,1,0,0H3.5a0,0,0,0,1,0,0V16A2,2,0,0,1,5.54,14Z"/><path class="cls-2" d="M28.5,21H3.5a1,1,0,0,1-1-1V16a3,3,0,0,1,3-3H26.46a3,3,0,0,1,3,3v4A1,1,0,0,1,28.5,21Zm-24-2h23V16a1,1,0,0,0-1-1H5.54a1,1,0,0,0-1,1Z"/><rect class="cls-1" height="3" width="4" x="4" y="23"/><path class="cls-2" d="M8,27H4a1,1,0,0,1-1-1V23a1,1,0,0,1,1-1H8a1,1,0,0,1,1,1v3A1,1,0,0,1,8,27ZM5,25H7V24H5Z"/><rect class="cls-1" height="3" width="4" x="24" y="23"/><path class="cls-2" d="M28,27H24a1,1,0,0,1-1-1V23a1,1,0,0,1,1-1h4a1,1,0,0,1,1,1v3A1,1,0,0,1,28,27Zm-3-2h2V24H25Z"/><rect class="cls-5" height="3" width="8" x="6" y="11"/><path class="cls-2" d="M14,15H6a1,1,0,0,1-1-1V11a1,1,0,0,1,1-1h8a1,1,0,0,1,1,1v3A1,1,0,0,1,14,15ZM7,13h6V12H7Z"/><rect class="cls-5" height="3" width="8" x="18" y="11"/><path class="cls-2" d="M26,15H18a1,1,0,0,1-1-1V11a1,1,0,0,1,1-1h8a1,1,0,0,1,1,1v3A1,1,0,0,1,26,15Zm-7-2h6V12H19Z"/></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#d6b5b0;}.cls-2{fill:#6d6daa;}.cls-3{fill:#f4dab7;}.cls-4{fill:#ffd599;}.cls-5{fill:#ff9797;}</style></defs><title/><rect class="cls-1" height="3" width="28" x="2" y="20"/><path class="cls-2" d="M30,24H2a1,1,0,0,1-1-1V20a1,1,0,0,1,1-1H30a1,1,0,0,1,1,1v3A1,1,0,0,1,30,24ZM3,22H29V21H3Z"/><path class="cls-3" d="M6,14H26a2,2,0,0,1,2,2v4a0,0,0,0,1,0,0H4a0,0,0,0,1,0,0V16A2,2,0,0,1,6,14Z"/><path class="cls-2" d="M28,21H4a1,1,0,0,1-1-1V16a3,3,0,0,1,3-3H26a3,3,0,0,1,3,3v4A1,1,0,0,1,28,21ZM5,19H27V16a1,1,0,0,0-1-1H6a1,1,0,0,0-1,1Z"/><rect class="cls-4" height="3" width="4" x="4" y="23"/><path class="cls-2" d="M8,27H4a1,1,0,0,1-1-1V23a1,1,0,0,1,1-1H8a1,1,0,0,1,1,1v3A1,1,0,0,1,8,27ZM5,25H7V24H5Z"/><rect class="cls-4" height="3" width="4" x="24" y="23"/><path class="cls-2" d="M28,27H24a1,1,0,0,1-1-1V23a1,1,0,0,1,1-1h4a1,1,0,0,1,1,1v3A1,1,0,0,1,28,27Zm-3-2h2V24H25Z"/><path class="cls-4" d="M10,6H22a4,4,0,0,1,4,4v4a0,0,0,0,1,0,0H6a0,0,0,0,1,0,0V10A4,4,0,0,1,10,6Z"/><path class="cls-2" d="M26,15H6a1,1,0,0,1-1-1V10a5,5,0,0,1,5-5H22a5,5,0,0,1,5,5v4A1,1,0,0,1,26,15ZM7,13H25V10a3,3,0,0,0-3-3H10a3,3,0,0,0-3,3Z"/><rect class="cls-5" height="3" width="8" x="12" y="11"/><path class="cls-2" d="M20,15H12a1,1,0,0,1-1-1V11a1,1,0,0,1,1-1h8a1,1,0,0,1,1,1v3A1,1,0,0,1,20,15Zm-7-2h6V12H13Z"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#c9c1f5;}.cls-2{fill:#6d6daa;}.cls-3{fill:#96d7ff;}</style></defs><title/><polygon class="cls-1" points="20 26 6 26 6 6 20 2 20 26"/><path class="cls-2" d="M20,27H6a1,1,0,0,1-1-1V6a1,1,0,0,1,.73-1l14-4a1,1,0,0,1,.87.16A1,1,0,0,1,21,2V26A1,1,0,0,1,20,27ZM7,25H19V3.33L7,6.75Z"/><polygon class="cls-3" points="26 30 6 29 6 6 26 7 26 30"/><path class="cls-2" d="M26,31H26L6,30a1,1,0,0,1-1-1V6a1,1,0,0,1,.31-.72A1,1,0,0,1,6.05,5l20,1A1,1,0,0,1,27,7V30a1,1,0,0,1-.31.72A1,1,0,0,1,26,31ZM7,28.05,25,29V8L7,7.05Z"/><path class="cls-2" d="M16,25a7,7,0,1,1,7-7A7,7,0,0,1,16,25Zm0-12a5,5,0,1,0,5,5A5,5,0,0,0,16,13Z"/><path class="cls-2" d="M16,25c-2.23,0-3.4-3.52-3.4-7s1.17-7,3.4-7,3.4,3.52,3.4,7S18.23,25,16,25Zm0-2h0Zm0-10c-.4.06-1.4,1.9-1.4,5s1,4.93,1.4,5,1.4-1.9,1.4-5S16.4,13.06,16,13Z"/><path class="cls-2" d="M22,19H10a1,1,0,0,1,0-2H22a1,1,0,0,1,0,2Z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#91e085;}.cls-2{fill:#6d6daa;}.cls-3{fill:#d6b5b0;}.cls-4{fill:#ffd599;}</style></defs><title/><rect class="cls-1" height="16" transform="translate(14.89 -9.31) rotate(45)" width="16" x="10.69" y="5.31"/><path class="cls-2" d="M18.69,25.63a1,1,0,0,1-.71-.3L6.67,14a1,1,0,0,1,0-1.41L18,1.29a1,1,0,0,1,1.41,0L30.71,12.61a1,1,0,0,1,0,1.41L19.39,25.33A1,1,0,0,1,18.69,25.63ZM8.79,13.31l9.9,9.9,9.9-9.9-9.9-9.9Z"/><rect class="cls-1" height="16" transform="translate(13.31 -5.51) rotate(45)" width="16" x="5.31" y="5.31"/><path class="cls-2" d="M13.31,25.63a1,1,0,0,1-.7-.3L1.29,14a1,1,0,0,1,0-1.41L12.61,1.29a1,1,0,0,1,1.41,0L25.33,12.61a1,1,0,0,1,0,1.41L14,25.33A1,1,0,0,1,13.31,25.63ZM3.41,13.31l9.9,9.9,9.9-9.9-9.9-9.9Z"/><rect class="cls-3" height="20" width="28" x="2" y="10"/><path class="cls-2" d="M30,31H2a1,1,0,0,1-1-1V10A1,1,0,0,1,2,9H30a1,1,0,0,1,1,1V30A1,1,0,0,1,30,31ZM3,29H29V11H3Z"/><path class="cls-4" d="M25,17h5a0,0,0,0,1,0,0v6a0,0,0,0,1,0,0H25a3,3,0,0,1-3-3v0A3,3,0,0,1,25,17Z"/><path class="cls-2" d="M30,24H25a4,4,0,0,1,0-8h5a1,1,0,0,1,1,1v6A1,1,0,0,1,30,24Zm-5-6a2,2,0,0,0,0,4h4V18Z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#eef5fd;}.cls-2{fill:#6d6daa;}.cls-3{fill:#91e085;}.cls-4{fill:#ff9797;}</style></defs><title/><path class="cls-1" d="M14,2H2V29H14a2,2,0,0,1,1.72,1H16V4A2,2,0,0,0,14,2Z"/><path class="cls-2" d="M16,31h-.28a1,1,0,0,1-.86-.5A1,1,0,0,0,14,30H2a1,1,0,0,1-1-1V2A1,1,0,0,1,2,1H14a3,3,0,0,1,3,3V30A1,1,0,0,1,16,31ZM3,28H14a3.09,3.09,0,0,1,1,.17V4a1,1,0,0,0-1-1H3Z"/><path class="cls-2" d="M13,17H5a1,1,0,0,1,0-2h8a1,1,0,0,1,0,2Z"/><path class="cls-2" d="M13,21.5H5a1,1,0,0,1,0-2h8a1,1,0,0,1,0,2Z"/><path class="cls-2" d="M13,26H5a1,1,0,0,1,0-2h8a1,1,0,0,1,0,2Z"/><circle class="cls-3" cx="9" cy="9" r="3"/><path class="cls-2" d="M9,13a4,4,0,1,1,4-4A4,4,0,0,1,9,13ZM9,7a2,2,0,1,0,2,2A2,2,0,0,0,9,7Z"/><path class="cls-1" d="M18,2H30V29H18a2,2,0,0,0-1.72,1H16V4A2,2,0,0,1,18,2Z"/><path class="cls-2" d="M16.28,31H16a1,1,0,0,1-1-1V4a3,3,0,0,1,3-3H30a1,1,0,0,1,1,1V29a1,1,0,0,1-1,1H18a1,1,0,0,0-.86.5A1,1,0,0,1,16.28,31ZM18,3a1,1,0,0,0-1,1V28.17A3.09,3.09,0,0,1,18,28H29V3Z"/><rect class="cls-4" height="6" width="6" x="20" y="6"/><path class="cls-2" d="M26,13H20a1,1,0,0,1-1-1V6a1,1,0,0,1,1-1h6a1,1,0,0,1,1,1v6A1,1,0,0,1,26,13Zm-5-2h4V7H21Z"/><path class="cls-2" d="M27,17H19a1,1,0,0,1,0-2h8a1,1,0,0,1,0,2Z"/><path class="cls-2" d="M27,21.5H19a1,1,0,0,1,0-2h8a1,1,0,0,1,0,2Z"/><path class="cls-2" d="M27,26H19a1,1,0,0,1,0-2h8a1,1,0,0,1,0,2Z"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#f4dab7;}.cls-2{fill:#6d6daa;}.cls-3{fill:#d6b5b0;}.cls-4{fill:#91e085;}</style></defs><title/><path class="cls-1" d="M27.91,26H4.09a1,1,0,0,1-.93-.55l-1.05-2A1,1,0,0,1,3.05,22H29a1,1,0,0,1,.94,1.45l-1.05,2A1,1,0,0,1,27.91,26Z"/><path class="cls-2" d="M27.91,27H4.09a2,2,0,0,1-1.82-1.09l-1-2A1.93,1.93,0,0,1,1.29,22a2,2,0,0,1,1.76-1H29a2,2,0,0,1,1.76,1,1.93,1.93,0,0,1,.06,1.93l-1,2A2,2,0,0,1,27.91,27ZM29,23,3.05,23l1,2,23.87,0A.06.06,0,0,0,28,25Z"/><path class="cls-3" d="M7,6H25a1,1,0,0,1,1,1V22a0,0,0,0,1,0,0H6a0,0,0,0,1,0,0V7A1,1,0,0,1,7,6Z"/><path class="cls-2" d="M26,23H6a1,1,0,0,1-1-1V7A2,2,0,0,1,7,5H25a2,2,0,0,1,2,2V22A1,1,0,0,1,26,23ZM7,21H25V7H7Z"/><path class="cls-2" d="M28,20H26a1,1,0,0,1-1-1V9a1,1,0,0,1,1-1h2a3,3,0,0,1,3,3v6A3,3,0,0,1,28,20Zm-1-2h1a1,1,0,0,0,1-1V11a1,1,0,0,0-1-1H27Z"/><polygon class="cls-4" points="19 18 13 18 13 11 16 10 19 11 19 18"/><path class="cls-2" d="M19,19H13a1,1,0,0,1-1-1V11a1,1,0,0,1,.68-.95l3-1a1,1,0,0,1,.64,0l3,1A1,1,0,0,1,20,11v7A1,1,0,0,1,19,19Zm-5-2h4V11.72l-2-.67-2,.67Z"/><path class="cls-2" d="M16,11a1,1,0,0,1-1-1V6a1,1,0,0,1,2,0v4A1,1,0,0,1,16,11Z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#ffd599;}.cls-2{fill:#6d6daa;}.cls-3{fill:#d6b5b0;}.cls-4{fill:#798bc6;}.cls-5{fill:#eef5fd;}</style></defs><title/><rect class="cls-1" height="24" width="28" x="2" y="6"/><path class="cls-2" d="M30,31H2a1,1,0,0,1-1-1V6A1,1,0,0,1,2,5H30a1,1,0,0,1,1,1V30A1,1,0,0,1,30,31ZM3,29H29V7H3Z"/><rect class="cls-3" height="4" width="28" x="2" y="6"/><path class="cls-2" d="M30,11H2a1,1,0,0,1-1-1V6A1,1,0,0,1,2,5H30a1,1,0,0,1,1,1v4A1,1,0,0,1,30,11ZM3,9H29V7H3Z"/><path class="cls-4" d="M6,2H6A2,2,0,0,1,8,4V6A0,0,0,0,1,8,6H4A0,0,0,0,1,4,6V4A2,2,0,0,1,6,2Z"/><path class="cls-2" d="M8,7H4A1,1,0,0,1,3,6V4A3,3,0,0,1,9,4V6A1,1,0,0,1,8,7ZM5,5H7V4A1,1,0,0,0,5,4Z"/><path class="cls-4" d="M26,2h0a2,2,0,0,1,2,2V6a0,0,0,0,1,0,0H24a0,0,0,0,1,0,0V4A2,2,0,0,1,26,2Z"/><path class="cls-2" d="M28,7H24a1,1,0,0,1-1-1V4a3,3,0,0,1,6,0V6A1,1,0,0,1,28,7ZM25,5h2V4a1,1,0,0,0-2,0Z"/><rect class="cls-5" height="12" width="18" x="7" y="14"/><path class="cls-2" d="M25,27H7a1,1,0,0,1-1-1V14a1,1,0,0,1,1-1H25a1,1,0,0,1,1,1V26A1,1,0,0,1,25,27ZM8,25H24V15H8Z"/><path class="cls-2" d="M25,21H7a1,1,0,0,1,0-2H25a1,1,0,0,1,0,2Z"/><path class="cls-2" d="M19,27H13a1,1,0,0,1-1-1V14a1,1,0,0,1,1-1h6a1,1,0,0,1,1,1V26A1,1,0,0,1,19,27Zm-5-2h4V15H14Z"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#eef5fd;}.cls-2{fill:#6d6daa;}.cls-3{fill:#ffd599;}.cls-4{fill:#96d7ff;}.cls-5{fill:#d6b5b0;}</style></defs><title/><path class="cls-1" d="M21.48,30h-11a1,1,0,0,1-1-.92L8,10H24L22.47,29.08A1,1,0,0,1,21.48,30Z"/><path class="cls-2" d="M21.48,31h-11a2,2,0,0,1-2-1.84L7,10.08a1,1,0,0,1,.27-.76A1,1,0,0,1,8,9H24a1,1,0,0,1,.73.32,1,1,0,0,1,.27.76L23.47,29.16A2,2,0,0,1,21.48,31ZM9.08,11l1.44,18h11l1.44-18Z"/><polygon class="cls-3" points="22.72 26 23.68 14 8.32 14 9.28 26 22.72 26"/><path class="cls-2" d="M22.72,27H9.28a1,1,0,0,1-1-.92l-1-12a1.05,1.05,0,0,1,.26-.76A1,1,0,0,1,8.32,13H23.68a1,1,0,0,1,.74.32,1.05,1.05,0,0,1,.26.76l-1,12A1,1,0,0,1,22.72,27ZM10.2,25H21.8l.8-10H9.4Z"/><rect class="cls-4" height="4" width="20" x="6" y="6"/><path class="cls-2" d="M26,11H6a1,1,0,0,1-1-1V6A1,1,0,0,1,6,5H26a1,1,0,0,1,1,1v4A1,1,0,0,1,26,11ZM7,9H25V7H7Z"/><path class="cls-5" d="M25,6H7L8.72,2.55A1,1,0,0,1,9.62,2H22.38a1,1,0,0,1,.9.55Z"/><path class="cls-2" d="M25,7H7a1,1,0,0,1-.89-1.45L7.83,2.11A2,2,0,0,1,9.62,1H22.38a2,2,0,0,1,1.79,1.11l1.72,3.44A1,1,0,0,1,25,7ZM8.62,5H23.38l-1-2H9.62Z"/><ellipse class="cls-5" cx="16" cy="20" rx="3" ry="2.5" transform="translate(-8.27 28.19) rotate(-70)"/><path class="cls-2" d="M15.69,24a3,3,0,0,1-1.06-.19,3.79,3.79,0,0,1-1.92-5,3.78,3.78,0,0,1,4.66-2.56,3.79,3.79,0,0,1,1.92,5h0A4,4,0,0,1,15.69,24Zm.61-5.9a2,2,0,0,0-1.71,1.44,1.82,1.82,0,0,0,.73,2.39c.76.28,1.72-.35,2.09-1.37h0a1.82,1.82,0,0,0-.73-2.39A1.22,1.22,0,0,0,16.3,18.05Z"/></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#6d6daa;}.cls-2{fill:#d6b5b0;}.cls-3{fill:#f4dab7;}</style></defs><title/><path class="cls-1" d="M26.2,18h-3a1,1,0,0,1-1-1V7a1,1,0,0,1,1-1H27a4,4,0,0,1,3.92,4.78l-.8,4A4,4,0,0,1,26.2,18Zm-2-2h2a2,2,0,0,0,2-1.61l.8-4a2,2,0,0,0-.41-1.66A2,2,0,0,0,27,8H24.22Z"/><path class="cls-2" d="M8,6H24a0,0,0,0,1,0,0v8a8,8,0,0,1-8,8h0a8,8,0,0,1-8-8V6A0,0,0,0,1,8,6Z"/><path class="cls-1" d="M16,23a9,9,0,0,1-9-9V6A1,1,0,0,1,8,5H24a1,1,0,0,1,1,1v8A9,9,0,0,1,16,23ZM9,7v7a7,7,0,0,0,14,0V7Z"/><path class="cls-3" d="M27.91,26H4.09a1,1,0,0,1-.93-.55l-1.05-2A1,1,0,0,1,3.05,22H29a1,1,0,0,1,.94,1.45l-1.05,2A1,1,0,0,1,27.91,26Z"/><path class="cls-1" d="M27.91,27H4.09a2,2,0,0,1-1.82-1.09l-1-2A1.93,1.93,0,0,1,1.29,22a2,2,0,0,1,1.76-1H29a2,2,0,0,1,1.76,1,1.93,1.93,0,0,1,.06,1.93l-1,2A2,2,0,0,1,27.91,27ZM29,23,3.05,23l1,2,23.87,0A.06.06,0,0,0,28,25Z"/></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#ffd599;}.cls-2{fill:#6d6daa;}.cls-3{fill:#d6b5b0;}.cls-4{fill:#eef5fd;}.cls-5{fill:#ff9797;}</style></defs><title/><rect class="cls-1" height="20" width="28" x="2" y="6"/><path class="cls-2" d="M30,27H2a1,1,0,0,1-1-1V6A1,1,0,0,1,2,5H30a1,1,0,0,1,1,1V26A1,1,0,0,1,30,27ZM3,25H29V7H3Z"/><rect class="cls-3" height="4" width="28" x="2" y="6"/><path class="cls-2" d="M30,11H2a1,1,0,0,1-1-1V6A1,1,0,0,1,2,5H30a1,1,0,0,1,1,1v4A1,1,0,0,1,30,11ZM3,9H29V7H3Z"/><rect class="cls-4" height="4" width="28" x="2" y="10"/><path class="cls-2" d="M30,15H2a1,1,0,0,1-1-1V10A1,1,0,0,1,2,9H30a1,1,0,0,1,1,1v4A1,1,0,0,1,30,15ZM3,13H29V11H3Z"/><circle class="cls-5" cx="23" cy="20" r="3"/><path class="cls-2" d="M23,24a4,4,0,1,1,4-4A4,4,0,0,1,23,24Zm0-6a2,2,0,1,0,2,2A2,2,0,0,0,23,18Z"/></svg>

After

Width:  |  Height:  |  Size: 1002 B

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#ffffff;}.cls-2{fill:#6d6daa;}.cls-3{fill:#ffd599;}.cls-4{fill:#d6b5b0;}.cls-5{fill:#eef5fd;}</style></defs><title/><rect class="cls-1" height="20" width="28" x="2" y="6"/><path class="cls-2" d="M30,27H2a1,1,0,0,1-1-1V6A1,1,0,0,1,2,5H30a1,1,0,0,1,1,1V26A1,1,0,0,1,30,27ZM3,25H29V7H3Z"/><rect class="cls-3" height="16" width="28" x="2" y="10"/><path class="cls-2" d="M30,27H2a1,1,0,0,1-1-1V10A1,1,0,0,1,2,9H30a1,1,0,0,1,1,1V26A1,1,0,0,1,30,27ZM3,25H29V11H3Z"/><rect class="cls-4" height="4" width="28" x="2" y="6"/><path class="cls-2" d="M30,11H2a1,1,0,0,1-1-1V6A1,1,0,0,1,2,5H30a1,1,0,0,1,1,1v4A1,1,0,0,1,30,11ZM3,9H29V7H3Z"/><path class="cls-5" d="M20,13a5,5,0,0,0-4.31,2.5h-7L7,18l1.67,2.5h1.66l1.25-1.67,1.25,1.67h2.86A5,5,0,1,0,20,13Zm0,6.67A1.67,1.67,0,1,1,21.67,18,1.67,1.67,0,0,1,20,19.67Z"/><path class="cls-2" d="M20,24a6,6,0,0,1-4.85-2.5H12.83a1,1,0,0,1-.8-.4l-.45-.6-.45.6a1,1,0,0,1-.8.4H8.67a1,1,0,0,1-.84-.45l-1.66-2.5a1,1,0,0,1,0-1.1L7.83,15a1,1,0,0,1,.84-.45h6.48A6,6,0,1,1,20,24Zm-6.67-4.5h2.36a1,1,0,0,1,.87.5A4,4,0,0,0,20,22a4,4,0,0,0,0-8,4,4,0,0,0-3.44,2,1,1,0,0,1-.87.5H9.2L8.2,18l1,1.5h.63l.95-1.27a1,1,0,0,1,1.6,0ZM20,20.67A2.67,2.67,0,1,1,22.67,18,2.68,2.68,0,0,1,20,20.67Zm0-3.34a.67.67,0,1,0,.67.67A.67.67,0,0,0,20,17.33Z"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#ffc661;}.cls-2{fill:#6d6daa;}.cls-3{fill:#ff9797;}</style></defs><title/><path class="cls-1" d="M25.16,16A10,10,0,1,0,6,12a9.92,9.92,0,0,0,.84,4Z"/><path class="cls-2" d="M25.16,17H6.84a1,1,0,0,1-.92-.6,11,11,0,1,1,20.16,0A1,1,0,0,1,25.16,17ZM7.52,15h17A8.73,8.73,0,0,0,25,12,9,9,0,0,0,7,12,8.73,8.73,0,0,0,7.52,15Z"/><path class="cls-3" d="M20.58,16A18.74,18.74,0,0,0,21,12c0-5.52-2.24-10-5-10s-5,4.48-5,10a18.74,18.74,0,0,0,.42,4Z"/><path class="cls-2" d="M20.58,17H11.42a1,1,0,0,1-1-.79A19.83,19.83,0,0,1,10,12c0-6.17,2.64-11,6-11s6,4.83,6,11a19.83,19.83,0,0,1-.44,4.21A1,1,0,0,1,20.58,17Zm-8.34-2h7.52A18.32,18.32,0,0,0,20,12c0-5.3-2.11-9-4-9s-4,3.7-4,9A18.32,18.32,0,0,0,12.24,15Z"/><path class="cls-2" d="M16,31a1,1,0,0,1-1-1V16a1,1,0,0,1,2,0V30A1,1,0,0,1,16,31Z"/><path class="cls-2" d="M18,31H14a1,1,0,0,1,0-2h4a1,1,0,0,1,0,2Z"/><path class="cls-2" d="M8,31a1,1,0,0,1-1-1V25H3v5a1,1,0,0,1-2,0V24a1,1,0,0,1,1-1H8a1,1,0,0,1,1,1v6A1,1,0,0,1,8,31Z"/><path class="cls-2" d="M2,31a1,1,0,0,1-1-1V18a1,1,0,0,1,2,0V30A1,1,0,0,1,2,31Z"/><path class="cls-2" d="M30,31a1,1,0,0,1-1-1V25H25v5a1,1,0,0,1-2,0V24a1,1,0,0,1,1-1h6a1,1,0,0,1,1,1v6A1,1,0,0,1,30,31Z"/><path class="cls-2" d="M30,31a1,1,0,0,1-1-1V18a1,1,0,0,1,2,0V30A1,1,0,0,1,30,31Z"/><path class="cls-2" d="M21,23H11a1,1,0,0,1,0-2H21a1,1,0,0,1,0,2Z"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#91e085;}.cls-2{fill:#6d6daa;}.cls-3{fill:#96d7ff;}.cls-4{fill:#eef5fd;}.cls-5{fill:#f4dab7;}.cls-6{fill:#d6b5b0;}.cls-7{fill:#ffc661;}</style></defs><title/><rect class="cls-1" height="6" width="28" x="2" y="2"/><path class="cls-2" d="M30,9H2A1,1,0,0,1,1,8V2A1,1,0,0,1,2,1H30a1,1,0,0,1,1,1V8A1,1,0,0,1,30,9ZM3,7H29V3H3Z"/><rect class="cls-3" height="22" width="28" x="2" y="8"/><path class="cls-2" d="M30,31H2a1,1,0,0,1-1-1V8A1,1,0,0,1,2,7H30a1,1,0,0,1,1,1V30A1,1,0,0,1,30,31ZM3,29H29V9H3Z"/><circle class="cls-4" cx="16" cy="19" r="8"/><path class="cls-2" d="M16,28a9,9,0,1,1,9-9A9,9,0,0,1,16,28Zm0-16a7,7,0,1,0,7,7A7,7,0,0,0,16,12Z"/><path class="cls-2" d="M23.7,6H22.3a1,1,0,0,1,0-2h1.4a1,1,0,0,1,0,2Z"/><rect class="cls-5" height="6" width="14" x="2" y="2"/><path class="cls-2" d="M16,9H2A1,1,0,0,1,1,8V2A1,1,0,0,1,2,1H16a1,1,0,0,1,1,1V8A1,1,0,0,1,16,9ZM3,7H15V3H3Z"/><rect class="cls-6" height="6" width="7" x="2" y="2"/><path class="cls-2" d="M9,9H2A1,1,0,0,1,1,8V2A1,1,0,0,1,2,1H9a1,1,0,0,1,1,1V8A1,1,0,0,1,9,9ZM3,7H8V3H3Z"/><rect class="cls-7" height="4" width="5" x="21" y="17"/><path class="cls-2" d="M26,22H21a1,1,0,0,1-1-1V17a1,1,0,0,1,1-1h5a1,1,0,0,1,1,1v4A1,1,0,0,1,26,22Zm-4-2h3V18H22Z"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#ffd599;}.cls-2{fill:#6d6daa;}.cls-3{fill:#eef5fd;}.cls-4{fill:#ff9797;}</style></defs><title/><path class="cls-1" d="M8,2H8a6,6,0,0,1,6,6v8a0,0,0,0,1,0,0H2a0,0,0,0,1,0,0V8A6,6,0,0,1,8,2Z"/><path class="cls-2" d="M14,17H2a1,1,0,0,1-1-1V8A7,7,0,0,1,15,8v8A1,1,0,0,1,14,17ZM3,15H13V8A5,5,0,0,0,3,8Z"/><path class="cls-3" d="M4,16h8a0,0,0,0,1,0,0V26a4,4,0,0,1-4,4H8a4,4,0,0,1-4-4V16A0,0,0,0,1,4,16Z"/><path class="cls-2" d="M8,31a5,5,0,0,1-5-5V16a1,1,0,0,1,1-1h8a1,1,0,0,1,1,1V26A5,5,0,0,1,8,31ZM5,17v9a3,3,0,0,0,6,0V17Z"/><rect class="cls-4" height="4" width="12" x="2" y="12"/><path class="cls-2" d="M14,17H2a1,1,0,0,1-1-1V12a1,1,0,0,1,1-1H14a1,1,0,0,1,1,1v4A1,1,0,0,1,14,17ZM3,15H13V13H3Z"/><path class="cls-1" d="M24,2h0a6,6,0,0,1,6,6v8a0,0,0,0,1,0,0H18a0,0,0,0,1,0,0V8A6,6,0,0,1,24,2Z"/><path class="cls-2" d="M30,17H18a1,1,0,0,1-1-1V8A7,7,0,0,1,31,8v8A1,1,0,0,1,30,17ZM19,15H29V8A5,5,0,0,0,19,8Z"/><path class="cls-3" d="M20,16h8a0,0,0,0,1,0,0V26a4,4,0,0,1-4,4h0a4,4,0,0,1-4-4V16A0,0,0,0,1,20,16Z"/><path class="cls-2" d="M24,31a5,5,0,0,1-5-5V16a1,1,0,0,1,1-1h8a1,1,0,0,1,1,1V26A5,5,0,0,1,24,31ZM21,17v9a3,3,0,0,0,6,0V17Z"/><rect class="cls-4" height="4" width="12" x="18" y="12"/><path class="cls-2" d="M30,17H18a1,1,0,0,1-1-1V12a1,1,0,0,1,1-1H30a1,1,0,0,1,1,1v4A1,1,0,0,1,30,17ZM19,15H29V13H19Z"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#d6b5b0;}.cls-2{fill:#6d6daa;}.cls-3{fill:#96d7ff;}</style></defs><title/><rect class="cls-1" height="20" width="28" x="2" y="6"/><path class="cls-2" d="M30,27H2a1,1,0,0,1-1-1V6A1,1,0,0,1,2,5H30a1,1,0,0,1,1,1V26A1,1,0,0,1,30,27ZM3,25H29V7H3Z"/><rect class="cls-3" height="20" width="24" x="2" y="6"/><path class="cls-2" d="M26,27H2a1,1,0,0,1-1-1V6A1,1,0,0,1,2,5H26a1,1,0,0,1,1,1V26A1,1,0,0,1,26,27ZM3,25H25V7H3Z"/><path class="cls-2" d="M14,23a7,7,0,1,1,7-7A7,7,0,0,1,14,23Zm0-12a5,5,0,1,0,5,5A5,5,0,0,0,14,11Z"/><path class="cls-2" d="M14,23c-2.23,0-3.4-3.52-3.4-7S11.77,9,14,9s3.4,3.52,3.4,7S16.23,23,14,23Zm0-2h0Zm0-10c-.4.07-1.4,1.9-1.4,5s1,4.93,1.4,5,1.4-1.9,1.4-5S14.4,11.07,14,11Z"/><path class="cls-2" d="M20,17H8a1,1,0,0,1,0-2H20a1,1,0,0,1,0,2Z"/></svg>

After

Width:  |  Height:  |  Size: 991 B

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#c9c1f5;}.cls-2{fill:#6d6daa;}.cls-3{fill:#eef5fd;}</style></defs><title/><rect class="cls-1" height="28" width="28" x="2" y="2"/><path class="cls-2" d="M30,31H2a1,1,0,0,1-1-1V2A1,1,0,0,1,2,1H30a1,1,0,0,1,1,1V30A1,1,0,0,1,30,31ZM3,29H29V3H3Z"/><rect class="cls-3" height="24" width="20" x="6" y="6"/><path class="cls-2" d="M26,31H6a1,1,0,0,1-1-1V6A1,1,0,0,1,6,5H26a1,1,0,0,1,1,1V30A1,1,0,0,1,26,31ZM7,29H25V7H7Z"/><path class="cls-2" d="M16,31a1,1,0,0,1-1-1V6a1,1,0,0,1,2,0V30A1,1,0,0,1,16,31Z"/></svg>

After

Width:  |  Height:  |  Size: 731 B

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#f4dab7;}.cls-2{fill:#6d6daa;}.cls-3{fill:#d6b5b0;}.cls-4{fill:#ff9797;}</style></defs><title/><rect class="cls-1" height="28" width="18" x="7" y="2"/><path class="cls-2" d="M25,31H7a1,1,0,0,1-1-1V2A1,1,0,0,1,7,1H25a1,1,0,0,1,1,1V30A1,1,0,0,1,25,31ZM8,29H24V3H8Z"/><rect class="cls-3" height="4" width="8" x="12" y="22"/><path class="cls-2" d="M20,27H12a1,1,0,0,1-1-1V22a1,1,0,0,1,1-1h8a1,1,0,0,1,1,1v4A1,1,0,0,1,20,27Zm-7-2h6V23H13Z"/><circle class="cls-4" cx="16" cy="9" r="3"/><path class="cls-2" d="M16,13a4,4,0,1,1,4-4A4,4,0,0,1,16,13Zm0-6a2,2,0,1,0,2,2A2,2,0,0,0,16,7Z"/></svg>

After

Width:  |  Height:  |  Size: 812 B

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#d6b5b0;}.cls-2{fill:#6d6daa;}.cls-3{fill:#798bc6;}.cls-4{fill:#c9c1f5;}.cls-5{fill:#ffd599;}.cls-6{fill:#eef5fd;}</style></defs><title/><rect class="cls-1" height="28" width="14" x="6" y="2"/><path class="cls-2" d="M20,31H6a1,1,0,0,1-1-1V2A1,1,0,0,1,6,1H20a1,1,0,0,1,1,1V30A1,1,0,0,1,20,31ZM7,29H19V3H7Z"/><path class="cls-3" d="M12,14H24a2,2,0,0,1,2,2v0a2,2,0,0,1-2,2H12a0,0,0,0,1,0,0V14A0,0,0,0,1,12,14Z"/><path class="cls-2" d="M24,19H12a1,1,0,0,1-1-1V14a1,1,0,0,1,1-1H24a3,3,0,0,1,0,6ZM13,17H24a1,1,0,0,0,0-2H13Z"/><rect class="cls-4" height="3" width="6" x="10" y="5.67"/><path class="cls-2" d="M16,9.67H10a1,1,0,0,1-1-1v-3a1,1,0,0,1,1-1h6a1,1,0,0,1,1,1v3A1,1,0,0,1,16,9.67Zm-5-2h4v-1H11Z"/><circle class="cls-5" cx="13" cy="15.67" r="4"/><path class="cls-2" d="M13,20.67a5,5,0,1,1,5-5A5,5,0,0,1,13,20.67Zm0-8a3,3,0,1,0,3,3A3,3,0,0,0,13,12.67Z"/><rect class="cls-4" height="4" width="14" x="6" y="26"/><path class="cls-2" d="M20,31H6a1,1,0,0,1-1-1V26a1,1,0,0,1,1-1H20a1,1,0,0,1,1,1v4A1,1,0,0,1,20,31ZM7,29H19V27H7Z"/><rect class="cls-6" height="3" width="14" x="6" y="23"/><path class="cls-2" d="M20,27H6a1,1,0,0,1-1-1V23a1,1,0,0,1,1-1H20a1,1,0,0,1,1,1v3A1,1,0,0,1,20,27ZM7,25H19V24H7Z"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#6d6daa;}.cls-2{fill:#ff9797;}.cls-3{fill:#ffd599;}.cls-4{fill:#d6b5b0;}</style></defs><title/><path class="cls-1" d="M14.5,12.5H13.45a1,1,0,0,1,0-2H14.5A8.51,8.51,0,0,0,23,2a1,1,0,0,1,2,0A10.51,10.51,0,0,1,14.5,12.5Z"/><path class="cls-1" d="M8.88,10.48a1,1,0,0,1-.38-.07A1,1,0,0,1,8,9.11,13,13,0,0,1,20,1h4a1,1,0,0,1,0,2H20A11,11,0,0,0,9.8,9.86,1,1,0,0,1,8.88,10.48Z"/><path class="cls-2" d="M14,14a6,6,0,1,0-9,5.19V28l3,2,3-2V26L9,24.5,11,23V19.19A6,6,0,0,0,14,14ZM8,12a2,2,0,1,1-2,2A2,2,0,0,1,8,12Z"/><path class="cls-1" d="M8,31a1,1,0,0,1-.55-.17l-3-2A1,1,0,0,1,4,28V19.74a7,7,0,1,1,8,0V23a1,1,0,0,1-.4.8l-.93.7.93.7a1,1,0,0,1,.4.8v2a1,1,0,0,1-.45.83l-3,2A1,1,0,0,1,8,31ZM6,27.46,8,28.8l2-1.34v-1L8.4,25.3a1,1,0,0,1,0-1.6L10,22.5V19.19a1,1,0,0,1,.5-.86A5,5,0,1,0,3,14a5,5,0,0,0,2.5,4.33,1,1,0,0,1,.5.86ZM11,23h0ZM8,17a3,3,0,1,1,3-3A3,3,0,0,1,8,17Zm0-4a1,1,0,1,0,1,1A1,1,0,0,0,8,13Z"/><polygon class="cls-3" points="30 21 18 21 18 5 24 2 30 5 30 21"/><path class="cls-1" d="M30,22H18a1,1,0,0,1-1-1V5a1,1,0,0,1,.55-.89l6-3a1,1,0,0,1,.9,0l6,3A1,1,0,0,1,31,5V21A1,1,0,0,1,30,22ZM19,20H29V5.62l-5-2.5-5,2.5Z"/><rect class="cls-4" height="5" width="12" x="18" y="16"/><path class="cls-1" d="M30,22H18a1,1,0,0,1-1-1V16a1,1,0,0,1,1-1H30a1,1,0,0,1,1,1v5A1,1,0,0,1,30,22ZM19,20H29V17H19Z"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#eef5fd;}.cls-2{fill:#6d6daa;}.cls-3{fill:#96d7ff;}.cls-4{fill:#798bc6;}</style></defs><title/><rect class="cls-1" height="20" width="28" x="2" y="2"/><path class="cls-2" d="M30,23H2a1,1,0,0,1-1-1V2A1,1,0,0,1,2,1H30a1,1,0,0,1,1,1V22A1,1,0,0,1,30,23ZM3,21H29V3H3Z"/><path class="cls-2" d="M21,31H11a1,1,0,0,1-.75-.34,1,1,0,0,1-.24-.78l1-8A1,1,0,0,1,12,21h8a1,1,0,0,1,1,.88l1,8a1,1,0,0,1-.24.78A1,1,0,0,1,21,31Zm-8.87-2h7.74l-.75-6H12.88Z"/><path class="cls-2" d="M26,31H6a1,1,0,0,1,0-2H26a1,1,0,0,1,0,2Z"/><polygon class="cls-3" points="21 17 11 17 11 9.31 16 7 21 9.31 21 17"/><path class="cls-2" d="M21,18H11a1,1,0,0,1-1-1V9.31a1,1,0,0,1,.58-.91l5-2.31a1,1,0,0,1,.84,0l5,2.31a1,1,0,0,1,.58.91V17A1,1,0,0,1,21,18Zm-9-2h8V10L16,8.1,12,10Z"/><rect class="cls-4" height="4" width="3" x="14.5" y="13"/><path class="cls-2" d="M17.5,18h-3a1,1,0,0,1-1-1V13a1,1,0,0,1,1-1h3a1,1,0,0,1,1,1v4A1,1,0,0,1,17.5,18Zm-2-2h1V14h-1Z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#96d7ff;}.cls-2{fill:#6d6daa;}.cls-3{fill:#c9c1f5;}.cls-4{fill:#eef5fd;}.cls-5{fill:#798bc6;}</style></defs><title/><rect class="cls-1" height="22" width="16" x="8" y="8"/><path class="cls-2" d="M24,31H8a1,1,0,0,1-1-1V8A1,1,0,0,1,8,7H24a1,1,0,0,1,1,1V30A1,1,0,0,1,24,31ZM9,29H23V9H9Z"/><rect class="cls-3" height="4" width="4" x="14" y="4"/><path class="cls-2" d="M18,9H14a1,1,0,0,1-1-1V4a1,1,0,0,1,1-1h4a1,1,0,0,1,1,1V8A1,1,0,0,1,18,9ZM15,7h2V5H15Z"/><rect class="cls-4" height="4" width="8" x="12" y="12"/><path class="cls-2" d="M20,17H12a1,1,0,0,1-1-1V12a1,1,0,0,1,1-1h8a1,1,0,0,1,1,1v4A1,1,0,0,1,20,17Zm-7-2h6V13H13Z"/><path class="cls-2" d="M16,5a1,1,0,0,1-1-1V2a1,1,0,0,1,2,0V4A1,1,0,0,1,16,5Z"/><path class="cls-2" d="M26,31H6a1,1,0,0,1,0-2H26a1,1,0,0,1,0,2Z"/><rect class="cls-5" height="6" width="4" x="14" y="24"/><path class="cls-2" d="M18,31H14a1,1,0,0,1-1-1V24a1,1,0,0,1,1-1h4a1,1,0,0,1,1,1v6A1,1,0,0,1,18,31Zm-3-2h2V25H15Z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#ffc661;}.cls-2{fill:#6d6daa;}.cls-3{fill:#c9c1f5;}.cls-4{fill:#96d7ff;}.cls-5{fill:#798bc6;}.cls-6{fill:#eef5fd;}</style></defs><title/><polygon class="cls-1" points="30 16 2 16 4 12 28 12 30 16"/><path class="cls-2" d="M30,17H2a1,1,0,0,1-.89-1.45l2-4A1,1,0,0,1,4,11H28a1,1,0,0,1,.89.55l2,4A1,1,0,0,1,30,17ZM3.62,15H28.38l-1-2H4.62Z"/><rect class="cls-3" height="24" transform="translate(39 7) rotate(90)" width="14" x="9" y="11"/><path class="cls-2" d="M28,31H4a1,1,0,0,1-1-1V16a1,1,0,0,1,1-1H28a1,1,0,0,1,1,1V30A1,1,0,0,1,28,31ZM5,29H27V17H5Z"/><rect class="cls-3" height="4" width="10" x="11" y="4"/><path class="cls-2" d="M21,9H11a1,1,0,0,1-1-1V4a1,1,0,0,1,1-1H21a1,1,0,0,1,1,1V8A1,1,0,0,1,21,9ZM12,7h8V5H12Z"/><path class="cls-2" d="M16,5a1,1,0,0,1-1-1V2a1,1,0,0,1,2,0V4A1,1,0,0,1,16,5Z"/><path class="cls-2" d="M30,31H2a1,1,0,0,1,0-2H30a1,1,0,0,1,0,2Z"/><rect class="cls-4" height="22" width="14" x="9" y="8"/><path class="cls-2" d="M23,31H9a1,1,0,0,1-1-1V8A1,1,0,0,1,9,7H23a1,1,0,0,1,1,1V30A1,1,0,0,1,23,31ZM10,29H22V9H10Z"/><rect class="cls-5" height="6" width="4" x="14" y="24"/><path class="cls-2" d="M18,31H14a1,1,0,0,1-1-1V24a1,1,0,0,1,1-1h4a1,1,0,0,1,1,1v6A1,1,0,0,1,18,31Zm-3-2h2V25H15Z"/><circle class="cls-6" cx="16" cy="16" r="3"/><path class="cls-2" d="M16,20a4,4,0,1,1,4-4A4,4,0,0,1,16,20Zm0-6a2,2,0,1,0,2,2A2,2,0,0,0,16,14Z"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#6d6daa;}.cls-2{fill:#ffd599;}.cls-3{fill:#eef5fd;}.cls-4{fill:#96d7ff;}.cls-5{fill:#798bc6;}</style></defs><title/><path class="cls-1" d="M26,13H6a1,1,0,0,1-1-1V4A1,1,0,0,1,6,3H26a1,1,0,0,1,1,1v8A1,1,0,0,1,26,13ZM7,11H25V5H7Z"/><rect class="cls-2" height="4" width="4" x="4" y="2"/><path class="cls-1" d="M8,7H4A1,1,0,0,1,3,6V2A1,1,0,0,1,4,1H8A1,1,0,0,1,9,2V6A1,1,0,0,1,8,7ZM5,5H7V3H5Z"/><rect class="cls-2" height="4" width="4" x="24" y="2"/><path class="cls-1" d="M28,7H24a1,1,0,0,1-1-1V2a1,1,0,0,1,1-1h4a1,1,0,0,1,1,1V6A1,1,0,0,1,28,7ZM25,5h2V3H25Z"/><rect class="cls-3" height="18" width="28" x="2" y="12"/><path class="cls-1" d="M30,31H2a1,1,0,0,1-1-1V12a1,1,0,0,1,1-1H30a1,1,0,0,1,1,1V30A1,1,0,0,1,30,31ZM3,29H29V13H3Z"/><polygon class="cls-4" points="22 30 10 30 10 20 16 17 22 20 22 30"/><path class="cls-1" d="M22,31H10a1,1,0,0,1-1-1V20a1,1,0,0,1,.55-.89l6-3a1,1,0,0,1,.9,0l6,3A1,1,0,0,1,23,20V30A1,1,0,0,1,22,31ZM11,29H21V20.62l-5-2.5-5,2.5Z"/><rect class="cls-5" height="5" width="4" x="14" y="25"/><path class="cls-1" d="M18,31H14a1,1,0,0,1-1-1V25a1,1,0,0,1,1-1h4a1,1,0,0,1,1,1v5A1,1,0,0,1,18,31Zm-3-2h2V26H15Z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#ffd599;}.cls-2{fill:#6d6daa;}.cls-3{fill:#ff9797;}.cls-4{fill:#91e085;}.cls-5{fill:#ffc661;}</style></defs><title/><rect class="cls-1" height="20" width="20" x="6" y="10"/><path class="cls-2" d="M26,31H6a1,1,0,0,1-1-1V10A1,1,0,0,1,6,9H26a1,1,0,0,1,1,1V30A1,1,0,0,1,26,31ZM7,29H25V11H7Z"/><rect class="cls-3" height="12" width="12" x="10" y="14"/><path class="cls-2" d="M22,27H10a1,1,0,0,1-1-1V14a1,1,0,0,1,1-1H22a1,1,0,0,1,1,1V26A1,1,0,0,1,22,27ZM11,25H21V15H11Z"/><rect class="cls-4" height="12" width="4" x="14" y="14"/><path class="cls-2" d="M18,27H14a1,1,0,0,1-1-1V14a1,1,0,0,1,1-1h4a1,1,0,0,1,1,1V26A1,1,0,0,1,18,27Zm-3-2h2V15H15Z"/><path class="cls-2" d="M23,11H9a1,1,0,0,1-1-1V4A1,1,0,0,1,9,3H23a1,1,0,0,1,1,1v6A1,1,0,0,1,23,11ZM10,9H22V5H10Z"/><rect class="cls-5" height="4" width="8" x="12" y="2"/><path class="cls-2" d="M20,7H12a1,1,0,0,1-1-1V2a1,1,0,0,1,1-1h8a1,1,0,0,1,1,1V6A1,1,0,0,1,20,7ZM13,5h6V3H13Z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" id="object" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#91e085;}.cls-2{fill:#6d6daa;}.cls-3{fill:#ff9797;}.cls-4{fill:#eef5fd;}.cls-5{fill:#96d7ff;}</style></defs><title/><polygon class="cls-1" points="30 30 2 30 6 20 26 20 30 30"/><path class="cls-2" d="M30,31H2a1,1,0,0,1-.93-1.37l4-10A1,1,0,0,1,6,19H26a1,1,0,0,1,.93.63l4,10A1,1,0,0,1,30,31ZM3.48,29h25l-3.2-8H6.68Z"/><polygon class="cls-3" points="25 30 7 30 9.57 20 22.43 20 25 30"/><path class="cls-2" d="M25,31H7a1,1,0,0,1-1-1.25l2.57-10a1,1,0,0,1,1-.75H22.43a1,1,0,0,1,1,.75l2.57,10A1,1,0,0,1,25,31ZM8.29,29H23.71l-2.06-8H10.35Z"/><path class="cls-4" d="M25,11c0,5-9,15-9,15S7,16,7,11a9,9,0,0,1,18,0Z"/><path class="cls-2" d="M16,27a1,1,0,0,1-.74-.33C14.31,25.61,6,16.2,6,11a10,10,0,0,1,20,0c0,5.2-8.31,14.61-9.26,15.67A1,1,0,0,1,16,27ZM16,3a8,8,0,0,0-8,8c0,3.42,5.23,10.24,8,13.48,2.77-3.24,8-10.06,8-13.48A8,8,0,0,0,16,3Z"/><polygon class="cls-5" points="20 15 12 15 12 10.2 16 7 20 10.2 20 15"/><path class="cls-2" d="M20,16H12a1,1,0,0,1-1-1V10.2a1,1,0,0,1,.38-.78l4-3.2a1,1,0,0,1,1.25,0l4,3.2a1,1,0,0,1,.37.78V15A1,1,0,0,1,20,16Zm-7-2h6V10.68l-3-2.4-3,2.4Z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.4" d="M16.19 2H7.81C4.17 2 2 4.17 2 7.81V16.18C2 19.83 4.17 22 7.81 22H16.18C19.82 22 21.99 19.83 21.99 16.19V7.81C22 4.17 19.83 2 16.19 2Z" fill="#292D32"/>
<path d="M13.0594 12.0001L15.3594 9.70011C15.6494 9.41011 15.6494 8.93011 15.3594 8.64011C15.0694 8.35011 14.5894 8.35011 14.2994 8.64011L11.9994 10.9401L9.69937 8.64011C9.40937 8.35011 8.92937 8.35011 8.63938 8.64011C8.34938 8.93011 8.34938 9.41011 8.63938 9.70011L10.9394 12.0001L8.63938 14.3001C8.34938 14.5901 8.34938 15.0701 8.63938 15.3601C8.78938 15.5101 8.97937 15.5801 9.16937 15.5801C9.35937 15.5801 9.54937 15.5101 9.69937 15.3601L11.9994 13.0601L14.2994 15.3601C14.4494 15.5101 14.6394 15.5801 14.8294 15.5801C15.0194 15.5801 15.2094 15.5101 15.3594 15.3601C15.6494 15.0701 15.6494 14.5901 15.3594 14.3001L13.0594 12.0001Z" fill="#292D32"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1,46 @@
import React from 'react';
import { IonList, IonItem, IonLabel, IonText } from '@ionic/react';
import closeSvg from './close.svg';
interface CloseButtonProps {
onClick: (e: React.UIEvent) => void;
}
const CloseButton: React.FC<CloseButtonProps> = ({ onClick }) => {
return (
<>
<div
style={{
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
width: '25vw',
height: '25vw',
maxWidth: '100px',
maxHeight: '100px',
}}
>
<div
style={{
height: '100%',
width: '100%',
backgroundImage: `url("${closeSvg}")`,
backgroundSize: 'contain',
backgroundPosition: 'center',
backgroundRepeat: 'no-repeat',
}}
onClick={onClick}
/>
<IonText>
<h5>Close</h5>
</IonText>
</div>
</>
);
};
export default React.memo(CloseButton);

View File

@@ -0,0 +1,71 @@
import React, { useState } from 'react';
import {
IonHeader,
IonTitle,
IonToolbar,
IonContent,
IonPage,
IonButtons,
IonBadge,
IonMenuButton,
IonButton,
IonIcon,
IonDatetime,
IonSelectOption,
IonList,
IonItem,
IonLabel,
IonSelect,
IonPopover,
IonText,
IonCard,
IonCardHeader,
IonCardTitle,
IonCardSubtitle,
IonCardContent,
IonTabs,
IonTabBar,
IonTabButton,
IonSegment,
IonSegmentButton,
useIonRouter,
IonSearchbar,
IonRow,
IonCol,
} from '@ionic/react';
// const ProductCard: React.FC = ({product}) =>
function ProductCard({ product }: { product: any }) {
return (
<>
<IonCard
style={{ width: '45%', minWidth: '120px' }}
button
onClick={(e) => console.log('helloworld')}
>
<div
style={{
backgroundSize: 'cover',
backgroundPosition: 'center',
backgroundRepeat: 'no-repeat',
backgroundImage: `url("${product.avatar}")`,
height: '100px',
width: '100%',
}}
></div>
<IonCardHeader style={{ padding: '0.5rem' }}>
<IonCardTitle style={{ fontSize: '0.8rem' }}>
{'#html #css #開發 #指導 #代做 #電子平台 #programming #coding #javascript #python #react #debug'
.split('')
.slice(0, 20)}
</IonCardTitle>
<IonCardSubtitle>Card Subtitle</IonCardSubtitle>
</IonCardHeader>
<IonCardContent>View Insights</IonCardContent>
</IonCard>
</>
);
}
export default ProductCard;

View File

@@ -0,0 +1,46 @@
import {
IonCard,
IonCardHeader,
IonCardTitle,
IonCardSubtitle,
IonCardContent,
} from '@ionic/react';
// const ProductCard: React.FC = ({product}) =>
function TopPicksProductCard({ product }: { product: any }) {
return (
<>
<IonCard
style={{
marginInline: 0,
width: '100%',
}}
button
onClick={(e) => console.log('helloworld')}
>
<div
style={{
backgroundSize: 'cover',
backgroundPosition: 'center',
backgroundRepeat: 'no-repeat',
backgroundImage: `url("${product.avatar}")`,
height: '100px',
width: '100%',
}}
></div>
<IonCardHeader style={{ padding: '0.1rem' }}>
<IonCardTitle style={{ fontSize: '0.8rem' }}>
{'#html #css #開發 #指導 #代做 #電子平台 #programming #coding #javascript #python #react #debug'
.split('')
.slice(0, 20)}
</IonCardTitle>
<IonCardSubtitle>Card Subtitle</IonCardSubtitle>
</IonCardHeader>
<IonCardContent>View Insights</IonCardContent>
</IonCard>
</>
);
}
export default TopPicksProductCard;

View File

@@ -1,14 +1,23 @@
import React, { createContext, PropsWithChildren, useReducer } from 'react';
import { initialState, AppState, reducers } from './state';
import { Storage, Drivers } from '@ionic/storage';
const browser_store = new Storage({
name: '__mydb',
driverOrder: [Drivers.LocalStorage, Drivers.IndexedDB],
});
export interface AppContextState {
state: AppState;
dispatch: React.Dispatch<any>;
browser_store: any;
}
export const AppContext = createContext<AppContextState>({
state: initialState,
dispatch: () => undefined,
browser_store: {},
});
export const AppContextProvider: React.FC<PropsWithChildren> = ({ children }) => {
@@ -19,9 +28,13 @@ export const AppContextProvider: React.FC<PropsWithChildren> = ({ children }) =>
value={{
state: store,
dispatch,
//
browser_store,
}}
>
{children}
</AppContext.Provider>
);
};
//

View File

@@ -0,0 +1,8 @@
import React from 'react';
function Following({ hide }: { hide: boolean }) {
if (hide) return <></>;
return <>Following</>;
}
export default Following;

View File

@@ -0,0 +1,8 @@
import React from 'react';
function FreeItems({ hide }: { hide: boolean }) {
if (hide) return <></>;
return <>FreeItems</>;
}
export default FreeItems;

View File

@@ -0,0 +1,8 @@
import React from 'react';
function Nearby({ hide }: { hide: boolean }) {
if (hide) return <></>;
return <>Nearby</>;
}
export default Nearby;

View File

@@ -0,0 +1,57 @@
import { useState, useEffect } from 'react';
import { IonCol, IonRow, IonGrid } from '@ionic/react';
import getTopPicks from '../../../api/getTopPicks';
import TopPicksProductCard from '../../../components/TopPicksProductCard';
import { IonInfiniteScrollCustomEvent } from '@ionic/core';
function TopPicks({ hide }: { hide: boolean }) {
const [items, setItems] = useState<string[]>([]);
const [topPicks, setTopPicks] = useState<any>([]);
const generateItems = () => {
const newItems = [];
for (let i = 0; i < 50; i++) {
newItems.push(`Item ${1 + items.length + i}`);
}
setItems([...items, ...newItems]);
};
const initialLoadTopPicks = () => {
getTopPicks().then((res: any) => setTopPicks(res));
};
const loadTopPicksOnScroll = (ev: IonInfiniteScrollCustomEvent<void>) => {
getTopPicks()
.then((res: any) => setTopPicks([...topPicks, ...res]))
.then(() => {
ev.target.complete();
});
};
useEffect(() => {
generateItems();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
initialLoadTopPicks();
}, []);
if (hide) return <></>;
return (
<>
<div style={{ width: '100%' }}>
<IonGrid>
<IonRow class="ion-justify-content-start">
{topPicks.map((product: any) => (
<IonCol size="6">
<TopPicksProductCard product={product} />
</IonCol>
))}
</IonRow>
</IonGrid>
</div>
</>
);
}
export default TopPicks;

View File

@@ -0,0 +1,429 @@
import {
createGesture,
IonBackButton,
IonButton,
IonButtons,
IonChip,
IonCol,
IonContent,
IonGrid,
IonHeader,
IonIcon,
IonItem,
IonItemDivider,
IonItemGroup,
IonLabel,
IonList,
IonPage,
IonPopover,
IonRefresher,
IonRefresherContent,
IonRow,
IonSegment,
IonSegmentButton,
// IonSlide,
// IonSlides,
IonText,
IonToolbar,
RefresherEventDetail,
IonCard,
} from '@ionic/react';
import React, { useEffect, useRef, useState } from 'react';
// import { SuperTabsContainer, SuperTab, SuperTabs, SuperTabsToolbar, SuperTabButton } from '@ionic-super-tabs/react';
import {
star,
home,
heart,
pin,
call,
globe,
basket,
barbell,
trash,
person,
} from 'ionicons/icons';
import {
mailSharp,
chevronDownSharp,
chevronForwardSharp,
arrowBackSharp,
starOutline,
share,
chevronDownCircleOutline,
chevronForwardOutline,
chatbubblesOutline,
menuOutline,
} from 'ionicons/icons';
import ProductCard from '../../../components/ProductCard';
//
import getSuggestedCategory from '../../../api/getSuggestedCategory';
import getProductList from '../../../api/getProductList';
import getTopSearches from '../../../api/getTopSearches';
import getCategory from '../../../api/getCategory';
import getYourDailyPicks from '../../../api/getYourDailyPicks';
import getFreshFinds from '../../../api/getFreshFinds';
import getSegments from '../../../api/getSegments';
import TopPicks from './TopPicks';
import Following from './Following';
import FreeItems from './FreeItems';
import Nearby from './Nearby';
import './style.scss';
interface CarousellHome {}
const Card = () => (
<>
<IonCard>HelloCard</IonCard>
</>
);
const CarousellHome: React.FC<CarousellHome> = () => {
const [showPopover, setShowPopover] = useState(false);
const [popoverEvent, setPopoverEvent] = useState<MouseEvent>();
const [location, setLocation] = useState<'madison' | 'austin' | 'chicago' | 'seattle'>('madison');
const [conferenceDate, setConferenceDate] = useState('2047-05-17T00:00:00-05:00');
const pageRef = useRef();
const handleRefresh = (event: CustomEvent<RefresherEventDetail>) => {
setTimeout(() => {
// Any calls to load data go here
event.detail.complete();
}, 2000);
};
const [suggestedCategories, setSuggestedCategories] = useState<string[]>([]);
useEffect(() => {
getSuggestedCategory().then((res: any) => setSuggestedCategories(res));
}, []);
const [categories, setCategories] = useState<any>([]);
useEffect(() => {
getCategory().then((res: any) => setCategories(res));
}, []);
const [productList, setProductList] = useState<any>([]);
useEffect(() => {
getProductList().then((res: any) => setProductList(res));
}, []);
const [yourDailyPicks, setYourDailyPicks] = useState<any>([]);
useEffect(() => {
getYourDailyPicks().then((res: any) => setYourDailyPicks(res));
}, []);
const [freshFinds, setFreshFinds] = useState<any>([]);
useEffect(() => {
getFreshFinds().then((res: any) => setFreshFinds(res));
}, []);
const [topSearches, setTopSearches] = useState<any>([]);
useEffect(() => {
getTopSearches().then((res: any) => setTopSearches(res));
}, []);
const [categorySegments, setCategorySegments] = useState<any>([]);
const [segment, setSegment] = useState<string>('');
useEffect(() => {
getSegments().then((res: any) => {
setCategorySegments(res);
setSegment(res[0].slug);
});
}, []);
const onMove = (detail: any) => {
console.log({ detail });
};
const segmentRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (segmentRef?.current) {
const gesture = createGesture({
gestureName: 'helloworld',
el: segmentRef.current,
onMove: (detail) => {
onMove(detail);
},
});
gesture.enable();
}
}, [segmentRef]);
// const slider = useRef<HTMLIonSlidesElement>(null);
const [value, setValue] = useState('0');
const slideOpts = {
initialSlide: 0,
speed: 400,
loop: false,
pagination: {
el: null,
},
};
const handleSlideChange = async (event: any) => {
let index: number = 0;
await event.target.getActiveIndex().then((value: any) => {
index = value;
});
setSegment(categorySegments[index].slug);
setValue('' + index);
};
return (
<IonPage id="carousell-home-page" style={{ marginBottom: '3rem' }}>
<IonHeader>
<IonToolbar>
<IonButtons slot="start">CarousellLogo</IonButtons>
<IonButtons slot="end">
<IonButton onClick={() => {}}>
<IonIcon slot="icon-only" icon={chatbubblesOutline}></IonIcon>
</IonButton>
<IonButton onClick={() => {}}>
<IonIcon slot="icon-only" icon={menuOutline}></IonIcon>
</IonButton>
</IonButtons>
</IonToolbar>
</IonHeader>
<IonContent>
<div style={{}}>
<div style={{ margin: '0.5rem 0.5rem' }}>
<h5> </h5>
</div>
<div style={{ margin: '0.5rem 0.5rem' }}>
<div style={{ height: '75px', width: '100%', backgroundColor: 'tomato' }}>
top button placeholder
</div>
</div>
<div style={{ margin: '0.5rem 0.5rem' }}>
<div style={{ height: '150px', width: '100%', backgroundColor: 'tomato' }}>
slider placeholder
</div>
</div>
</div>
<div style={{ margin: '0rem 0.5rem' }}>
<IonList>
<IonItemGroup>
<IonItemDivider style={{ padding: 0, margin: 0, border: 'none', color: 'black' }}>
<h6>Looks like your kinda thing</h6>
</IonItemDivider>
<div style={{ overflowX: 'scroll', width: '100%' }}>
<div
style={{
display: 'flex',
flexDirection: 'row',
whiteSpace: 'nowrap',
margin: '0.5rem 0',
}}
>
{suggestedCategories.map((category: any, index: number) => (
<div key={index}>
<IonChip outline>{category}</IonChip>
</div>
))}
</div>
</div>
</IonItemGroup>
<IonItemGroup>
<IonItemDivider style={{ padding: 0, margin: 0, border: 'none', color: 'black' }}>
<h6>Explore Carousell</h6>
</IonItemDivider>
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
}}
></div>
<div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'flexStart' }}>
<div
style={{
height: '180px',
display: 'flex',
flexDirection: 'column',
flexWrap: 'wrap',
gap: '5px',
overflowX: 'scroll',
width: '100%',
justifyContent: 'flex-start',
alignItems: 'flex-start',
}}
>
{categories.map((category: any, index: number) => (
<div
key={index}
style={{
width: '80px',
minHeight: '80px',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}}
>
<div
style={{
width: '50px',
height: '50px',
borderRadius: '25px',
backgroundColor: 'gold',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
boxShadow: 'rgba(0, 0, 0, 0.35) 0px 5px 15px',
}}
>
<div
style={{
width: '30px',
height: '30px',
backgroundImage: `url("${category.avatar}")`,
backgroundSize: 'cover',
backgroundPosition: 'center',
backgroundRepeat: 'no-repeat',
}}
></div>
</div>
<div style={{ marginTop: '0.5rem', fontSize: '0.6rem', textAlign: 'center' }}>
{category.name || ''}
</div>
</div>
))}
</div>
</div>
<div style={{ overflowX: 'scroll', padding: '1rem 0rem' }}>
<div style={{ display: 'flex', flexDirection: 'row', whiteSpace: 'nowrap' }}></div>
</div>
</IonItemGroup>
<IonItemGroup>
<IonItemDivider
sticky
style={{ padding: 0, margin: 0, border: 'none', color: 'black' }}
>
<h6>Your Daily Picks</h6>
</IonItemDivider>
<div style={{ width: '100%', overflowX: 'scroll' }}>
<div style={{ display: 'flex', flexDirection: 'row' }}>
{yourDailyPicks.map((product: any, index: number) => (
<ProductCard key={index} product={product} />
))}
</div>
</div>
</IonItemGroup>
<IonItemGroup>
<IonItemDivider
sticky
style={{ padding: 0, margin: 0, border: 'none', color: 'black' }}
>
<h6>Fresh Finds</h6>
</IonItemDivider>
<div style={{ width: '100%', overflowX: 'scroll' }}>
<div style={{ display: 'flex', flexDirection: 'row' }}>
{freshFinds.map((product: any, index: number) => (
<ProductCard key={index} product={product} />
))}
</div>
</div>
</IonItemGroup>
<IonItemGroup>
<IonItemDivider
sticky
style={{ padding: 0, margin: 0, border: 'none', color: 'black' }}
>
<h6>Top searches</h6>
</IonItemDivider>
<div style={{ width: '100%', overflowX: 'scroll' }}>
<div style={{ display: 'flex', flexDirection: 'row' }}>
{freshFinds.map((product: any, index: number) => (
<ProductCard key={index} product={product} />
))}
</div>
</div>
</IonItemGroup>
<IonItemGroup>
<IonItemDivider
sticky
style={{ padding: 0, margin: 0, border: 'none', color: 'black' }}
>
<IonSegment
value={segment}
scrollable
onIonChange={(e) => {
console.log(e.target);
setSegment(e.detail.value as any);
}}
selectOnFocus
>
{categorySegments.map((seg: any, index: number) => (
<IonSegmentButton key={index} value={seg.slug}>
<IonLabel>{seg.name}</IonLabel>
</IonSegmentButton>
))}
</IonSegment>
</IonItemDivider>
<IonItem id="top-picks">ion slide should be here</IonItem>
</IonItemGroup>
</IonList>
</div>
<div>
<IonText>
<h6>Follow Us</h6>
</IonText>
<div>2023 louiscklaw</div>
<div>Help Centre</div>
<div>Contact Us</div>
<div>Press</div>
<div>Jobs</div>
<div>Advertise with Us</div>
<div>Terms</div>
<div>Privacy</div>
</div>
<div>
<div>English</div>
</div>
<div style={{ fontSize: '0.5rem' }}>
Explore Carousell Following Computers & Tech Women's Fashion Men's Fashion Beauty &
Personal Care Free Items Audio Furniture & Home Living Babies & Kids Health & Nutrition
Food & Drinks Tickets & Vouchers Auto Accessories Community Looking For Announcements
Services Mobile Phones & Gadgets Property Cars Luxury Video Gaming Photography TV & Home
Appliances Hobbies & Toys Sports Equipment Pet Supplies Motorbikes Jobs Preorders
Everything Else
</div>
<IonRefresher slot="fixed" onIonRefresh={handleRefresh}>
<IonRefresherContent
pullingIcon={chevronDownCircleOutline}
pullingText="Pull to refresh"
refreshingSpinner="circles"
refreshingText="Refreshing..."
></IonRefresherContent>
</IonRefresher>
<div style={{}}>CarousellHome</div>
</IonContent>
</IonPage>
);
};
export default React.memo(CarousellHome);

View File

@@ -0,0 +1,32 @@
#carousell-home-page {
::-webkit-scrollbar,
*::-webkit-scrollbar {
display: none;
}
ion-slides {
--offset-bottom: auto !important;
--overflow: hidden;
overflow: auto;
&::-webkit-scrollbar {
display: none;
}
}
#top-pick-product-list {
ion-card {
--margin-inline: 0;
}
}
#top-picks {
--padding-start: 0;
--inner-padding-start: 0;
--padding-end: 0;
--inner-padding-end: 0;
ion-item {
--background: gold;
}
}
}

View File

@@ -0,0 +1,410 @@
import {
IonBackButton,
IonBreadcrumb,
IonBreadcrumbs,
IonButton,
IonButtons,
IonChip,
IonContent,
IonIcon,
IonPage,
IonText,
IonToolbar,
ScrollDetail,
useIonRouter,
useIonViewDidEnter,
useIonViewWillEnter,
useIonViewWillLeave,
IonCard,
} from '@ionic/react';
import {
heartOutline,
shareOutline,
flagOutline,
timerOutline,
pricetagOutline,
} from 'ionicons/icons';
import React, { useContext, useEffect, useRef, useState } from 'react';
// import AboutPopover from '../../components/AboutPopover';
import { useIonAlert } from '@ionic/react';
import StarRatings from 'react-star-ratings';
import './style.scss';
import { AppContext } from '../../../data/AppContext';
import { createGesture } from '@ionic/react';
import ReactMarkdown from 'react-markdown';
import getUnsplashRandomImage from '../../../api/getUnsplashRandomImage';
const ContentMd = `helloworld`.trim();
const userJson = {
avatar: getUnsplashRandomImage({ keyword: 'hotel' }),
name: 'louis_coding',
since: 'Joined 4 years ago',
verified: true,
rating: 5.0,
total_comment: 37,
};
const productSample = {
category: { main: 'Services', sub_cat: ['Learning & Enrichment', 'Enrichment & Tuition'] },
avatar: getUnsplashRandomImage({ keyword: 'hotel' }),
title: '#html #css #開發 #指導 ',
price: 30,
content: ContentMd,
user: userJson,
};
const commentSample = {
user: userJson,
content: '準時有禮',
product: productSample,
time: '5 days',
properties: 'Review from seller',
};
const commentList = [commentSample, commentSample, commentSample, commentSample, commentSample];
const productList = [
productSample,
productSample,
productSample,
productSample,
productSample,
productSample,
];
interface ProductPageProps {}
const ProductPage: React.FC<ProductPageProps> = () => {
const [showPopover, setShowPopover] = useState(false);
const [popoverEvent, setPopoverEvent] = useState<MouseEvent>();
const [location, setLocation] = useState<'madison' | 'austin' | 'chicago' | 'seattle'>('madison');
const [conferenceDate, setConferenceDate] = useState('2047-05-17T00:00:00-05:00');
const [showAlert, hideAlert] = useIonAlert();
const { browser_store } = useContext(AppContext);
const refRectangle = useRef<HTMLDivElement>(null);
const [swipeType, setSwipeType] = useState();
const [deltaX, setDeltaX] = useState();
const [velocityX, setVelocityX] = useState();
const [swipeVerdict, setSwipeVerdict] = useState('helloworld');
const contentRef = useRef<HTMLIonContentElement>(null);
const route = useIonRouter();
const [maxBreadcrumbs, setMaxBreadcrumbs] = useState<number | undefined>(2);
const [isPageTop, setIsPageTop] = useState(true);
useEffect(() => {
if (swipeVerdict == 'swipe-left')
if (route.canGoBack() == true) {
route.goBack();
} else {
route.push('/tabs/schedule');
}
}, [swipeVerdict]);
useIonViewWillEnter(() => {});
useIonViewWillLeave(() => {});
const onMove = (detail: any) => {
const type = detail.type;
const currentX = detail.currentX;
const deltaX = detail.deltaX;
const velocityX = detail.velocityX;
setSwipeType(type);
setDeltaX(deltaX);
setVelocityX(velocityX);
if (type == 'pan')
if (Math.abs(deltaX) > 50)
if (velocityX > 0) {
setSwipeVerdict('swipe-right');
} else {
setSwipeVerdict('swipe-left');
}
};
useIonViewDidEnter(() => {
let gesture: any = {};
if (refRectangle?.current) {
gesture = createGesture({
gestureName: 'helloworld',
el: refRectangle.current,
onMove: (detail) => {
onMove(detail);
},
});
gesture.enable();
}
return () => {
gesture?.destroy();
};
}, [refRectangle]);
return (
<IonPage id="product-page">
<IonContent
ref={contentRef}
scrollEvents={true}
onIonScroll={(ev: CustomEvent<ScrollDetail>) => {
if (ev.detail.deltaY > 10) {
setIsPageTop(false);
} else {
setIsPageTop(true);
}
}}
>
<div style={{ position: 'fixed', top: 0, width: '100%', height: 0 }}>
<IonToolbar
className="toolbar"
mode="md"
style={{
'--background': isPageTop ? 'none' : 'white',
'--color': isPageTop ? 'white' : 'black',
'--border-style': 'none',
}}
>
<IonButtons slot="start">
<IonBackButton defaultHref="/tabs/schedule"></IonBackButton>
</IonButtons>
<IonButtons slot="end">
<IonButton onClick={() => {}}>
<IonIcon slot="icon-only" icon={shareOutline}></IonIcon>
</IonButton>
<IonButton onClick={() => {}}>
<IonIcon slot="icon-only" icon={flagOutline}></IonIcon>
</IonButton>
</IonButtons>
</IonToolbar>
</div>
<img src={getUnsplashRandomImage({ keyword: 'helloworld' })} width="100%" />
<div style={{ padding: '1rem', marginBottom: '3rem' }}>
<IonBreadcrumbs
maxItems={maxBreadcrumbs}
onIonCollapsedClick={() => setMaxBreadcrumbs(undefined)}
>
<IonBreadcrumb href="#home" style={{ fontSize: '0.8rem' }}>
{productSample.category.main}
</IonBreadcrumb>
<IonBreadcrumb href="#electronics" style={{ fontSize: '0.8rem' }}>
{productSample.category.sub_cat[0]}
</IonBreadcrumb>
<IonBreadcrumb href="#cameras" style={{ fontSize: '0.8rem' }}>
{productSample.category.sub_cat[1]}
</IonBreadcrumb>
</IonBreadcrumbs>
<IonText>
<h4>{productSample.title}</h4>
</IonText>
<div
style={{
margin: '0.5rem 0',
fontSize: '1rem',
color: 'grey',
display: 'flex',
flexDirection: 'column',
gap: '0.5rem',
}}
>
<IonText className="product-properties">
<IonIcon icon={timerOutline} />
10 hours ago by kylema11201
</IonText>
<IonText className="product-properties">
<IonIcon icon={pricetagOutline} />
HK$0
</IonText>
<IonText className="product-properties">
<IonIcon icon={heartOutline} />
234 Likes
</IonText>
<IonText className="product-properties">In Enrichment & Tuition</IonText>
<IonText className="product-properties">Type of Rate Hourly</IonText>
</div>
<p>
<ReactMarkdown>{productSample.content}</ReactMarkdown>
</p>
<IonButton fill="clear" size="small">
read more
</IonButton>
<IonText className="product-properties">
<p>Kowloon Tong ()</p>
</IonText>
<IonText className="product-properties">
<p>Region Kowloon</p>
</IonText>
<IonText className="product-properties">
<p>Tutor Qualification Master's</p>
</IonText>
<IonText className="product-properties">
<p>Type of Tutor Full-Time Tutor</p>
</IonText>
<IonText className="product-properties">
<p>Levels to Tutor University, Asso, IVE, Secondary</p>
</IonText>
<IonText className="product-properties">
<p>Subjects Stem, Computer Science, IT</p>
</IonText>
<IonText className="product-properties">
<p>Preferred Days / Times TBA</p>
</IonText>
<IonText>Share This Listing</IonText>
Advertisement
<div style={{ width: '100%', height: '300px' }}></div>
<div className="seller-properties" style={{ padding: 0, margin: 0 }}>
<h4>Meet The Seller</h4>
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'flex-start',
gap: '1rem',
}}
>
<div style={{ width: '80px', height: '80px' }}>
<img src={productSample.user.avatar} style={{ borderRadius: '40px' }} />
</div>
<div>
<p>
{productSample.user.name}
<br />
{productSample.user.since}
<br />
{productSample.user.verified ? 'Verified' : 'not Verified'}
<br />
<StarRatings
rating={3}
starRatedColor="green"
changeRating={() => {}}
numberOfStars={5}
name="rating"
starDimension="1rem"
starSpacing="0px"
//
/>
{productSample.user.rating} ({productSample.user.total_comment})<br />
</p>
</div>
</div>
</div>
{commentList.map((commentJson) => (
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'flex-start',
gap: '1rem',
}}
>
<div>
<img
src={commentJson.user.avatar}
width="30px"
height="30px"
style={{ borderRadius: '15px' }}
></img>
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
<div>{commentJson.user.name}</div>
<div>{commentJson.content}</div>
<div
style={{
backgroundColor: 'lightgrey',
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
gap: '1rem',
padding: '0.5rem',
borderRadius: '10px',
}}
>
<div
style={{
backgroundImage: `url("${commentJson.product.avatar}")`,
backgroundSize: 'cover',
backgroundPosition: 'center',
borderRadius: '10px',
width: '80px',
height: '80px',
}}
></div>
<div
style={{
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-start',
gap: '0.5rem',
}}
>
<div style={{ fontWeight: 'bold', fontSize: '0.8rem' }}>
{commentJson.product.title}
</div>
<div style={{ fontSize: '0.8rem' }}>HK${commentJson.product.price}</div>
</div>
</div>
<div className="txt-grey" style={{ fontSize: '0.8rem' }}>
{commentJson.time}∙{commentJson.properties}
</div>
</div>
</div>
))}
<IonButton fill="clear" routerLink={'/tabs/carousell/product/comments'}>
Read all
</IonButton>
<div className="search-suggestion">
<h3>What others also search for</h3>
<div>
<IonChip color="primary">mirror </IonChip>
<IonChip color="primary">mirror </IonChip>
<IonChip color="primary">maskon mirror</IonChip>
<IonChip color="primary">mirror pin</IonChip>
<IonChip color="primary"></IonChip>
<IonChip color="primary">csl mirror card</IonChip>
<IonChip color="primary">mirror yes card</IonChip>
<IonChip color="primary">mirror csl </IonChip>
<IonChip color="primary">error yes card</IonChip>
<IonChip color="primary">mirror tee</IonChip>
</div>
</div>
{/* similar-listings */}
<div className="similar-listings">
<h3>Similar listings</h3>
<div className="product-listing">
{productList.map((product) => (
<IonCard>
<div className="helloworld-product-card">
<div
className="product-image"
style={{ backgroundImage: `url("${product.avatar}")` }}
></div>
<div className="product-title">{product.title}</div>
<div className="product-price">HK${product.price}</div>
</div>
</IonCard>
))}
</div>
</div>
</div>
</IonContent>
</IonPage>
);
};
export default React.memo(ProductPage);

View File

@@ -0,0 +1,47 @@
.product-properties {
display: flex;
flex-direction: row;
align-items: center;
ion-icon {
margin-right: 1rem;
}
}
#product-page {
.txt-grey {
color: grey;
}
.product-listing {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
gap: 4%;
row-gap: calc(100vw * 0.04);
}
ion-card {
width: 48%;
margin: 0;
padding: 0;
.product-image {
background-size: cover;
background-position: center;
background-repeat: no-repeat;
width: 100%;
height: 100px;
}
.product-name {
font-weight: bold;
font-size: 0.9rem;
}
.product-price {
font-size: 0.8rem;
}
}
}

View File

@@ -0,0 +1,130 @@
import React, { useState } from 'react';
// import { useTranslation } from 'react-i18next';
// import StarRatings from 'react-star-ratings';
import {
IonHeader,
IonTitle,
IonToolbar,
IonContent,
IonPage,
IonButtons,
IonBadge,
IonMenuButton,
IonButton,
IonIcon,
IonDatetime,
IonSelectOption,
IonList,
IonItem,
IonLabel,
IonSelect,
IonPopover,
IonText,
IonCard,
IonCardHeader,
IonCardTitle,
IonCardSubtitle,
IonCardContent,
IonTabs,
IonTabBar,
IonTabButton,
IonSegment,
IonSegmentButton,
useIonRouter,
} from '@ionic/react';
import './style.scss';
import {
locationSharp,
settingsOutline,
qrCode,
shareSocialOutline,
ellipsisHorizontal,
ellipsisVertical,
logoFacebook,
phonePortraitSharp,
pricetagSharp,
archiveSharp,
calendar,
personCircle,
map,
informationCircle,
mailSharp,
chevronDownSharp,
chevronForwardSharp,
} from 'ionicons/icons';
// import AboutPopover from '../../components/AboutPopover';
import { format, parseISO } from 'date-fns';
import lookForVisitorSvg from './look_for_visitor.svg';
type SessionListProps = {
hide: boolean;
};
const AboutContent: React.FC<SessionListProps> = ({ hide }) => {
let route = useIonRouter();
if (hide) return <></>;
return (
<>
<div
style={{
//
paddingTop: '1rem',
paddingLeft: '1rem',
paddingRight: '1rem',
display: 'flex',
flexDirection: 'column',
gap: '1rem',
}}
>
<div>
<IonText color="tertiary" style={{ fontSize: '0.8rem' }}>
<IonText style={{ fontWeight: 'bold' }} color="success">
25
</IonText>
<IonText>Followers</IonText>
{' '}
<IonText style={{ fontWeight: 'bold' }} color="success">
0
</IonText>
<IonText>Followers</IonText>
</IonText>
</div>
<div
style={{
paddingBottom: '3rem',
}}
>
<IonText style={{ fontSize: '0.9rem' }}>
<p> payme / / FPS</p>
<p>Accepting HSBC payme / alipay / FPS </p>
<p> / for more detail:</p>
<p>https://louiscklaw.github.io/carousell </p>
<p>PM查詢</p>
</IonText>
</div>
</div>
{/* private information */}
<IonList>
<IonItem lines="none">
<h3>Private information</h3>
</IonItem>
<IonItem
lines="full"
button
onClick={(e) => {
route.push('/tabs/carousell_me/OffersMade');
}}
>
<IonText style={{ fontSize: '0.9rem' }}>My Offers</IonText>
</IonItem>
</IonList>
</>
);
};
export default AboutContent;

View File

@@ -0,0 +1,167 @@
import React, { useState } from 'react';
// import { useTranslation } from 'react-i18next';
// import StarRatings from 'react-star-ratings';
import {
IonHeader,
IonTitle,
IonToolbar,
IonContent,
IonPage,
IonButtons,
IonBadge,
IonMenuButton,
IonButton,
IonIcon,
IonDatetime,
IonSelectOption,
IonList,
IonItem,
IonLabel,
IonSelect,
IonPopover,
IonText,
IonCard,
IonCardHeader,
IonCardTitle,
IonCardSubtitle,
IonCardContent,
IonTabs,
IonTabBar,
IonTabButton,
IonSegment,
IonSegmentButton,
useIonRouter,
IonSearchbar,
IonRow,
IonCol,
} from '@ionic/react';
import './style.scss';
import {
locationSharp,
settingsOutline,
qrCode,
shareSocialOutline,
ellipsisHorizontal,
ellipsisVertical,
logoFacebook,
phonePortraitSharp,
pricetagSharp,
archiveSharp,
calendar,
personCircle,
map,
informationCircle,
mailSharp,
chevronDownSharp,
chevronForwardSharp,
filterSharp,
filter,
} from 'ionicons/icons';
// import AboutPopover from '../../components/AboutPopover';
import { format, parseISO } from 'date-fns';
// import lookForVisitorSvg from './look_for_visitor.svg';
const SellingButton: React.FC = () => {
const router = useIonRouter();
return (
<>
<div style={{ width: '50%' }}>
<IonCard
style={{ margin: '0.5rem' }}
button
onClick={(e) => {
window.location.href =
'https://www.carousell.com.hk/p/coding-javascript-python-vba-freelance-1192889425/';
}}
>
<img
alt="Silhouette of mountains"
src="https://ionicframework.com/docs/img/demos/card-media.png"
/>
<IonCardHeader style={{ padding: '0.5rem' }}>
<IonCardTitle style={{ fontSize: '0.8rem' }}>
{'#html #css #開發 #指導 #代做 #電子平台 #programming #coding #javascript #python #react #debug'
.split('')
.slice(0, 20)}
</IonCardTitle>
<IonCardSubtitle>Card Subtitle</IonCardSubtitle>
</IonCardHeader>
<IonCardContent>View Insights</IonCardContent>
</IonCard>
</div>
</>
);
};
type SessionListProps = {
hide: boolean;
};
const ListingsContent: React.FC<SessionListProps> = ({ hide }) => {
let route = useIonRouter();
let [openExplain, setOpenExplain] = useState(false);
if (hide) return <></>;
return (
<>
<div id="listing-content">
<div style={{ marginTop: '0.5rem', paddingLeft: '0.5rem', paddingRight: '0.5rem' }}>
<IonText style={{ fontWeight: 'bold' }}>33 Listings</IonText>
<IonSearchbar
mode={'ios'}
placeholder="Search the seller's listings"
style={{ padding: 0 }}
></IonSearchbar>
<div style={{ fontSize: '0.75rem', display: 'flex', justifyContent: 'space-between' }}>
<IonButton size="small" fill="outline" onClick={(e) => setOpenExplain(true)}>
<IonIcon slot="end" icon={filter} style={{ fontSize: '0.75rem' }}></IonIcon>
<div style={{ fontSize: '0.75rem' }}>Filters</div>
</IonButton>
<IonButton size="small" fill="outline" style={{ fontSize: '0.75rem' }}>
<IonText>{`Status: ${'All'}`}</IonText>
</IonButton>
<IonButton size="small" fill="outline" style={{ fontSize: '0.75rem' }}>
<IonText>{`In: All Categories`}</IonText>
</IonButton>
</div>
</div>
{/* Sell listing */}
<div
style={{
width: '100%',
display: 'flex',
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'flex-start',
}}
>
<SellingButton />
<SellingButton />
<SellingButton />
</div>
<div
style={{
height: '5rem',
color: 'lightgray',
display: 'inline-flex',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
//
width: '100%',
}}
>
end of list
</div>
</div>
</>
);
};
export default ListingsContent;

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@@ -0,0 +1,8 @@
#listing-content {
ion-button {
--padding-start: 5px;
--padding-end: 5px;
--padding-top: 5px;
--padding-bottom: 5px;
}
}

View File

@@ -0,0 +1,201 @@
import {
IonBackButton,
IonButton,
IonButtons,
IonCol,
IonContent,
IonGrid,
IonHeader,
IonIcon,
IonInput,
IonItem,
IonLabel,
IonList,
IonMenuButton,
IonPage,
IonPopover,
IonRow,
IonText,
IonTitle,
IonToolbar,
useIonRouter,
useIonViewDidEnter,
} from '@ionic/react';
import { star, starOutline, checkmarkDoneOutline } from 'ionicons/icons';
import React, { useContext, useEffect, useRef, useState } from 'react';
// import AboutPopover from '../../components/AboutPopover';
import { useIonAlert } from '@ionic/react';
import './style.scss';
import { AppContext } from '../../../data/AppContext';
import {
createGesture,
// Gesture
} from '@ionic/react';
import { useTranslation } from 'react-i18next';
// import { ImgPrinterSvg, ImgRiceSvg } from 'src/pages/tabs/carousell_me/settings/svgs';
interface AboutProps {}
const MyProfile: React.FC<AboutProps> = () => {
const [showPopover, setShowPopover] = useState(false);
const [popoverEvent, setPopoverEvent] = useState<MouseEvent>();
const [location, setLocation] = useState<'madison' | 'austin' | 'chicago' | 'seattle'>('madison');
const [conferenceDate, setConferenceDate] = useState('2047-05-17T00:00:00-05:00');
const [showAlert, hideAlert] = useIonAlert();
const { browser_store } = useContext(AppContext);
const refRectangle = useRef<HTMLDivElement>(null);
const [swipeType, setSwipeType] = useState();
const [deltaX, setDeltaX] = useState();
const [velocityX, setVelocityX] = useState();
const [swipeVerdict, setSwipeVerdict] = useState('helloworld');
const route = useIonRouter();
const [username, setUsername] = useState('hello user');
const [usernameError, setUsernameError] = useState(false);
useEffect(() => {
if (swipeVerdict == 'swipe-left')
if (route.canGoBack() == true) {
route.goBack();
} else {
route.push('/tabs/schedule');
}
}, [swipeVerdict]);
const onMove = (detail: any) => {
const type = detail.type;
const currentX = detail.currentX;
const deltaX = detail.deltaX;
const velocityX = detail.velocityX;
setSwipeType(type);
setDeltaX(deltaX);
setVelocityX(velocityX);
if (type == 'pan')
if (Math.abs(deltaX) > 50)
if (velocityX > 0) {
setSwipeVerdict('swipe-right');
} else {
setSwipeVerdict('swipe-left');
}
};
useIonViewDidEnter(() => {
let gesture: any = {};
if (refRectangle?.current) {
gesture = createGesture({
gestureName: 'helloworld',
el: refRectangle.current,
onMove: (detail) => {
onMove(detail);
},
});
gesture.enable();
}
return () => {
gesture?.destroy();
};
}, [refRectangle]);
const handleStoreWrite = () => {
(async () => {
await browser_store.set('hello', 'world');
})();
};
const handleStoreRead = () => {
(async () => {
console.log(await browser_store.get('hello'));
})();
};
const handleStoreClear = () => {
(async () => {
await browser_store.clear();
})();
};
const handleStoreRemove = () => {
(async () => {
await browser_store.remove('hello');
})();
};
const handleStoreKeys = () => {
(async () => {
console.dir(await browser_store.keys());
})();
};
const handleStoreLength = () => {
(async () => {
console.dir(await browser_store.length());
})();
};
const userInput = 'javascript:alert("Oh no!")';
const { t } = useTranslation();
return (
<IonPage id="my-profile-page">
<IonHeader translucent={true}>
<IonToolbar>
<IonButtons slot="start">
<IonBackButton defaultHref="/tabs/schedule"></IonBackButton>
</IonButtons>
<IonButtons slot="end">
<IonButton>
<IonIcon slot="icon-only" icon={checkmarkDoneOutline}></IonIcon>
</IonButton>
</IonButtons>
<IonTitle>{t('My Profile')}</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent fullscreen={true}>
<IonHeader collapse="condense">
<IonToolbar>
<IonTitle size="large">{t('My Profile')}</IonTitle>
</IonToolbar>
</IonHeader>
<IonGrid fixed>
<IonList>
<IonItem lines="none">
<IonLabel style={{ fontWeight: 'bold' }}>Public Profile</IonLabel>
</IonItem>
<IonItem lines="none">
<div
style={{
width: '100%',
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
gap: '1rem',
}}
>
<div>Username</div>
<div>
<IonInput placeholder="username"></IonInput>
</div>
</div>
</IonItem>
<IonItem lines="full">
<IonLabel>Public Profile</IonLabel>
</IonItem>
</IonList>
</IonGrid>
</IonContent>
</IonPage>
);
};
export default React.memo(MyProfile);

View File

@@ -0,0 +1,2 @@
#sample-blank-page {
}

View File

@@ -0,0 +1,159 @@
import {
IonBackButton,
IonButton,
IonButtons,
IonContent,
IonHeader,
IonIcon,
IonPage,
IonPopover,
IonTitle,
IonToolbar,
useIonRouter,
useIonViewDidEnter,
} from '@ionic/react';
import { star, starOutline } from 'ionicons/icons';
import React, { useContext, useEffect, useRef, useState } from 'react';
// import AboutPopover from '../../components/AboutPopover';
import { useIonAlert } from '@ionic/react';
import './style.scss';
import { AppContext } from '../../../data/AppContext';
import { createGesture, Gesture } from '@ionic/react';
interface AboutProps {}
const MyProfile: React.FC<AboutProps> = () => {
const [showPopover, setShowPopover] = useState(false);
const [popoverEvent, setPopoverEvent] = useState<MouseEvent>();
const [location, setLocation] = useState<'madison' | 'austin' | 'chicago' | 'seattle'>('madison');
const [conferenceDate, setConferenceDate] = useState('2047-05-17T00:00:00-05:00');
const [showAlert, hideAlert] = useIonAlert();
const { browser_store } = useContext(AppContext);
const refRectangle = useRef<HTMLDivElement>(null);
const [swipeType, setSwipeType] = useState();
const [deltaX, setDeltaX] = useState();
const [velocityX, setVelocityX] = useState();
const [swipeVerdict, setSwipeVerdict] = useState('helloworld');
const route = useIonRouter();
useEffect(() => {
if (swipeVerdict == 'swipe-left')
if (route.canGoBack() == true) {
route.goBack();
} else {
route.push('/tabs/schedule');
}
}, [swipeVerdict]);
const onMove = (detail: any) => {
const type = detail.type;
const currentX = detail.currentX;
const deltaX = detail.deltaX;
const velocityX = detail.velocityX;
setSwipeType(type);
setDeltaX(deltaX);
setVelocityX(velocityX);
if (type == 'pan')
if (Math.abs(deltaX) > 50)
if (velocityX > 0) {
setSwipeVerdict('swipe-right');
} else {
setSwipeVerdict('swipe-left');
}
};
useIonViewDidEnter(() => {
let gesture: any = {};
if (refRectangle?.current) {
gesture = createGesture({
gestureName: 'helloworld',
el: refRectangle.current,
onMove: (detail) => {
onMove(detail);
},
});
gesture.enable();
}
return () => {
gesture?.destroy();
};
}, [refRectangle]);
const handleStoreWrite = () => {
(async () => {
await browser_store.set('hello', 'world');
})();
};
const handleStoreRead = () => {
(async () => {
console.log(await browser_store.get('hello'));
})();
};
const handleStoreClear = () => {
(async () => {
await browser_store.clear();
})();
};
const handleStoreRemove = () => {
(async () => {
await browser_store.remove('hello');
})();
};
const handleStoreKeys = () => {
(async () => {
console.dir(await browser_store.keys());
})();
};
const handleStoreLength = () => {
(async () => {
console.dir(await browser_store.length());
})();
};
const userInput = 'javascript:alert("Oh no!")';
return (
<IonPage id="sample-blank-page">
<IonHeader translucent={true}>
<IonToolbar>
<IonButtons slot="start">
<IonBackButton defaultHref="/tabs/schedule"></IonBackButton>
</IonButtons>
<IonTitle>
<h3 style={{ fontWeight: 'bold', fontSize: '0.9rem' }}>Offers Made</h3>
</IonTitle>
<IonButtons slot="end">
<IonButton onClick={() => {}}>
{false ? (
<IonIcon slot="icon-only" icon={star}></IonIcon>
) : (
<IonIcon slot="icon-only" icon={starOutline}></IonIcon>
)}
</IonButton>
</IonButtons>
</IonToolbar>
</IonHeader>
<IonContent>My Profile</IonContent>
{/*
<IonPopover isOpen={showPopover} event={popoverEvent} onDidDismiss={() => setShowPopover(false)}>
<AboutPopover dismiss={() => setShowPopover(false)} />
</IonPopover>
*/}
</IonPage>
);
};
export default React.memo(MyProfile);

View File

@@ -0,0 +1,2 @@
#sample-blank-page {
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@@ -0,0 +1,207 @@
import React, { useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import StarRatings from 'react-star-ratings';
import {
IonHeader,
IonTitle,
IonToolbar,
IonContent,
IonPage,
IonButtons,
IonBadge,
IonMenuButton,
IonButton,
IonIcon,
IonDatetime,
IonSelectOption,
IonList,
IonItem,
IonLabel,
IonSelect,
IonPopover,
IonText,
IonCard,
IonCardHeader,
IonCardTitle,
IonCardSubtitle,
IonCardContent,
IonTabs,
IonTabBar,
IonTabButton,
IonSegment,
IonSegmentButton,
useIonRouter,
IonAvatar,
IonModal,
} from '@ionic/react';
import './style.scss';
import {
locationSharp,
settingsOutline,
qrCode,
shareSocialOutline,
ellipsisHorizontal,
ellipsisVertical,
logoFacebook,
phonePortraitSharp,
pricetagSharp,
archiveSharp,
calendar,
personCircle,
map,
informationCircle,
mailSharp,
chevronDownSharp,
chevronForwardSharp,
} from 'ionicons/icons';
// import AboutPopover from '../../components/AboutPopover';
import { format, parseISO } from 'date-fns';
import './style.scss';
import AmazingChatSvg from './AmazingChat.svg';
import lookForVisitorSvg from './look_for_visitor.svg';
type SessionListProps = {
hide: boolean;
};
const SampleReview: React.FC = () => {
const modal = useRef<HTMLIonModalElement>(null);
function dismiss() {
modal.current?.dismiss();
}
let [openExplain, setOpenExplain] = useState(false);
return (
<>
<IonModal id="explain-review" ref={modal} isOpen={openExplain}>
<div
className="wrapper"
style={{
padding: '1rem',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
gap: '0.5rem',
}}
>
<h1>Dialog header</h1>
<img src={AmazingChatSvg} width="33%" />
<div>
<IonText style={{ fontSize: '1.2rem', fontWeight: 'bold' }}>Amazing chat</IonText>
</div>
<div style={{ fontSize: '0.9rem' }}>
<p>You enjoyed chatting with this seller,</p>
<p>it felt like you were talking to and old friend</p>
</div>
<IonButton size="default" expand="block" onClick={dismiss}>
Got it!
</IonButton>
</div>
</IonModal>
<div id="sample-review">
<div style={{ padding: '1rem', display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
<div
style={{
display: 'flex',
flexDirection: 'row',
gap: '1rem',
justifyContent: 'center',
alignItems: 'center',
}}
>
<IonAvatar style={{ height: '50px', width: '50px' }}>
<img
alt="Silhouette of a person's head"
src="https://ionicframework.com/docs/img/demos/avatar.svg"
/>
</IonAvatar>
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
<IonText>Man1130</IonText>
<IonText style={{ fontSize: '0.8rem' }} color="dark">
<StarRatings
rating={3}
starRatedColor="green"
changeRating={() => {}}
numberOfStars={5}
name="rating"
starDimension="1rem"
starSpacing="0px"
//
/>
review from buyer 2 months ago
</IonText>
</div>
</div>
<div style={{ fontSize: '0.8rem' }}>
<IonButton size="small" fill="outline" onClick={(e) => setOpenExplain(true)}>
<IonIcon slot="start" icon={chevronForwardSharp}></IonIcon>
Amazing
</IonButton>
<IonButton size="small" fill="outline">
<IonIcon slot="start" icon={chevronForwardSharp}></IonIcon>
Knows
</IonButton>
<IonButton size="small" fill="outline">
<IonIcon slot="start" icon={chevronForwardSharp}></IonIcon>
extra mile
</IonButton>
</div>
<IonText>program之外仲幫左我好多 </IonText>
<div
style={{
padding: '0.5rem',
borderRadius: '0.5rem',
backgroundColor: 'rgb(240, 241, 241)',
display: 'flex',
flexDirection: 'row',
justifyContent: 'flex-start',
gap: '0.5rem',
}}
>
<img
src="https://upload.wikimedia.org/wikipedia/commons/6/6a/JavaScript-logo.png"
style={{ width: '60px', height: '60px' }}
/>
<div style={{ fontSize: '0.8rem' }}>
#html #css # # # # #programming #coding #javascript #python #react
#debug HK$100
</div>
</div>
</div>
</div>
</>
);
};
const ReviewsContent: React.FC<SessionListProps> = ({ hide }) => {
let route = useIonRouter();
if (hide) return <></>;
return (
<>
<div id="review-list">
<SampleReview />
<SampleReview />
<SampleReview />
<SampleReview />
<SampleReview />
<SampleReview />
</div>
</>
);
};
export default ReviewsContent;

View File

@@ -0,0 +1,26 @@
ion-modal#explain-review {
--width: 75vw;
--min-width: 250px;
--height: fit-content;
--border-radius: 6px;
--box-shadow: 0 28px 48px rgba(0, 0, 0, 0.4);
}
ion-modal#explain-review h1 {
margin: 20px 20px 10px 20px;
}
ion-modal#explain-review ion-icon {
margin-right: 6px;
width: 48px;
height: 48px;
padding: 4px 0;
color: #aaaaaa;
}
ion-modal#explain-review .wrapper {
margin-bottom: 10px;
}

View File

@@ -0,0 +1,389 @@
import React, { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';
import StarRatings from 'react-star-ratings';
import * as selectors from '../../data/selectors';
import {
IonHeader,
IonTitle,
IonToolbar,
IonContent,
IonPage,
IonButtons,
IonBadge,
IonMenuButton,
IonButton,
IonIcon,
IonDatetime,
IonSelectOption,
IonList,
IonItem,
IonLabel,
IonSelect,
IonPopover,
IonText,
IonCard,
IonCardHeader,
IonCardTitle,
IonCardSubtitle,
IonCardContent,
IonTabs,
IonTabBar,
IonTabButton,
IonSegment,
IonSegmentButton,
useIonRouter,
} from '@ionic/react';
import './style.scss';
import {
locationSharp,
settingsOutline,
qrCode,
shareSocialOutline,
ellipsisHorizontal,
ellipsisVertical,
logoFacebook,
phonePortraitSharp,
pricetagSharp,
archiveSharp,
calendar,
personCircle,
map,
informationCircle,
mailSharp,
chevronDownSharp,
chevronForwardSharp,
heartSharp,
heartOutline,
chatbubblesOutline,
heart,
chatbubbles,
chatbox,
} from 'ionicons/icons';
import AboutPopover from '../../components/AboutPopover';
import { format, parseISO } from 'date-fns';
import lookForVisitorSvg from './look_for_visitor.svg';
import AboutContent from './AboutContent';
import ReviewsContent from './ReviewsContent';
import ListingsContent from './ListingsContent';
import { triggerShare } from '../../util/triggerShare';
import { connect } from '../../data/connect';
import PATHS from '../../PATHS';
// import { toProperCase } from 'src/util/toProperCase';
import './theme/variables.scss';
import { messages } from '../DemoFacebookClone/main/messages';
import { Router } from 'react-router';
interface OwnProps {}
interface StateProps {
events: Event[];
}
interface DispatchProps {}
interface CarousellMeProps extends OwnProps, StateProps, DispatchProps {}
const CarousellMe: React.FC<CarousellMeProps> = () => {
const [showPopover, setShowPopover] = useState(false);
const [popoverEvent, setPopoverEvent] = useState<MouseEvent>();
const [location, setLocation] = useState<'madison' | 'austin' | 'chicago' | 'seattle'>('madison');
const [conferenceDate, setConferenceDate] = useState('2047-05-17T00:00:00-05:00');
const { t } = useTranslation();
const route = useIonRouter();
const selectOptions = {
header: 'Select a Location',
};
const presentPopover = (e: React.MouseEvent) => {
setPopoverEvent(e.nativeEvent);
setShowPopover(true);
};
function displayDate(date: string, dateFormat: string) {
return format(parseISO(date), dateFormat);
}
const changeRating = () => {
console.log('change rating');
};
// listing , reviews, about
const [segment, setSegment] = useState<'listings' | 'reviews' | 'about'>('listings');
const handleSettingPageClick = () => {
route.push('/tabs/carousell_me/settings');
};
const [isCopied, setIsCopied] = useState(false);
const [isOpen, setIsOpen] = useState(false);
const handleShareLink = useCallback(() => {
triggerShare(`https://louiscklaw.github.io`, 'louis portfolio')
.then(() => {
if (navigator.clipboard) setIsCopied(true);
console.debug('share:copied');
})
.finally(() => {
console.log('share:end');
// setIsOpen(false);
});
}, []);
return (
<IonPage id="carousell-me-page" style={{}}>
<IonContent>
<IonHeader className="ion-no-border">
<IonToolbar>
<IonButtons slot="end">
<IonButton onClick={presentPopover}>
<div>
<IonIcon slot="icon-only" icon={heartOutline} size="large"></IonIcon>
</div>
</IonButton>
<IonButton onClick={presentPopover}>
<div
style={{
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
}}
>
<IonIcon slot="icon-only" icon={chatbox} size="large"></IonIcon>
<div
style={{
color: 'black',
fontWeight: 'bold',
//
position: 'relative',
height: 0,
top: '-1.5rem',
//
fontSize: '0.8rem',
}}
>
<div>99</div>
</div>
</div>
</IonButton>
</IonButtons>
</IonToolbar>
</IonHeader>
<div className="about-header">
{/* Instead of loading an image each time the select changes, use opacity to transition them */}
<div
className="about-image madison"
style={{
//
opacity: location === 'madison' ? '1' : undefined,
}}
></div>
</div>
{/* */}
<div
style={{
display: 'flex',
flexDirection: 'column',
gap: '0.5rem',
paddingLeft: '1rem',
paddingRight: '1rem',
}}
>
<div className="profile-test">
<img
src="https://media.karousell.com/media/photos/profiles/2025/02/05/louis_coding_1738774979_f1598e0b.jpg"
style={{
height: '75px',
width: '75px',
borderRadius: '50px',
border: '3px solid white',
//
boxShadow: '0 4px 8px rgba(0, 0, 0, 0.2)',
}}
/>
<div className="setting-icons">
<IonButton shape="round" fill="clear" onClick={handleShareLink}>
<IonIcon
color="primary"
slot="icon-only"
ios={shareSocialOutline}
md={shareSocialOutline}
></IonIcon>
</IonButton>
<IonButton shape="round" fill="clear" routerLink={PATHS.CAROUSELL_ME_QR}>
<IonIcon color="primary" slot="icon-only" ios={qrCode} md={qrCode}></IonIcon>
</IonButton>
<IonButton
shape="round"
fill="clear"
routerLink={PATHS.CAROUSELL_ME_SETTINGS}
// onClick={() => route.push(PATHS.CAROUSELL_ME_SETTINGS, 'forward', 'push')}
// onClick={handleSettingPageClick}
>
<IonIcon
color="primary"
slot="icon-only"
ios={settingsOutline}
md={settingsOutline}
></IonIcon>
</IonButton>
</div>
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.25rem' }}>
<div style={{ fontWeight: 'bold' }}>louis_coding</div>
<div
style={{
fontSize: '0.9rem',
display: 'flex',
flexDirection: 'column',
gap: '0.8rem',
}}
>
<IonText color="medium">@louis_coding</IonText>
<div
style={{
display: 'flex',
flexDirection: 'row',
alignItems: 'base-line',
gap: '0.2rem',
}}
>
<IonText color="medium">5.0</IonText>
<StarRatings
rating={3}
starRatedColor="green"
changeRating={changeRating}
numberOfStars={5}
name="rating"
starDimension="1rem"
starSpacing="0px"
//
/>
<IonText color="medium">(12)</IonText>
<IonText color="medium">Joined 5y 6m</IonText>
</div>
{/* location */}
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'flex-start',
gap: '1rem',
}}
>
<div
style={{
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
gap: '0.2rem',
}}
>
<IonText color="medium">Verified</IonText>
<IonIcon color="primary" ios={logoFacebook} md={logoFacebook}></IonIcon>
<IonIcon
color="primary"
ios={phonePortraitSharp}
md={phonePortraitSharp}
></IonIcon>
<IonIcon color="primary" ios={mailSharp} md={mailSharp}></IonIcon>
</div>
<div>
<IonText color="medium">
<IonIcon ios={locationSharp} md={locationSharp}></IonIcon>
Hong Kong
</IonText>
</div>
</div>
{/* location */}
{/* conbutton and caroubiz */}
<div>
<IonButton fill="outline" color="primary" shape="round" size="small">
<IonIcon color="primary" ios={pricetagSharp} md={pricetagSharp}></IonIcon>
409
</IonButton>
<IonButton fill="outline" color="primary" shape="round" size="small">
<IonIcon color="primary" ios={archiveSharp} md={archiveSharp}></IonIcon>
caroubiz
</IonButton>
</div>
{/* conbutton and caroubiz */}
{/* profile visitor */}
<IonCard
button
onClick={(e) => route.push('/tabs/carousell_me/insights')}
style={{ margin: '0rem' }}
>
<IonCardContent>
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
}}
>
<img src={lookForVisitorSvg} height="20%" width="20%" />
<div style={{ marginLeft: '1rem' }}>
<IonText title="helloworld">
<h3 style={{ color: 'black', fontWeight: 'bold' }}>
No profile visitors today
</h3>
</IonText>
<IonText>
<h6 style={{ fontSize: '0.7rem' }}>List an item to get more visitors</h6>
</IonText>
</div>
</div>
</IonCardContent>
</IonCard>
{/* profile visitor */}
</div>
</div>
</div>
{/* listing / reviews / about */}
<IonSegment
mode={'md'}
value={segment}
onIonChange={(e) => setSegment(e.detail.value as any)}
>
<IonSegmentButton value="listings">{t('Listings')}</IonSegmentButton>
<IonSegmentButton value="reviews">{t('Reviwes')}</IonSegmentButton>
<IonSegmentButton value="about">{t('About')}</IonSegmentButton>
</IonSegment>
{/* listing / reviews / about */}
<ListingsContent hide={segment != 'listings'} />
<ReviewsContent hide={segment != 'reviews'} />
<AboutContent hide={segment != 'about'} />
</IonContent>
</IonPage>
);
};
// export default React.memo(CarousellMe);
export default connect<OwnProps, StateProps, DispatchProps>({
mapStateToProps: (state) => ({
events: selectors.getEvents(state),
}),
component: React.memo(CarousellMe),
});

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@@ -0,0 +1,120 @@
#carousell-me-page {
--ion-color-tertiary: #ad8e70;
--ion-color-tertiary-rgb: 173, 142, 112;
--ion-color-tertiary-contrast: #000000;
--ion-color-tertiary-contrast-rgb: 0, 0, 0;
--ion-color-tertiary-shade: #987d63;
--ion-color-tertiary-tint: #b5997e;
.setting-icons {
ion-button::part(native) {
margin: 0;
padding: 0;
}
}
ion-toolbar {
position: absolute;
top: 0;
left: 0;
right: 0;
--background: transparent;
--color: white;
}
ion-toolbar ion-back-button,
ion-toolbar ion-button,
ion-toolbar ion-menu-button {
--color: white;
}
.about-header {
position: relative;
width: 100%;
height: 15%;
}
.about-header .about-image {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background-position: center;
background-size: cover;
background-repeat: no-repeat;
opacity: 0;
transition: opacity 500ms ease-in-out;
}
.about-header .madison {
background-image: url('https://cdn.dribbble.com/users/438226/screenshots/16695232/media/145ec731468579d04291d11c4c389c65.png');
filter: brightness(75%);
}
.about-info {
position: absolute;
margin-top: -10px;
border-radius: 10px;
background: var(--ion-background-color, #fff);
}
.about-info h3 {
margin-top: 0;
}
.about-info ion-list {
padding-top: 0;
}
.about-info p {
line-height: 130%;
color: var(--ion-color-dark);
}
.about-info ion-icon {
margin-inline-end: 32px;
}
/*
* iOS Only
*/
.ios .about-info {
--ion-padding: 19px;
}
.ios .about-info h3 {
font-weight: 700;
}
.profile-test {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: flex-end;
position: relative;
height: 50px;
ion-icon {
font-size: 1.5rem;
margin-left: 1rem;
}
}
}
#date-input-popover {
--offset-y: -var(--ion-safe-area-bottom);
--max-width: 90%;
--width: 336px;
}

View File

@@ -0,0 +1,59 @@
#carousell-me-page {
* {
--ion-color-primary: #243763;
--ion-color-primary-rgb: 36, 55, 99;
--ion-color-primary-contrast: #ffffff;
--ion-color-primary-contrast-rgb: 255, 255, 255;
--ion-color-primary-shade: #203057;
--ion-color-primary-tint: #3a4b73;
--ion-color-secondary: #ff6e31;
--ion-color-secondary-rgb: 255, 110, 49;
--ion-color-secondary-contrast: #000000;
--ion-color-secondary-contrast-rgb: 0, 0, 0;
--ion-color-secondary-shade: #e0612b;
--ion-color-secondary-tint: #ff7d46;
--ion-color-tertiary: #ad8e70;
--ion-color-tertiary-rgb: 173, 142, 112;
--ion-color-tertiary-contrast: #000000;
--ion-color-tertiary-contrast-rgb: 0, 0, 0;
--ion-color-tertiary-shade: #987d63;
--ion-color-tertiary-tint: #b5997e;
--ion-color-success: #2dd36f;
--ion-color-success-rgb: 45, 211, 111;
--ion-color-success-contrast: #000000;
--ion-color-success-contrast-rgb: 0, 0, 0;
--ion-color-success-shade: #28ba62;
--ion-color-success-tint: #42d77d;
--ion-color-warning: #ffc409;
--ion-color-warning-rgb: 255, 196, 9;
--ion-color-warning-contrast: #000000;
--ion-color-warning-contrast-rgb: 0, 0, 0;
--ion-color-warning-shade: #e0ac08;
--ion-color-warning-tint: #ffca22;
--ion-color-danger: #eb445a;
--ion-color-danger-rgb: 235, 68, 90;
--ion-color-danger-contrast: #ffffff;
--ion-color-danger-contrast-rgb: 255, 255, 255;
--ion-color-danger-shade: #cf3c4f;
--ion-color-danger-tint: #ed576b;
--ion-color-medium: #92949c;
--ion-color-medium-rgb: 146, 148, 156;
--ion-color-medium-contrast: #000000;
--ion-color-medium-contrast-rgb: 0, 0, 0;
--ion-color-medium-shade: #808289;
--ion-color-medium-tint: #9d9fa6;
--ion-color-light: #ffebb7;
--ion-color-light-rgb: 255, 235, 183;
--ion-color-light-contrast: #000000;
--ion-color-light-contrast-rgb: 0, 0, 0;
--ion-color-light-shade: #e0cfa1;
--ion-color-light-tint: #ffedbe;
}
}

View File

@@ -56,7 +56,7 @@ const DummyPayPage: React.FC<PageProps> = ({
},
});
router.goBack();
router.push(PATHS.PAYMENT_SUCCESS, 'back', 'replace');
setShowJoinOKToast(true);
} catch (error) {

View File

@@ -124,7 +124,7 @@ const EventDetail: React.FC<PageProps> = ({ event_detail, setEventIdToJoin }) =>
function handleJoinClick() {
if (event_detail && event_detail?.id) {
setEventIdToJoin(event_detail.id);
router.push(PATHS.DUMMY_EVENT_PAY_PAGE);
router.push(PATHS.DUMMY_EVENT_PAY_PAGE, 'forward', 'push');
}
}

View File

@@ -0,0 +1,221 @@
import React, { useRef, useEffect, useState } from 'react';
import {
IonContent,
IonPage,
IonHeader,
IonToolbar,
IonButtons,
IonButton,
IonIcon,
useIonViewWillEnter,
IonBackButton,
IonText,
} from '@ionic/react';
import { arrowForward, share, star, starOutline } from 'ionicons/icons';
import { setMenuEnabled } from '../../data/sessions/sessions.actions';
import { setHasSeenTutorial } from '../../data/user/user.actions';
import './style.scss';
import { connect } from '../../data/connect';
import { RouteComponentProps } from 'react-router';
import PATHS from '../../PATHS';
import getUnsplashRandomImage from '../../api/getUnsplashRandomImage';
import schedulePng from './sampleHeader.png';
// import type { Swiper } from 'swiper/types';
// import type { Swiper as SwiperClass } from 'swiper/types';
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/css';
import '@ionic/react/css/ionic-swiper.css';
import getHtmlContent from '../../api/getHtmlContent';
interface OwnProps extends RouteComponentProps {}
interface DispatchProps {
setHasSeenTutorial: typeof setHasSeenTutorial;
setMenuEnabled: typeof setMenuEnabled;
}
interface TutorialProps extends OwnProps, DispatchProps {}
const HotelServiceWifi: React.FC<TutorialProps> = () => {
const [htmlContent, setHtmlContent] = useState<string>('');
let [loadingContent, setLoadingContent] = useState<boolean>(true);
useEffect(() => {
getHtmlContent()
.then((res) => setHtmlContent(res.trim()))
.then(() => setLoadingContent(false));
}, []);
return (
<IonPage id="hotel-service-intro-page">
<IonHeader className="ion-no-border">
<IonToolbar>
<IonButtons slot="start">
<IonBackButton defaultHref="/tabs/schedule"></IonBackButton>
</IonButtons>
<IonButtons slot="end">
<IonButton onClick={() => {}}>
{false ? (
<IonIcon slot="icon-only" icon={star}></IonIcon>
) : (
<IonIcon slot="icon-only" icon={starOutline}></IonIcon>
)}
</IonButton>
<IonButton onClick={() => {}}>
<IonIcon slot="icon-only" icon={share}></IonIcon>
</IonButton>
</IonButtons>
</IonToolbar>
</IonHeader>
<IonContent>
{/* helloworld */}
<Swiper>
<SwiperSlide>
<div
style={{
width: '100vw',
height: '33vh',
backgroundSize: 'cover',
backgroundPosition: 'center',
backgroundImage: `url(//plus.unsplash.com/premium_photo-1661964071015-d97428970584)`,
}}
></div>
</SwiperSlide>
<SwiperSlide>
<div
style={{
width: '100vw',
height: '33vh',
backgroundSize: 'cover',
backgroundPosition: 'center',
backgroundImage: `url(//images.unsplash.com/photo-1618773928121-c32242e63f39)`,
}}
></div>
</SwiperSlide>
<SwiperSlide>
<div
style={{
width: '100vw',
height: '33vh',
backgroundSize: 'cover',
backgroundPosition: 'center',
backgroundImage: `url(//images.unsplash.com/photo-1551882547-ff40c63fe5fa)`,
}}
></div>
</SwiperSlide>
</Swiper>
{/* */}
<div
id="content"
style={{
paddingLeft: '0.5rem',
paddingRight: '0.5rem',
marginTop: '1rem',
marginBottom: '1rem',
}}
>
<div dangerouslySetInnerHTML={{ __html: contentHtml }}>{}</div>
</div>
</IonContent>
</IonPage>
);
};
export default connect<OwnProps, {}, DispatchProps>({
mapDispatchToProps: {
setHasSeenTutorial,
setMenuEnabled,
},
component: HotelServiceWifi,
});
const contentHtml = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {padding:0; margin:0; box-sizing: border-box;}
.text { color: rgba(0,0,0,0.8)}
.text-grey {color: rgba(0,0,0,0.5)}
.text-asscent {color: rgba(64,0,0,0.8)}
.bold {font-weight: bold;}
.description {font-size: 1rem}
.title { font-size: 1.1rem }
.text-subtitle { font-size: 0.8rem }
.center { text-align: center}
.hr-asscent { border-bottom: 3px solid rgba(64,0,0,0.8) }
.hr-grey { border-bottom: 1px solid rgba(64,64,64,0.5) }
.asscent-background { background-color: rgba(64,0,0,0.1); border-radius: 10px; padding: 1rem 0.5rem }
td {padding-right: 2rem; font-size: 0.8rem}
.horizontal-spacer { padding: 2rem 0}
.shadow { box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px; }
.hard-shadow { box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px; }
</style>
</head>
<body>
<div class="text bold center horizontal-spacer">
<h3>helloworld Hotel</h3>
</div>
<div class="text-grey description">〒107-0062 東京都港区南青山1丁目26-1</div>
<hr class="hr-asscent">
<div class="asscent-background shadow">
<div class="text-asscent">ホテル情報</div>
<hr class="hr-grey" >
<table>
<tr>
<td class="text-grey">チェックイン</td><td class="text-grey">15:00</td>
</tr>
<tr>
<td class="text-grey">チェックアウト</td><td class="text-grey">10:00</td>
</tr>
<tr>
<td class="text-grey">夜間玄関施錠</td><td class="text-grey">25:00</td>
</tr>
</table>
</div>
<div class="text-asscent center">
<h5>ご利用可能なクレジットカード</h5>
</div>
<hr class="hr-grey" >
<div class="horizontal-spacer">
<div class="text-asscent bold center">helloworld 物語</div>
<div class="text-subtitle bold center">"TRAVEL IS LIFE, DX IS HOW"</div>
</div>
<div
class="horizontal-spacer shadow"
style="
width:100%;
height: 200px;
background-image: url('https://images.unsplash.com/photo-1566073771259-6a8506099945');
background-size:cover;
background-position:center;
background-repeat: no-repeat;
border-radius: 10px;
"></div>
<div class="horizontal-spacer text-grey bold description">
<p>異国情緒あふれる館に招かれたような優雅なひととき。</p>
<p>helloworld LifeHOTELはヨーロッパを中心とした様々なコンセプトで全国に展開しており、ホテルに一歩足を踏み入れた瞬間から、異国情緒あふれるLYNKEDならではの世界観を楽しんでいただけます。</p>
<p>ご宿泊の際は、1日の締めくくりにほっとくつろいでいただけるあたたかさと機能性を兼ね備えた客室で。</p>
<p>邸宅に招かれたような雰囲気を兼ね備えたレストランでのお食事は、記念日など特別な日にも。</p>
<p>オーセンティックな教会や華やかで明るいパーティールームで最高にロマンティックな結婚式を。</p>
<p>そのほか各種パーティーや会議、天然温泉をひいたスパ施設など、心あたたまるおもてなしで、みなさまをお迎えいたします。</p>
<p>helloworld HOTELのドラマティックステージへようこそ。</p>
</div>
</body>
</html>
`;

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 976 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

View File

@@ -10,7 +10,7 @@
.slider {
display: grid;
grid-template-columns: repeat(4, 100%);
// grid-template-columns: repeat(4, 100%);
grid-template-rows: 1fr;
height: 100%;

View File

@@ -0,0 +1,210 @@
import {
IonButton,
IonButtons,
IonContent,
IonHeader,
IonIcon,
IonPage,
IonText,
IonToolbar,
useIonRouter,
} from '@ionic/react';
import React, { useEffect, useState } from 'react';
import { star, starOutline, share, chevronBack } from 'ionicons/icons';
// import type { Swiper } from 'swiper/types';
// import type { Swiper as SwiperClass } from 'swiper/types';
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/css';
import '@ionic/react/css/ionic-swiper.css';
import './style.scss';
import Sampleheader from './sampleHeader.png';
import getUnsplashRandomImage from '../../api/getUnsplashRandomImage';
// import ContentHtml from './ContentHtml.tsx.del';
import getHtmlContent from '../../api/getHtmlContent';
import PATHS from '../../PATHS';
const tutorialSample1 = {
image: getUnsplashRandomImage({ keyword: 'seafood' }),
title: `
## ホテルの利益率は?`.trim(),
content: `
新型コロナウイルス感染症拡大により、ホテル業界は厳しい経営を強いられる中、ウィズコロナに向けて。`.trim(),
};
const tutorialSample2 = {
image: getUnsplashRandomImage({ keyword: 'hotel' }),
title: `
## ホテルの収益構造`.trim(),
content: `
ホテルの収益構造を分解すると、以下の3部門に分けられます。`.trim(),
};
const tutorialSample3 = {
image: getUnsplashRandomImage({ keyword: 'hotel' }),
title: `
## 宿泊部門`.trim(),
content: `
ホテル・旅館の主軸となるサービスが宿泊部門で、利用者の宿泊に関する料金が計上されます。`.trim(),
};
const tutorialSample4 = {
image: getUnsplashRandomImage({ keyword: 'hotel' }),
title: `
## 飲食部門`.trim(),
content: `
ホテルに内設されているレストランやバーで、飲食サービスを提供するのが飲食部門です。`.trim(),
};
const tutorialSample5 = {
image: getUnsplashRandomImage({ keyword: 'hotel' }),
title: `
## 宴会・イベント部門`.trim(),
content: `
団体・グループで宴会やイベントを催したい場合に、会場の貸し出しや料理の提供を行うのが宴会・イベント部門です。`.trim(),
};
const tutorialSetup = [
tutorialSample1,
tutorialSample2,
tutorialSample3,
tutorialSample4,
tutorialSample5,
];
const tutorialLastSlideIdx = tutorialSetup.length - 1;
interface HotelServiceIntro {}
const HotelServiceIntro: React.FC<HotelServiceIntro> = () => {
const route = useIonRouter();
// const pageRef = useRef();
// let [swiper, setSwiper] = useState<SwiperCore>();
const [htmlContent, setHtmlContent] = useState<string>('');
let [loadingContent, setLoadingContent] = useState<boolean>(true);
useEffect(() => {
getHtmlContent()
.then((res) => setHtmlContent(res.trim()))
.then(() => setLoadingContent(false));
}, []);
return (
<IonPage id="hotel-service-intro-page">
<IonHeader className="no-ion-border">
<IonToolbar>
<IonButtons slot="start">
<IonButton onClick={() => route.push(PATHS.EVENT_LIST)}>
<IonIcon slot="icon-only" icon={chevronBack}></IonIcon>
</IonButton>
</IonButtons>
<IonButtons slot="end">
<IonButton onClick={() => {}}>
{false ? (
<IonIcon slot="icon-only" icon={star}></IonIcon>
) : (
<IonIcon slot="icon-only" icon={starOutline}></IonIcon>
)}
</IonButton>
<IonButton onClick={() => {}}>
<IonIcon slot="icon-only" icon={share}></IonIcon>
</IonButton>
</IonButtons>
</IonToolbar>
</IonHeader>
<IonContent>
<Swiper>
<SwiperSlide>
<div
style={{
width: '100vw',
height: '25vh',
backgroundSize: 'cover',
backgroundPosition: 'center',
backgroundImage: `url(//plus.unsplash.com/premium_photo-1661964071015-d97428970584)`,
}}
></div>
</SwiperSlide>
<SwiperSlide>
<div
style={{
width: '100vw',
height: '25vh',
backgroundSize: 'cover',
backgroundPosition: 'center',
backgroundImage: `url(//images.unsplash.com/photo-1618773928121-c32242e63f39)`,
}}
></div>
</SwiperSlide>
<SwiperSlide>
<div
style={{
width: '100vw',
height: '25vh',
backgroundSize: 'cover',
backgroundPosition: 'center',
backgroundImage: `url(//images.unsplash.com/photo-1551882547-ff40c63fe5fa)`,
}}
></div>
</SwiperSlide>
</Swiper>
<div
style={{
position: 'relative',
top: '-50px',
left: '1rem',
zIndex: 102,
height: '50px',
}}
>
<div
style={{
width: '100px',
height: '100px',
backgroundImage: `url("${getUnsplashRandomImage({ keyword: 'hotel' })}")`,
backgroundSize: 'cover',
backgroundPosition: 'center',
backgroundRepeat: 'no-repeat',
borderRadius: '50px',
border: '3px solid white',
//
boxShadow: '0 4px 8px rgba(0, 0, 0, 0.2)',
}}
></div>
</div>
<div style={{ paddingLeft: '1rem', paddingRight: '1rem', marginTop: '1rem' }}>
{loadingContent ? (
<>loading content</>
) : (
<>
<div style={{}}>
<div
dangerouslySetInnerHTML={{ __html: htmlContent }}
style={{ width: '100%', minHeight: '300px' }}
></div>
</div>
<div
style={{
marginTop: '1.5rem',
marginBottom: '1.5rem',
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
}}
>
<IonText style={{ opacity: '0.5' }}>end</IonText>
</div>
</>
)}
</div>
</IonContent>
</IonPage>
);
};
export default React.memo(HotelServiceIntro);

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 976 KiB

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