diff options
| author | trisusilo <tri.susilo@altama.co.id> | 2023-10-03 08:27:50 +0000 |
|---|---|---|
| committer | trisusilo <tri.susilo@altama.co.id> | 2023-10-03 08:27:50 +0000 |
| commit | cf0b3bff8547783fe518351dd85debdc1e9633e4 (patch) | |
| tree | b0bc7f485865dca0eb17b8e0424a52037031dc98 | |
| parent | 23b667695991fafeae523aff1de7df81770461cd (diff) | |
| parent | 787d3aaa3187d3432c8e6b743b555ea3e4a4980c (diff) | |
Merged in CR/Pricelist (pull request #80)
CR/Pricelist
30 files changed, 818 insertions, 554 deletions
diff --git a/chakra.theme.js b/chakra.theme.js new file mode 100644 index 00000000..f379db20 --- /dev/null +++ b/chakra.theme.js @@ -0,0 +1,10 @@ +import { extendTheme } from '@chakra-ui/react' + +const theme = extendTheme({ + fonts: { + heading: `'Inter', sans-serif`, + body: `'Inter', sans-serif` + } +}) + +export default theme diff --git a/package.json b/package.json index cb85bd28..cabe4ed4 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,10 @@ "format": "prettier --write \"./src/**/*.{js,jsx,ts,tsx}\" --config ./.prettierrc" }, "dependencies": { + "@chakra-ui/next-js": "^2.1.5", + "@chakra-ui/react": "^2.8.1", + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", "@heroicons/react": "^2.0.13", "@hookform/resolvers": "^2.9.10", "@react-email/components": "^0.0.2", @@ -20,9 +24,9 @@ "classnames": "^2.3.2", "cookies-next": "^2.1.1", "flowbite": "^1.6.4", - "flowbite-react": "^0.4.2", - "framer-motion": "^7.6.7", + "framer-motion": "^7.10.3", "lodash-contrib": "^4.1200.1", + "lucide-react": "^0.279.0", "midtrans-client": "^1.3.1", "next": "13.0.0", "next-auth": "^4.22.3", diff --git a/public/images/icon_service/DUE-PAYMENT.svg b/public/images/icon_service/DUE-PAYMENT.svg new file mode 100644 index 00000000..d27c6a53 --- /dev/null +++ b/public/images/icon_service/DUE-PAYMENT.svg @@ -0,0 +1,21 @@ +<svg width="1200" height="1200" viewBox="0 0 1200 1200" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g clip-path="url(#clip0_3368_3828)"> +<path d="M1010.88 657.36C1001.52 652.8 998.88 647.76 998.88 637.92C999.36 523.44 999.12 408.96 999.12 294.72C999.12 225.12 952.8 179.04 883.68 178.8C857.52 178.8 831.12 178.8 804.96 178.8H793.68C793.68 167.04 793.92 156.72 793.68 146.64C793.2 132.96 785.52 124.56 773.52 124.32C760.8 124.08 753.12 132.24 752.88 146.88C752.64 157.2 752.88 167.52 752.88 177.84H555.12C554.64 176.4 554.16 175.68 554.16 174.96C553.92 165.84 553.92 156.96 553.92 147.84C553.68 132.24 546.24 123.84 533.04 124.08C520.8 124.32 513.12 132.96 512.88 147.6C512.64 157.68 512.88 167.52 512.88 177.84H314.4C314.4 167.04 314.64 156.96 314.4 146.88C314.16 132.72 306.24 124.08 293.52 124.08C281.28 124.32 273.84 132.48 273.6 146.4C273.36 156.48 273.6 166.56 273.6 178.08C269.04 178.32 265.68 178.56 262.32 178.56C233.04 178.56 203.76 178.32 174.48 178.8C120.24 179.52 73.4401 221.28 68.8801 275.04C66.2401 306.24 67.4401 337.92 67.4401 369.6C67.2001 544.8 67.2001 720 67.4401 895.2C67.4401 909.36 69.1201 924 73.2001 937.2C87.8401 984.72 129.84 1013.52 183.12 1013.52C369.84 1013.52 556.8 1013.52 743.76 1013.28C753.6 1013.28 761.28 1015.68 768.96 1022.4C817.2 1063.44 873.36 1080.48 936 1074.24C1031.76 1064.64 1112.16 990 1129.44 896.4C1147.2 798.24 1099.68 701.52 1010.88 657.36ZM110.4 273.6C114.72 244.56 140.64 221.76 170.64 220.08C204.24 218.4 238.08 219.6 273.36 219.6C273.36 230.4 273.36 240.72 273.36 251.04C273.6 265.44 281.52 273.84 294 273.6C306 273.36 313.68 264.96 313.92 251.28C314.16 241.2 313.92 231.12 313.92 220.08H512.4C512.4 229.92 512.4 239.76 512.4 249.84C512.64 264.96 520.56 273.84 533.28 273.84C545.76 273.6 552.96 265.2 553.2 250.32C553.44 240.24 553.2 230.4 553.2 219.84H752.16C752.16 229.92 752.16 239.76 752.16 249.84C752.4 265.44 759.84 273.84 772.8 273.84C785.52 273.84 792.96 264.72 793.2 249.36C793.44 240.48 793.44 231.36 793.44 222.48C793.44 221.76 794.16 221.28 794.64 220.32C829.2 220.32 864.24 218.16 898.8 221.04C934.08 223.92 957.6 253.44 957.84 289.2C958.08 302.64 957.84 316.08 957.84 330.48H109.92C109.92 310.8 107.76 291.84 110.4 273.6ZM712.8 972.72C536.4 972.72 360.24 972.72 183.84 972.72C136.08 972.72 108.48 944.88 108.48 897.12C108.48 726.48 108.48 555.84 108.48 384.96V372.72H957.84V637.68C864.72 623.52 786.72 650.4 732 727.92C677.04 805.68 678.24 888 723.6 972.24C719.76 972.24 716.4 972.72 712.8 972.72ZM912.48 1034.64C812.88 1034.64 732 954.24 732 854.64C732 755.52 813.12 674.16 912.48 674.4C1011.36 674.4 1091.76 754.8 1092.24 853.92C1092.48 953.52 1011.84 1034.4 912.48 1034.64Z" fill="#E20613"/> +<path d="M700.8 446.88C700.56 432.96 692.64 425.52 678.72 425.28C645.36 425.04 612 424.8 578.64 425.28C564.48 425.52 557.28 433.2 557.28 447.12C557.04 480.48 557.04 513.84 557.28 547.2C557.28 561.12 564.96 568.32 579.12 568.56C582.24 568.56 585.36 568.56 588.72 568.56C595.92 568.56 603.12 568.56 610.56 568.56H613.92C618.48 568.56 623.04 568.56 627.6 568.56C632.4 568.56 637.44 568.56 642.48 568.56C654.48 568.56 666.48 568.56 678.24 568.56C693.12 568.32 701.04 561.36 701.04 546.72C701.04 513.6 701.28 480.24 700.8 446.88ZM659.04 527.28H598.56V467.28H659.04V527.28Z" fill="#E20613"/> +<path d="M891.12 447.6C890.88 432.96 883.68 425.52 868.8 425.28C835.92 425.04 802.8 425.04 769.92 425.28C755.28 425.52 747.6 432.96 747.6 447.6C747.36 480.48 747.12 513.6 747.6 546.48C747.84 561.36 755.28 568.56 770.16 568.56C803.04 568.8 836.16 568.8 869.04 568.56C883.68 568.56 890.88 561.12 891.12 546.24C891.36 529.68 891.12 513.36 891.12 496.8C891.36 480.72 891.6 464.16 891.12 447.6ZM849.84 527.04H789.36V467.28H849.84V527.04Z" fill="#E20613"/> +<path d="M700.56 621.12C700.32 608.16 692.16 600.24 678.96 600.24C645.6 600 612.24 600 578.88 600.24C564.96 600.48 557.28 608.16 557.04 622.08C556.8 655.44 556.8 688.8 557.04 722.16C557.04 736.56 564.96 744 579.6 744.24C591.12 744.48 602.64 744.24 614.16 744.24C619.2 744.24 624 744.24 629.04 744.24C633.6 744.24 638.16 744.24 642.72 744.24C654.72 744.24 666.72 744.24 678.72 744.24C691.92 744 700.32 736.8 700.56 723.84C701.04 689.28 701.04 655.2 700.56 621.12ZM658.8 702.24H598.32V641.52H658.8V702.24Z" fill="#E20613"/> +<path d="M318.961 447.36C318.961 433.44 311.521 425.52 297.601 425.28C264.241 424.8 230.881 424.8 197.521 425.28C183.121 425.52 175.441 433.44 175.201 448.08C174.961 480.72 174.961 513.36 175.201 546C175.441 561.36 182.881 568.8 198.001 569.04C214.561 569.28 230.881 569.04 247.441 569.04C264.001 569.04 280.561 569.28 296.881 569.04C311.041 568.8 318.721 561.6 318.721 547.68C319.201 514.08 319.201 480.72 318.961 447.36ZM277.681 527.04H217.201V466.8H277.681V527.04Z" fill="#E20613"/> +<path d="M510.001 448.08C510.001 433.68 502.321 425.52 487.921 425.52C454.561 425.28 421.201 425.28 387.841 425.52C373.921 425.76 366.241 433.68 366.241 447.6C366.001 480.48 366.001 513.6 366.241 546.48C366.241 561.12 373.921 568.8 388.321 569.04C391.441 569.04 394.561 569.04 397.921 569.04C405.121 569.04 412.321 569.04 419.761 569.04H423.121C427.681 569.04 432.241 569.04 436.801 569.04C441.841 569.04 446.641 569.04 451.681 569.04C463.681 569.04 475.681 569.04 487.441 569.04C502.561 568.8 510.241 561.36 510.241 546C510.241 513.12 510.241 480.72 510.001 448.08ZM468.241 527.52H407.761V467.28H468.241V527.52Z" fill="#E20613"/> +<path d="M510.001 622.8C510.001 608.64 501.841 600.24 487.681 600.24C454.561 600 421.681 600 388.801 600.24C374.401 600.24 366.481 608.4 366.241 622.56C366.001 655.68 366.001 688.56 366.241 721.44C366.241 736.08 374.161 743.76 388.561 744C400.321 744.24 411.841 744.24 423.601 744C428.401 744 433.201 744 438.001 744C442.321 744 446.641 744 451.201 744C463.201 744 475.441 744 487.681 744C502.081 743.76 510.241 736.08 510.241 721.68C510.241 688.8 510.241 655.68 510.001 622.8ZM468.241 702.72H407.761V641.52H468.241V702.72Z" fill="#E20613"/> +<path d="M510 797.52C510 783.12 501.84 775.44 487.44 775.2C454.32 774.96 421.44 774.96 388.56 775.2C374.16 775.2 366.48 783.12 366.24 797.52C366 814.08 366.24 830.64 366.24 846.96C366.24 863.04 366 879.12 366.24 895.44C366.48 910.56 373.92 918.96 388.8 918.96C421.68 919.2 454.8 919.2 487.68 918.96C502.08 918.96 510 910.56 510 896.4C510.24 863.52 510.24 830.64 510 797.52ZM468.48 877.44H407.76V816.96H468.48V877.44Z" fill="#E20613"/> +<path d="M318.961 797.52C318.961 783.12 311.041 775.68 296.401 775.44C279.841 775.2 263.281 775.44 246.961 775.44C230.881 775.44 214.801 775.44 198.721 775.44C183.601 775.68 175.441 782.88 175.201 798C174.961 830.64 174.961 863.28 175.201 895.92C175.201 911.52 183.361 919.2 199.201 919.44C231.361 919.68 263.761 919.68 295.921 919.44C311.281 919.44 318.961 911.76 318.961 896.64C319.201 863.52 319.201 830.4 318.961 797.52ZM277.921 877.68H217.441V816.72H277.921V877.68Z" fill="#E20613"/> +<path d="M318.96 621.84C318.72 608.64 311.04 600.48 298.08 600.24C264.24 599.76 230.64 599.76 196.8 600.24C183.6 600.48 175.44 608.4 175.2 621.36C174.72 655.2 174.72 688.8 175.2 722.64C175.44 736.32 183.6 744 197.52 744C230.4 744.24 263.52 744.24 296.4 744C311.52 744 318.72 736.32 318.96 720.72C319.2 704.64 318.96 688.56 318.96 672.48C318.96 655.68 319.2 638.64 318.96 621.84ZM277.68 702.72H217.2V642H277.68V702.72Z" fill="#E20613"/> +<path d="M879.6 911.76L860.4 867.84H845.04V911.76H802.8V772.32H877.2C909.84 772.32 927.36 794.16 927.36 820.32C927.36 844.32 913.44 857.04 902.16 862.56L927.36 912H879.6V911.76ZM884.64 819.84C884.64 812.4 877.92 809.04 870.72 809.04H845.04V830.88H870.72C877.92 831.12 884.64 827.76 884.64 819.84Z" fill="#E20613"/> +<path d="M973.2 900.961V950.161H935.52V810.721H973.2V821.281C981.36 811.681 991.2 808.081 1001.52 808.081C1026.72 808.081 1045.92 826.561 1045.92 860.881C1045.92 895.681 1026.72 913.921 1001.52 913.921C991.2 914.161 981.6 910.561 973.2 900.961ZM1007.52 861.121C1007.52 848.641 998.64 841.441 988.8 841.441C984 841.441 976.8 843.841 973.44 848.401V874.081C976.8 878.161 984 881.041 988.8 881.041C998.64 881.041 1007.52 873.841 1007.52 861.121Z" fill="#E20613"/> +</g> +<defs> +<clipPath id="clip0_3368_3828"> +<rect width="1200" height="1200" fill="white"/> +</clipPath> +</defs> +</svg> diff --git a/public/images/icon_service/ONE-STOP-SOLUTIONS.svg b/public/images/icon_service/ONE-STOP-SOLUTIONS.svg new file mode 100644 index 00000000..82d0aa06 --- /dev/null +++ b/public/images/icon_service/ONE-STOP-SOLUTIONS.svg @@ -0,0 +1,10 @@ +<svg width="1201" height="1064" viewBox="0 0 1201 1064" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M1169.91 627.377C1115.41 627.87 1060.66 627.624 1005.91 627.377C995.552 627.377 981.988 631.816 975.576 625.157C969.411 618.499 973.85 605.181 973.85 594.576C973.603 486.063 973.85 377.55 973.85 269.037C973.85 248.567 966.205 239.196 948.201 239.196C798.749 239.196 649.297 239.196 499.845 239.196C482.828 239.196 474.196 248.321 474.196 265.584C474.196 317.375 474.196 369.412 474.196 421.202C474.196 422.435 474.196 423.668 474.196 424.655C474.936 437.726 483.814 447.097 496.145 447.59C508.23 448.33 518.588 439.699 520.561 427.121C521.054 423.668 520.807 420.215 520.807 416.516C520.807 375.824 521.054 335.378 520.561 294.685C520.561 287.78 521.794 285.314 529.439 285.314C566.186 285.807 602.932 285.807 639.432 285.314C646.091 285.314 647.817 287.04 647.817 293.699C647.324 320.334 647.57 346.722 647.817 373.357C648.064 395.307 664.587 405.665 684.317 396.047C697.388 389.881 709.719 378.783 723.036 378.043C736.847 377.057 749.425 389.634 762.742 395.8C783.459 405.418 799.489 395.553 799.736 372.618C799.982 346.476 799.982 320.334 799.489 294.192C799.242 286.794 801.709 285.314 808.614 285.314C844.621 285.561 880.381 285.807 916.387 285.314C925.512 285.067 926.992 288.027 926.992 296.412C926.745 402.459 926.745 508.752 926.992 614.799C926.992 624.911 923.786 626.637 914.414 626.637C810.587 626.39 706.76 626.637 602.932 626.884C580.243 626.884 557.554 626.884 535.111 627.377C522.534 627.624 513.902 636.749 513.162 648.833C512.422 660.917 519.821 670.782 531.905 673.495C535.605 674.235 539.551 674.235 543.497 674.235C591.834 674.235 640.419 674.728 688.756 674.235C697.635 674.235 699.607 676.454 699.607 685.086C699.361 791.626 699.361 898.167 699.607 1004.71C699.607 1014.08 697.141 1016.3 688.016 1016.05C601.452 1015.8 514.642 1015.8 428.078 1015.8C424.132 1015.8 420.186 1015.8 416.487 1016.05C404.649 1017.04 396.017 1025.42 394.784 1036.77C393.551 1048.11 400.703 1058.47 412.048 1061.43C416.98 1062.66 422.159 1062.66 427.092 1062.66C673.712 1062.66 920.58 1062.66 1167.2 1062.91C1181.5 1062.91 1192.85 1059.46 1200.49 1046.63V644.147C1193.84 631.569 1183.97 627.13 1169.91 627.377ZM752.878 339.817C732.901 323.54 714.405 323.787 694.429 340.064C694.429 321.321 694.429 305.783 694.429 290C694.429 285.067 697.881 285.561 700.841 285.561C716.131 285.561 731.175 285.807 746.465 285.561C751.644 285.561 753.124 287.04 753.124 292.219C752.631 307.263 752.878 322.06 752.878 339.817ZM927.732 674.481C942.529 674.975 957.326 674.975 972.123 674.481C979.029 674.235 979.522 677.194 979.522 682.867C979.275 696.924 979.522 710.981 979.522 727.998C960.286 713.448 941.296 711.228 921.073 728.738C921.073 710.735 921.32 696.184 921.073 681.88C920.58 676.701 921.813 674.235 927.732 674.481ZM1143.52 1016.3C1079.16 1016.05 1014.79 1016.3 950.421 1016.3C886.299 1016.3 822.425 1016.05 758.55 1016.54C749.918 1016.54 747.452 1014.82 747.452 1005.69C747.699 898.906 747.699 791.873 747.452 685.086C747.452 677.441 748.685 674.481 757.317 674.481C793.077 674.975 829.083 674.975 865.09 674.481C872.242 674.481 874.462 675.961 874.215 683.36C873.722 709.502 873.968 735.643 873.968 761.785C873.968 784.721 890.492 794.586 910.962 784.474C923.786 778.309 936.857 766.964 949.681 766.964C962.505 766.964 975.576 778.309 988.4 784.474C1008.87 794.339 1025.64 784.474 1025.89 761.785C1026.13 735.643 1026.13 709.502 1025.89 683.36C1025.89 676.454 1027.12 673.988 1034.77 674.235C1071.51 674.728 1108.01 674.482 1144.76 674.235C1151.17 674.235 1153.14 675.961 1153.14 682.62C1152.9 791.133 1152.9 899.646 1153.14 1007.91C1153.39 1016.3 1149.69 1016.3 1143.52 1016.3Z" fill="#E20613"/> +<path d="M235.714 0.713796C140.765 -0.765929 61.1067 76.4264 59.627 171.375C58.3939 268.051 135.093 346.476 232.508 347.463C327.211 348.449 405.636 271.503 406.622 176.308C407.362 80.3723 331.403 2.19352 235.714 0.713796ZM233.741 300.851C163.948 301.098 106.732 244.868 106.485 175.321C105.992 105.774 162.961 48.065 232.015 47.5717C302.302 47.0785 359.025 103.555 359.518 174.088C360.258 243.635 303.782 300.358 233.741 300.851Z" fill="#E20613"/> +<path d="M512.67 461.648C481.102 461.648 449.535 461.648 417.967 461.648C386.4 461.648 354.832 461.648 323.018 461.648C307.235 461.648 299.589 468.06 296.137 483.597C280.353 554.624 264.569 625.651 249.032 696.678C244.1 718.627 253.718 730.465 276.16 730.465C338.309 730.465 400.211 730.465 462.359 730.465C480.609 730.465 488.254 724.792 491.954 707.282C507.984 636.255 523.768 565.229 539.305 494.202C543.497 473.732 533.632 461.648 512.67 461.648ZM451.261 674.235C449.781 681.387 447.562 683.853 440.163 683.853C396.511 683.607 352.613 683.607 308.961 683.853C301.316 683.853 299.589 681.88 301.316 674.482C313.153 621.951 324.745 569.668 336.336 517.138C337.322 513.192 336.829 508.013 344.228 508.259C391.826 508.506 439.423 508.506 488.008 508.506C475.43 564.735 463.099 619.485 451.261 674.235Z" fill="#E20613"/> +<path d="M242.866 370.152C268.514 371.138 302.055 367.439 335.348 374.837C360.75 380.51 384.426 389.881 405.389 405.418C418.706 415.283 421.419 428.108 413.281 439.699C404.895 451.29 391.825 453.263 378.507 443.645C352.859 425.395 324.004 417.256 292.93 417.01C254.21 416.763 215.737 416.516 177.018 417.01C104.511 417.996 48.7751 474.226 47.7886 546.732C47.542 571.641 47.542 596.796 47.7886 621.705C48.0352 654.505 72.9439 679.167 105.745 679.414C142.491 679.661 178.991 679.414 215.737 679.661C230.041 679.661 239.413 688.292 240.399 701.117C241.386 713.694 233.001 724.299 220.916 726.272C218.204 726.765 215.491 726.519 212.778 726.519C177.265 726.519 141.751 726.765 106.238 726.519C46.8021 726.272 1.1773 680.894 1.1773 621.212C1.1773 587.671 -1.28891 554.131 3.15027 520.59C14.0016 438.466 87.9878 372.125 170.852 370.398C192.062 369.905 213.518 370.152 242.866 370.152Z" fill="#E20613"/> +<path d="M380.234 903.1C380.234 946.751 380.234 990.403 380.234 1034.06C380.234 1051.81 370.862 1062.91 356.558 1062.66C342.748 1062.42 333.376 1051.32 333.376 1034.55C333.376 946.012 333.376 857.475 333.376 768.938C333.376 754.141 342.008 744.029 354.585 742.796C366.423 741.563 377.768 750.441 379.741 762.526C380.234 765.978 379.987 769.431 379.987 773.13C380.234 816.536 380.234 859.941 380.234 903.1Z" fill="#E20613"/> +<path d="M86.508 902.853C86.508 858.461 86.2614 813.823 86.508 769.431C86.7547 749.701 101.552 738.603 117.829 744.769C125.721 747.728 130.9 753.154 132.38 761.539C133.119 766.225 133.366 770.911 133.366 775.596C133.366 860.68 133.366 945.765 133.366 1030.85C133.366 1032.08 133.366 1033.07 133.366 1034.3C133.119 1052.3 123.994 1063.16 109.69 1063.16C95.3864 1063.16 86.508 1052.3 86.508 1034.05C86.508 990.156 86.508 946.505 86.508 902.853Z" fill="#E20613"/> +<path d="M256.43 936.886C256.43 969.687 256.43 1002.24 256.43 1035.04C256.43 1052.3 247.551 1062.91 233.494 1062.91C219.683 1063.16 209.818 1052.06 209.818 1035.29C209.818 969.44 209.818 903.592 209.818 837.745C209.818 821.221 219.683 810.37 233.741 810.37C247.551 810.616 256.43 820.728 256.676 837.251C256.676 870.545 256.43 903.592 256.43 936.886Z" fill="#E20613"/> +<path d="M175.538 645.874C163.454 645.874 151.369 646.12 139.285 645.874C107.471 645.134 87.0014 624.664 86.5082 592.85C86.2616 573.86 86.2616 554.624 86.5082 535.634C86.7548 518.617 95.8798 508.259 110.184 508.506C123.995 508.752 132.873 519.11 133.12 535.387C133.366 552.898 133.613 570.408 133.12 587.918C132.873 596.549 135.586 599.509 144.217 599.262C167.646 598.769 191.075 599.016 214.258 599.016C230.042 599.016 239.906 607.647 240.153 621.212C240.646 635.516 231.028 645.134 214.751 645.627C201.927 646.367 188.856 645.874 175.538 645.874Z" fill="#E20613"/> +</svg> diff --git a/public/images/icon_service/TAX.svg b/public/images/icon_service/TAX.svg new file mode 100644 index 00000000..d58daf3f --- /dev/null +++ b/public/images/icon_service/TAX.svg @@ -0,0 +1,18 @@ +<svg width="1200" height="1200" viewBox="0 0 1200 1200" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M1036.08 200.16C998.88 165.6 962.4 130.32 924.72 96.0002C914.64 86.8802 901.92 80.4002 890.4 72.7202H354.72C331.2 80.6402 315.6 95.5202 315.6 121.92C315.36 225.36 315.6 328.56 315.6 432C315.6 444.24 321.6 451.68 331.68 451.68C341.52 451.92 348.24 444.48 348.48 432.48C348.48 429.84 348.48 426.96 348.48 424.32C348.48 325.44 348.48 226.56 348.48 127.68C348.48 110.4 353.04 105.84 370.32 105.84H855.84C855.84 134.16 855.6 161.28 855.84 188.4C856.08 235.44 884.88 264.24 931.68 264.48C958.08 264.72 984.48 264.48 1010.88 264.48H1021.92V276.48C1021.92 541.2 1021.92 805.92 1021.92 1070.64C1021.92 1090.56 1017.84 1094.64 997.92 1094.64C789.12 1094.64 580.32 1094.64 371.52 1094.64C369.36 1094.64 367.44 1094.64 365.28 1094.64C354 1094.16 348.48 1088.64 348.24 1077.36C348 1065.6 348.48 1054.08 348 1042.32C347.52 1032.48 340.8 1025.76 331.92 1025.52C322.56 1025.28 315.6 1032.48 315.12 1042.56C314.88 1052.88 315.12 1063.2 315.12 1073.52C315.12 1108.32 334.56 1127.52 369.36 1127.52H999.84C1035.36 1127.52 1054.8 1108.32 1054.8 1073.04C1054.8 797.04 1054.8 521.04 1054.8 245.04C1055.28 226.8 1049.28 212.4 1036.08 200.16ZM1017.36 231.12C986.64 231.12 955.68 231.84 924.96 230.88C903.84 230.4 890.16 216.48 889.44 194.4C888.48 166.32 889.2 138.24 889.2 107.04C933.6 148.8 976.08 188.88 1018.8 228.96C1018.08 229.68 1017.6 230.4 1017.36 231.12Z" fill="#E20613"/> +<path d="M466.08 486.48C377.52 486.48 288.96 486.48 200.4 486.48C164.64 486.48 144.96 506.16 144.96 541.92C144.96 607.2 144.96 672.48 144.96 737.52C144.96 803.04 144.96 868.56 144.96 934.32C144.96 969.12 165.12 989.52 199.68 989.52C288.24 989.52 376.8 989.52 465.36 989.52C500.88 989.52 520.8 969.601 520.8 934.081C520.8 803.281 520.8 672.48 520.8 541.68C520.8 506.4 500.88 486.48 466.08 486.48ZM487.92 935.041C487.92 950.641 482.16 956.4 466.8 956.4C377.52 956.4 288.24 956.4 198.96 956.4C183.36 956.4 177.6 950.64 177.6 934.32C177.6 868.8 177.6 803.28 177.6 737.76C177.6 672.48 177.6 607.44 177.6 542.16C177.6 524.64 182.88 519.36 200.16 519.36C288.72 519.36 377.28 519.36 465.84 519.36C482.16 519.36 487.68 524.64 487.68 540.72C487.92 672.24 487.92 803.761 487.92 935.041Z" fill="#E20613"/> +<path d="M870.48 331.68C867.36 338.16 865.92 342.48 863.52 346.08C808.08 429.36 752.4 512.64 696.72 595.68C689.52 606.48 680.16 609.12 671.52 602.88C663.36 597.12 662.4 587.76 669.36 577.44C725.04 493.92 780.96 410.4 836.64 326.88C841.92 318.96 848.88 314.64 857.28 318.24C862.56 320.64 866.16 327.12 870.48 331.68Z" fill="#E20613"/> +<path d="M765.84 810.48C719.76 810.48 673.92 810.48 627.84 810.48C616.56 810.48 609.84 805.2 608.4 796.08C607.2 787.68 612.96 779.76 621.6 778.08C625.2 777.36 629.04 777.6 632.88 777.6C721.68 777.6 810.72 777.6 899.52 777.6C901.68 777.6 903.6 777.6 905.76 777.6C917.04 778.08 924.48 784.32 924.72 793.68C924.96 803.52 917.28 810.48 905.52 810.48C859.2 810.48 812.4 810.48 765.84 810.48Z" fill="#E20613"/> +<path d="M768 688.32C813.36 688.32 858.48 688.32 903.84 688.32C917.04 688.32 924.72 694.08 924.96 704.16C925.2 714.48 917.04 721.2 903.6 721.2C811.92 721.2 720.48 721.2 628.8 721.2C617.28 721.2 610.32 716.4 608.64 707.52C606.48 696.96 614.4 688.32 626.88 688.32C669.36 688.32 712.08 688.32 754.56 688.32C759.12 688.32 763.44 688.32 768 688.32Z" fill="#E20613"/> +<path d="M766.8 867.12C811.44 867.12 856.08 867.12 900.48 867.12C904.32 867.12 908.16 867.12 911.76 867.6C919.92 869.04 925.44 875.04 924.24 882.72C923.28 888.48 918.24 894.24 913.68 898.32C911.28 900.48 905.76 900 901.68 900C811.44 900 721.2 900 630.96 900C627.6 900 624 900 620.88 899.04C612.48 896.88 608.16 890.88 608.64 882.48C609.12 874.08 613.92 868.32 622.8 867.6C630.96 866.88 639.36 867.12 647.52 867.12C687.12 867.12 726.96 867.12 766.8 867.12Z" fill="#E20613"/> +<path d="M667.92 329.76C634.32 329.76 608.4 356.4 608.4 391.2C608.4 426.48 634.32 453.6 668.16 453.6C701.76 453.6 727.68 426.72 727.68 391.92C727.68 356.4 702 329.76 667.92 329.76ZM667.44 420.72C652.08 420.48 641.04 407.76 641.28 391.2C641.52 374.64 653.04 362.64 668.64 362.88C684.24 363.12 695.04 375.36 694.8 392.4C694.56 408.96 682.8 420.96 667.44 420.72Z" fill="#E20613"/> +<path d="M865.199 469.44C831.119 469.44 805.439 496.32 805.439 531.84C805.439 566.64 831.359 593.52 864.959 593.76C898.559 593.76 925.199 566.16 925.199 531.12C924.959 496.56 898.799 469.44 865.199 469.44ZM865.439 560.64C850.319 560.88 838.559 548.64 838.319 531.84C838.079 514.8 849.119 502.56 864.479 502.56C880.319 502.32 891.599 514.32 891.599 531.12C892.079 547.68 880.799 560.4 865.439 560.64Z" fill="#E20613"/> +<path d="M852.48 989.52C834.72 989.52 816.72 989.52 798.96 989.52C785.76 989.52 778.8 983.52 779.04 972.72C779.28 962.4 786.24 956.64 798.72 956.64C834 956.64 869.28 956.64 904.8 956.64C917.52 956.64 925.44 963.36 924.96 973.44C924.72 983.04 917.04 989.52 905.04 989.52C887.28 989.52 869.76 989.52 852.48 989.52Z" fill="#E20613"/> +<path d="M457.2 589.92C457.2 561.6 444.72 549.12 416.4 549.12C360.48 549.12 304.56 549.12 248.64 549.12C245.28 549.12 241.68 549.12 238.32 549.6C220.32 551.76 208.56 564.72 208.32 582.96C208.08 598.08 208.32 613.2 208.32 628.32C208.56 650.88 221.76 663.84 244.32 664.08C273.84 664.08 303.36 664.08 332.88 664.08C362.4 664.08 391.92 664.08 421.44 664.08C443.52 664.08 456.72 651.36 457.2 629.28C457.44 616.08 457.2 602.88 457.2 589.92ZM424.32 592.8C423.6 605.04 424.08 617.28 424.08 630.48H241.92V582.72C245.76 582.48 249.12 582.24 252.48 582.24C306 582.24 359.52 582.48 413.28 582C421.44 582 425.04 583.68 424.32 592.8Z" fill="#E20613"/> +<path d="M446.639 891.36C439.679 892.08 432.479 891.6 423.839 891.6C423.839 899.52 424.079 905.76 423.839 912.24C423.119 922.56 415.919 929.52 406.799 929.28C397.919 929.04 391.439 922.32 390.719 912.48C390.239 906 390.719 899.76 390.719 892.08C383.279 892.08 377.279 892.32 371.039 892.08C359.999 891.36 352.799 884.16 353.279 874.8C353.759 865.68 360.719 859.68 371.519 859.2C377.279 858.96 383.039 859.2 390.479 859.2C390.479 852.24 390.239 846.24 390.479 840.24C390.959 828.72 397.199 821.76 407.039 821.76C416.879 821.76 423.119 828.48 423.599 840C423.839 845.76 423.599 851.52 423.599 859.2C431.519 859.2 437.999 858.96 444.479 859.2C453.839 859.68 460.319 865.92 460.799 874.56C461.759 882.72 455.759 890.4 446.639 891.36Z" fill="#E20613"/> +<path d="M307.2 754.56C314.4 762 314.4 772.08 307.68 778.56C300.96 785.28 291.84 784.8 283.68 777.6C281.52 775.44 279.36 773.28 277.2 771.12C275.04 768.96 272.88 766.8 268.56 762.96C264.24 768 260.4 773.04 255.84 777.6C247.92 785.04 238.8 785.28 232.08 778.8C225.12 772.08 225.12 762.24 233.04 754.32C237.36 750 242.4 746.4 250.08 740.16C242.64 734.16 237.12 730.8 232.56 726C225.12 718.32 225.12 708.96 232.08 702.24C238.8 695.76 247.44 695.52 255.12 702.72C259.68 707.28 263.28 712.8 267.36 717.84C269.04 718.08 270.72 718.32 272.4 718.56C275.76 713.76 278.64 708.72 282.72 704.4C291.36 695.52 300.72 695.04 307.92 702.24C314.88 709.2 314.16 719.04 305.52 727.68C301.68 731.52 297.12 734.64 290.64 739.92C297.6 746.16 302.64 750 307.2 754.56Z" fill="#E20613"/> +<path d="M303.36 849.12C291.12 872.16 277.92 894.72 264.48 917.04C259.92 924.72 249.84 926.16 242.64 921.84C235.2 917.28 232.32 908.64 236.88 900.24C249.12 878.16 261.84 856.08 275.04 834.24C277.44 830.16 283.2 828 285.36 826.56C300.24 826.8 308.88 838.8 303.36 849.12Z" fill="#E20613"/> +<path d="M455.28 741.12C454.8 750.24 447.84 756.48 437.04 756.72C427.2 756.96 417.12 756.72 407.28 756.72C398.16 756.72 388.8 756.96 379.68 756.72C368.4 756.48 361.2 749.76 361.44 740.16C361.68 731.04 368.64 724.08 378.96 723.84C398.4 723.6 417.84 723.6 437.52 723.84C448.08 724.08 455.76 731.76 455.28 741.12Z" fill="#E20613"/> +<path d="M243.84 845.52C244.08 854.64 237.12 861.84 228 862.08C218.88 862.32 211.44 855.12 211.44 846.24C211.44 837.36 218.88 829.68 227.52 829.68C236.4 829.44 243.6 836.64 243.84 845.52Z" fill="#E20613"/> +<path d="M328.32 904.8C328.32 913.92 321.12 921.12 312 921.12C303.12 921.12 295.44 913.44 295.68 904.8C295.68 895.92 303.36 888.48 312.24 888.48C321.12 888.48 328.32 895.68 328.32 904.8Z" fill="#E20613"/> +</svg> diff --git a/public/images/icon_service/WARRANTY.svg b/public/images/icon_service/WARRANTY.svg new file mode 100644 index 00000000..2d3398e2 --- /dev/null +++ b/public/images/icon_service/WARRANTY.svg @@ -0,0 +1,8 @@ +<svg width="1200" height="1200" viewBox="0 0 1200 1200" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M1149.12 628.8C1148.16 617.28 1142.88 611.28 1132.32 607.44C1103.52 596.64 1075.2 584.64 1046.64 574.08C1038.72 571.2 1035.84 567.36 1035.84 558.72C1036.32 487.68 1036.08 416.4 1036.32 345.36C1036.32 336.24 1033.2 330 1024.56 326.64C1020.72 325.2 1016.88 323.28 1013.28 321.36C861.6 248.4 709.92 175.44 558.48 102.24C547.2 96.7198 537.84 95.9998 526.56 102.24C505.92 113.28 484.32 122.88 463.2 132.96C330 197.04 196.56 260.88 63.36 324.96C54.24 329.28 48 334.56 48 346.32C48.24 430.32 48.24 514.32 48.24 598.56H48.48C48.48 681.36 48.72 764.4 48.24 847.2C48.24 861.36 52.8 869.04 65.76 875.28C221.76 949.92 377.28 1025.04 533.04 1100.16C540.48 1103.76 546.24 1102.8 553.44 1099.44C642.48 1056.48 731.76 1013.76 821.04 970.8C827.28 967.68 831.84 967.44 838.32 972C863.76 990.24 892.08 1003.2 921.84 1012.8C926.64 1014.48 931.44 1014.96 936.24 1013.28C1001.52 992.16 1056 956.16 1093.92 897.84C1147.2 815.52 1158.24 724.08 1149.12 628.8ZM525.84 1052.16C525.84 1064.16 520.32 1058.4 515.76 1056.24C390.96 996.24 266.4 936.24 141.84 876.24C123.36 867.36 105.12 858.48 86.4 849.6C81.6 847.44 79.92 844.8 79.92 839.28C80.16 682.56 80.16 525.84 80.16 367.68C114.48 384.24 146.88 400.08 179.76 415.44C186.24 418.32 185.04 422.88 185.04 427.68C185.04 504.96 185.04 582.24 185.04 659.28C185.04 665.04 184.8 670.8 185.04 676.32C185.52 692.16 196.8 698.88 210.72 691.44C232.8 679.44 254.64 667.44 276.24 654.48C283.2 650.4 286.08 651.6 290.64 657.6C319.92 697.92 349.68 737.76 379.2 777.84C384.96 785.52 390.96 791.04 401.04 787.68C410.88 784.32 411.36 775.92 411.36 767.04C411.12 687.6 411.36 607.92 411.36 526.8C431.04 536.4 450 545.52 468.96 554.64C485.28 562.56 501.6 570.48 518.16 577.92C523.44 580.32 526.08 583.2 526.08 589.68C525.84 744 525.6 898.08 525.84 1052.16ZM370.32 507.12C375.6 509.76 379.44 511.92 379.44 519.36C378.96 585.6 379.2 651.6 379.2 717.84C379.2 719.28 378.96 720.48 378.72 724.08C354.24 690.96 331.2 659.76 307.92 628.56C294.48 610.56 291.12 609.84 271.44 621.12C253.68 631.2 235.92 641.04 217.2 651.6V433.92C223.92 437.28 230.16 440.4 236.4 443.28C281.04 464.4 325.68 486 370.32 507.12ZM237.6 407.52C270.96 391.44 302.16 376.08 333.6 360.96C374.4 341.04 415.44 321.36 456.24 301.44C460.8 299.28 464.64 297.84 469.92 300.48C520.08 324.72 570.24 348.72 622.32 373.68C610.56 379.68 600 384.96 589.2 390C527.76 419.76 466.32 449.28 404.88 479.04C399.6 481.44 395.28 483.36 389.04 480.24C339.36 456.24 289.44 432.48 237.6 407.52ZM532.32 549.36C499.92 533.28 467.04 517.92 434.16 502.08C435.36 498 439.2 497.76 441.84 496.56C513.84 461.76 585.84 427.2 658.08 392.4C659.76 391.68 661.44 390.72 663.12 389.76C669.84 386.64 674.64 382.08 674.88 374.4C675.12 366.24 669.84 361.44 662.88 358.08C624 339.36 584.88 320.64 546 301.92C523.2 290.88 500.16 280.32 477.36 268.8C468 264 459.84 264.48 450.48 269.28C370.8 308.16 290.88 346.56 211.2 385.44C204 389.04 198.24 388.8 191.04 385.44C161.76 371.04 132.48 357.12 101.28 342C160.8 313.44 218.64 285.84 276.48 258C362.64 216.72 448.56 175.2 534.72 133.92C540.24 131.28 544.8 130.56 550.56 133.44C693.6 202.56 836.64 271.44 979.68 340.56C980.4 340.8 980.88 341.28 982.8 342.48C962.88 352.08 943.68 361.44 924.24 370.56C800.64 430.08 677.04 489.36 553.44 549.12C545.76 552.72 540 553.2 532.32 549.36ZM795.84 947.04C718.32 984.24 640.8 1021.68 563.28 1059.12C562.32 1059.6 561.12 1059.36 558.96 1059.6V1047.12C558.96 896.4 559.2 745.92 558.72 595.2C558.72 585.36 561.36 580.8 570.24 576.48C712.56 508.32 854.88 439.92 996.96 371.52C998.88 370.56 1001.04 369.6 1003.68 368.4V556.8C983.76 548.88 963.84 541.68 944.4 533.52C933.84 528.96 924.48 529.2 913.92 533.52C851.04 558.72 787.68 583.44 724.56 607.92C714.96 611.52 709.92 617.28 708.96 627.84C703.68 674.64 705.12 721.2 713.52 767.52C714.24 771.84 715.92 776.4 713.76 781.68C707.28 777.12 701.76 780.48 696 783.36C676.56 792.96 656.88 801.84 637.68 811.68C625.44 817.68 623.76 832.08 634.08 839.28C637.92 841.92 642 843.84 646.8 841.44C671.76 829.68 696.48 817.68 722.16 805.44C728.64 826.08 736.56 847.44 746.4 867.6C735.12 863.52 725.52 866.88 715.2 872.16C690.24 884.88 664.8 896.64 639.6 908.88C628.32 914.4 624.48 922.56 628.8 931.44C632.88 940.32 642 942.48 653.04 937.2C678.72 924.96 703.92 912 730.08 900.72C742.32 895.44 750.72 888.72 751.2 874.8C762.96 898.56 778.8 919.2 797.28 937.92C801.36 942 802.56 943.92 795.84 947.04ZM1073.52 872.4C1040.64 925.44 993.36 959.52 935.04 979.92C929.52 981.84 925.44 980.16 920.88 978.48C823.2 943.2 767.76 871.92 746.64 772.08C737.76 729.84 734.88 687.12 739.2 643.92C739.92 637.44 742.08 634.8 747.84 632.64C806.16 609.84 864.24 587.04 922.32 564C927.36 562.08 931.44 562.08 936.24 564C994.32 587.04 1052.64 609.84 1110.96 632.4C1116.72 634.56 1118.88 637.44 1119.6 643.68C1121.04 657.84 1120.8 671.76 1121.28 688.56C1120.56 752.16 1108.8 815.28 1073.52 872.4ZM1042.8 672.72C1033.92 671.04 1028.88 676.8 1024.08 683.04C994.56 722.16 964.8 761.04 935.28 800.16C930.48 806.64 927.84 807.84 922.8 800.4C911.76 784.56 899.76 769.2 888.24 753.84C880.32 743.28 871.44 740.88 863.28 746.64C854.88 752.64 854.4 761.76 862.32 772.56C879.36 795.36 896.4 818.16 913.44 840.96C923.28 853.92 934.32 854.16 943.92 841.44C979.44 794.88 1014.72 748.32 1050.24 701.76C1053.36 697.68 1055.76 693.6 1056.48 688.32C1055.52 680.16 1051.44 674.4 1042.8 672.72Z" fill="#FEFEFE"/> +<path d="M1149.12 628.8C1148.16 617.28 1142.88 611.28 1132.32 607.44C1103.52 596.64 1075.2 584.64 1046.64 574.08C1038.72 571.2 1035.84 567.36 1035.84 558.72C1036.32 487.68 1036.08 416.4 1036.32 345.36C1036.32 336.24 1033.2 330 1024.56 326.64C1020.72 325.2 1016.88 323.28 1013.28 321.36C861.6 248.4 709.92 175.44 558.48 102.24C547.2 96.7198 537.84 95.9998 526.56 102.24C505.92 113.28 484.32 122.88 463.2 132.96C330 197.04 196.56 260.88 63.36 324.96C54.24 329.28 48 334.56 48 346.32C48.24 430.32 48.24 514.32 48.24 598.56H48.48C48.48 681.36 48.72 764.4 48.24 847.2C48.24 861.36 52.8 869.04 65.76 875.28C221.76 949.92 377.28 1025.04 533.04 1100.16C540.48 1103.76 546.24 1102.8 553.44 1099.44C642.48 1056.48 731.76 1013.76 821.04 970.8C827.28 967.68 831.84 967.44 838.32 972C863.76 990.24 892.08 1003.2 921.84 1012.8C926.64 1014.48 931.44 1014.96 936.24 1013.28C1001.52 992.16 1056 956.16 1093.92 897.84C1147.2 815.52 1158.24 724.08 1149.12 628.8ZM525.84 1052.16C525.84 1064.16 520.32 1058.4 515.76 1056.24C390.96 996.24 266.4 936.24 141.84 876.24C123.36 867.36 105.12 858.48 86.4 849.6C81.6 847.44 79.92 844.8 79.92 839.28C80.16 682.56 80.16 525.84 80.16 367.68C114.48 384.24 146.88 400.08 179.76 415.44C186.24 418.32 185.04 422.88 185.04 427.68C185.04 504.96 185.04 582.24 185.04 659.28C185.04 665.04 184.8 670.8 185.04 676.32C185.52 692.16 196.8 698.88 210.72 691.44C232.8 679.44 254.64 667.44 276.24 654.48C283.2 650.4 286.08 651.6 290.64 657.6C319.92 697.92 349.68 737.76 379.2 777.84C384.96 785.52 390.96 791.04 401.04 787.68C410.88 784.32 411.36 775.92 411.36 767.04C411.12 687.6 411.36 607.92 411.36 526.8C431.04 536.4 450 545.52 468.96 554.64C485.28 562.56 501.6 570.48 518.16 577.92C523.44 580.32 526.08 583.2 526.08 589.68C525.84 744 525.6 898.08 525.84 1052.16ZM370.32 507.12C375.6 509.76 379.44 511.92 379.44 519.36C378.96 585.6 379.2 651.6 379.2 717.84C379.2 719.28 378.96 720.48 378.72 724.08C354.24 690.96 331.2 659.76 307.92 628.56C294.48 610.56 291.12 609.84 271.44 621.12C253.68 631.2 235.92 641.04 217.2 651.6V433.92C223.92 437.28 230.16 440.4 236.4 443.28C281.04 464.4 325.68 486 370.32 507.12ZM237.6 407.52C270.96 391.44 302.16 376.08 333.6 360.96C374.4 341.04 415.44 321.36 456.24 301.44C460.8 299.28 464.64 297.84 469.92 300.48C520.08 324.72 570.24 348.72 622.32 373.68C610.56 379.68 600 384.96 589.2 390C527.76 419.76 466.32 449.28 404.88 479.04C399.6 481.44 395.28 483.36 389.04 480.24C339.36 456.24 289.44 432.48 237.6 407.52ZM532.32 549.36C499.92 533.28 467.04 517.92 434.16 502.08C435.36 498 439.2 497.76 441.84 496.56C513.84 461.76 585.84 427.2 658.08 392.4C659.76 391.68 661.44 390.72 663.12 389.76C669.84 386.64 674.64 382.08 674.88 374.4C675.12 366.24 669.84 361.44 662.88 358.08C624 339.36 584.88 320.64 546 301.92C523.2 290.88 500.16 280.32 477.36 268.8C468 264 459.84 264.48 450.48 269.28C370.8 308.16 290.88 346.56 211.2 385.44C204 389.04 198.24 388.8 191.04 385.44C161.76 371.04 132.48 357.12 101.28 342C160.8 313.44 218.64 285.84 276.48 258C362.64 216.72 448.56 175.2 534.72 133.92C540.24 131.28 544.8 130.56 550.56 133.44C693.6 202.56 836.64 271.44 979.68 340.56C980.4 340.8 980.88 341.28 982.8 342.48C962.88 352.08 943.68 361.44 924.24 370.56C800.64 430.08 677.04 489.36 553.44 549.12C545.76 552.72 540 553.2 532.32 549.36ZM795.84 947.04C718.32 984.24 640.8 1021.68 563.28 1059.12C562.32 1059.6 561.12 1059.36 558.96 1059.6V1047.12C558.96 896.4 559.2 745.92 558.72 595.2C558.72 585.36 561.36 580.8 570.24 576.48C712.56 508.32 854.88 439.92 996.96 371.52C998.88 370.56 1001.04 369.6 1003.68 368.4V556.8C983.76 548.88 963.84 541.68 944.4 533.52C933.84 528.96 924.48 529.2 913.92 533.52C851.04 558.72 787.68 583.44 724.56 607.92C714.96 611.52 709.92 617.28 708.96 627.84C703.68 674.64 705.12 721.2 713.52 767.52C714.24 771.84 715.92 776.4 713.76 781.68C707.28 777.12 701.76 780.48 696 783.36C676.56 792.96 656.88 801.84 637.68 811.68C625.44 817.68 623.76 832.08 634.08 839.28C637.92 841.92 642 843.84 646.8 841.44C671.76 829.68 696.48 817.68 722.16 805.44C728.64 826.08 736.56 847.44 746.4 867.6C735.12 863.52 725.52 866.88 715.2 872.16C690.24 884.88 664.8 896.64 639.6 908.88C628.32 914.4 624.48 922.56 628.8 931.44C632.88 940.32 642 942.48 653.04 937.2C678.72 924.96 703.92 912 730.08 900.72C742.32 895.44 750.72 888.72 751.2 874.8C762.96 898.56 778.8 919.2 797.28 937.92C801.36 942 802.56 943.92 795.84 947.04ZM1073.52 872.4C1040.64 925.44 993.36 959.52 935.04 979.92C929.52 981.84 925.44 980.16 920.88 978.48C823.2 943.2 767.76 871.92 746.64 772.08C737.76 729.84 734.88 687.12 739.2 643.92C739.92 637.44 742.08 634.8 747.84 632.64C806.16 609.84 864.24 587.04 922.32 564C927.36 562.08 931.44 562.08 936.24 564C994.32 587.04 1052.64 609.84 1110.96 632.4C1116.72 634.56 1118.88 637.44 1119.6 643.68C1121.04 657.84 1120.8 671.76 1121.28 688.56C1120.56 752.16 1108.8 815.28 1073.52 872.4ZM1042.8 672.72C1033.92 671.04 1028.88 676.8 1024.08 683.04C994.56 722.16 964.8 761.04 935.28 800.16C930.48 806.64 927.84 807.84 922.8 800.4C911.76 784.56 899.76 769.2 888.24 753.84C880.32 743.28 871.44 740.88 863.28 746.64C854.88 752.64 854.4 761.76 862.32 772.56C879.36 795.36 896.4 818.16 913.44 840.96C923.28 853.92 934.32 854.16 943.92 841.44C979.44 794.88 1014.72 748.32 1050.24 701.76C1053.36 697.68 1055.76 693.6 1056.48 688.32C1055.52 680.16 1051.44 674.4 1042.8 672.72Z" fill="#E20613"/> +<path d="M750.96 874.8C750.48 888.72 742.08 895.44 729.84 900.72C703.92 912.24 678.48 925.2 652.8 937.2C641.76 942.48 632.64 940.32 628.56 931.44C624.24 922.56 628.08 914.4 639.36 908.88C664.56 896.64 690 884.88 714.96 872.16C725.04 867.12 734.88 863.52 746.16 867.6C706.8 872.4 675.6 897.36 640.32 911.76C631.2 915.6 628.56 923.52 632.16 930.24C635.76 936.96 643.2 938.88 652.08 934.56C679.68 921.12 707.76 908.16 735.36 894.72C741.12 891.84 745.2 887.76 746.4 881.28C747.12 878.64 746.16 874.32 750.96 874.8Z" fill="#FEFEFE"/> +<path d="M1056.48 688.32C1056 693.84 1053.36 697.92 1050.24 701.76C1014.72 748.32 979.44 794.88 943.92 841.44C934.32 854.16 923.04 853.68 913.44 840.96C896.4 818.16 879.36 795.36 862.32 772.56C854.4 761.76 854.64 752.88 863.28 746.64C871.44 740.88 880.32 743.28 888.24 753.84C899.76 769.2 911.76 784.56 922.8 800.4C927.84 807.84 930.48 806.4 935.28 800.16C964.56 761.04 994.56 722.16 1024.08 683.04C1028.88 676.8 1033.92 671.04 1042.8 672.72C1051.44 674.4 1055.52 680.16 1056.48 688.32Z" fill="#FEFEFE"/> +<path d="M750.96 874.8C750.48 888.72 742.08 895.44 729.84 900.72C703.92 912.24 678.48 925.2 652.8 937.2C641.76 942.48 632.64 940.32 628.56 931.44C624.24 922.56 628.08 914.4 639.36 908.88C664.56 896.64 690 884.88 714.96 872.16C725.04 867.12 734.88 863.52 746.16 867.6C747.6 870.24 751.44 871.2 750.96 874.8Z" fill="#E20613"/> +<path d="M1056.48 688.32C1056 693.84 1053.36 697.92 1050.24 701.76C1014.72 748.32 979.44 794.88 943.92 841.44C934.32 854.16 923.04 853.68 913.44 840.96C896.4 818.16 879.36 795.36 862.32 772.56C854.4 761.76 854.64 752.88 863.28 746.64C871.44 740.88 880.32 743.28 888.24 753.84C899.76 769.2 911.76 784.56 922.8 800.4C927.84 807.84 930.48 806.4 935.28 800.16C964.56 761.04 994.56 722.16 1024.08 683.04C1028.88 676.8 1033.92 671.04 1042.8 672.72C1051.44 674.4 1055.52 680.16 1056.48 688.32Z" fill="#E20613"/> +</svg> diff --git a/src/core/components/elements/Image/Image.jsx b/src/core/components/elements/Image/Image.jsx index ba6bf50d..d7b19821 100644 --- a/src/core/components/elements/Image/Image.jsx +++ b/src/core/components/elements/Image/Image.jsx @@ -9,18 +9,18 @@ import 'react-lazy-load-image-component/src/effects/opacity.css' * @param {string} props.alt - Alternative text to be displayed if the image is not found. * @returns {JSX.Element} - Rendered `Image` component. */ -const Image = ({ ...props }) => ( - <> +const Image = ({ ...props }) => { + return ( <LazyLoadImage {...props} src={props.src || '/images/noimage.jpeg'} placeholderSrc='/images/indoteknik-placeholder.png' + effect='opacity' alt={props.src ? props.alt : 'Image Not Found - Indoteknik'} wrapperClassName='bg-white' + loading='eager' /> - </> -) - -Image.defaultProps = LazyLoadImage.defaultProps + ) +} export default Image diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx index 3aba55c9..fb94e4a6 100644 --- a/src/core/components/elements/Navbar/NavbarDesktop.jsx +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -111,26 +111,6 @@ const NavbarDesktop = () => { Quotation </Link> <Cardheader cartCount={cartCount}/> - {/* <Link - href='/shop/cart' - target='_blank' - rel='noreferrer' - className='flex items-center gap-x-2 !text-gray_r-12/80' - > - <div className={`relative ${cartCount > 0 && 'mr-2'}`}> - <ShoppingCartIcon className='w-7' /> - {cartCount > 0 && ( - <span className='absolute -top-2 -right-2 badge-solid-red rounded-full w-5 h-5 flex items-center justify-center'> - {cartCount} - </span> - )} - </div> - <span> - Keranjang - <br /> - Belanja - </span> - </Link> */} <Link target='_blank' rel='noreferrer' diff --git a/src/core/components/elements/Skeleton/ProductCardSkeleton.jsx b/src/core/components/elements/Skeleton/ProductCardSkeleton.jsx index 84d1c0d1..1e0ca6a3 100644 --- a/src/core/components/elements/Skeleton/ProductCardSkeleton.jsx +++ b/src/core/components/elements/Skeleton/ProductCardSkeleton.jsx @@ -1,26 +1,46 @@ -const ProductCardSkeleton = () => ( - <div - role='status' - className='p-4 max-w-sm rounded border border-gray-300 shadow animate-pulse md:p-6' - > - <div className='flex items-center justify-center h-36 mb-4 bg-gray-300 rounded' aria-busy> - <svg - className='w-12 h-12 text-gray-200' - xmlns='http://www.w3.org/2000/svg' - aria-hidden='true' - fill='currentColor' - viewBox='0 0 640 512' - > - <path d='M480 80C480 35.82 515.8 0 560 0C604.2 0 640 35.82 640 80C640 124.2 604.2 160 560 160C515.8 160 480 124.2 480 80zM0 456.1C0 445.6 2.964 435.3 8.551 426.4L225.3 81.01C231.9 70.42 243.5 64 256 64C268.5 64 280.1 70.42 286.8 81.01L412.7 281.7L460.9 202.7C464.1 196.1 472.2 192 480 192C487.8 192 495 196.1 499.1 202.7L631.1 419.1C636.9 428.6 640 439.7 640 450.9C640 484.6 612.6 512 578.9 512H55.91C25.03 512 .0006 486.1 .0006 456.1L0 456.1z' /> - </svg> - </div> - <div className='h-2 bg-gray-200 rounded-full w-10 mb-1'></div> - <div className='h-2.5 bg-gray-200 rounded-full w-full mb-4'></div> - <div className='h-2 bg-gray-200 rounded-full mb-2.5'></div> - <div className='h-2 bg-gray-200 rounded-full mb-2.5'></div> - <div className='h-2 bg-gray-200 rounded-full'></div> - <span className='sr-only'>Loading...</span> - </div> -) +import { Box, HStack, Skeleton, SkeletonText, VStack, useBreakpointValue } from '@chakra-ui/react' + +const ProductCardSkeleton = () => { + const wrapperHeight = useBreakpointValue({ base: '300px', md: '350px' }) + return ( + <Box + role='status' + w='100%' + bgColor='white' + h={wrapperHeight} + borderWidth='1px' + borderRadius='md' + > + <Skeleton height='50%' {...skeletonColors} /> + + <VStack padding='10px 12px 16px 12px' height='50%'> + <Box w='full'> + <Skeleton height='12px' w='30%' {...skeletonColors} /> + <SkeletonText + noOfLines={2} + spacing='8px' + skeletonHeight='12px' + mt='12px' + {...skeletonColors} + /> + </Box> + + <VStack spacing='12px' alignItems='flex-start' mt='20px' w='full'> + <HStack spacing='8px' w='full'> + <Skeleton height='12px' w='60%' {...skeletonColors} /> + <Skeleton height='12px' w='10%' {...skeletonColors} /> + </HStack> + <Skeleton height='12px' w='50%' {...skeletonColors} /> + </VStack> + </VStack> + <span className='sr-only'>Loading...</span> + </Box> + ) +} + +const skeletonColors = { + startColor: 'gray.200', + endColor: 'gray.400' +} export default ProductCardSkeleton diff --git a/src/lib/brand/components/Brands.jsx b/src/lib/brand/components/Brands.jsx index c7483e40..f6cb4fbf 100644 --- a/src/lib/brand/components/Brands.jsx +++ b/src/lib/brand/components/Brands.jsx @@ -1,7 +1,7 @@ -import odooApi from '@/core/api/odooApi' import { useCallback, useEffect, useState } from 'react' import BrandCard from './BrandCard' import LogoSpinner from '@/core/components/elements/Spinner/LogoSpinner' +import axios from 'axios' const Brands = () => { const alpha = Array.from(Array(26)).map((e, i) => i + 65) @@ -13,13 +13,18 @@ const Brands = () => { const loadBrand = useCallback(async () => { setIsLoading(true) - const name = startWith ? `${startWith}%` : '' - const result = await odooApi( + const name = startWith ? `${startWith}*` : '' + //Get brand from odoo + /*const result = await odooApi( 'GET', `/api/v1/manufacture?limit=0&offset=${manufactures.length}&name=${name}` - ) + )*/ + + // Change get brands from solr + const result = await axios(`${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/brands?params=${name}`) + setIsLoading(false) - setManufactures((manufactures) => [...manufactures, ...result.manufactures]) + setManufactures((manufactures) => [...result.data]) }, [startWith]) const toggleStartWith = (alphabet) => { diff --git a/src/lib/cart/components/Cartheader.jsx b/src/lib/cart/components/Cartheader.jsx index dd6c276e..cbe7c7e1 100644 --- a/src/lib/cart/components/Cartheader.jsx +++ b/src/lib/cart/components/Cartheader.jsx @@ -48,7 +48,7 @@ const Cardheader = (cartCount) => { setProductCart(cart) setCountCart(cart.productTotal) setIsloading(false) - }, [setProductCart]) + }, [setProductCart, setIsloading]) useEffect(() => { if (!products) return @@ -158,14 +158,14 @@ const Cardheader = (cartCount) => { </div> </div> ))} - {products.length === 0 && !isLoading && ( + {auth && products.length === 0 && !isLoading && ( <div className='justify-center p-4'> <p className='text-gray-500 text-center '> Tidak Ada Produk di Keranjang Belanja Anda </p> </div> )} - {products.length > 0 && !isLoading && ( + {auth && products.length > 0 && !isLoading && ( <> <ul role='list' class='divide-y divide-gray-200 dark:divide-gray-700'> {products && @@ -251,11 +251,11 @@ const Cardheader = (cartCount) => { </> )} </div> - {products.length > 0 && !isLoading && ( + {auth && products.length > 0 && !isLoading && ( <> <div className='mt-3'> - <span className='text-gray-400 text-caption-2'>Sub Total Sebelum PPN : </span> - <span className='font-semibold text-red-600'>Rp. {currencyFormat(subTotal)}</span> + <span className='text-gray-400 text-caption-2'>Subtotal Sebelum PPN : </span> + <span className='font-semibold text-red-600'>{currencyFormat(subTotal)}</span> </div> <div className='mt-5 mb-2'> <button diff --git a/src/lib/checkout/components/CheckoutOld.jsx b/src/lib/checkout/components/CheckoutOld.jsx index 088b641b..6852059e 100644 --- a/src/lib/checkout/components/CheckoutOld.jsx +++ b/src/lib/checkout/components/CheckoutOld.jsx @@ -22,7 +22,6 @@ import DesktopView from '@/core/components/views/DesktopView' import ExpedisiList from '../api/ExpedisiList' import whatsappUrl from '@/core/utils/whatsappUrl' import { createSlug } from '@/core/utils/slug' -import { Button, Modal } from 'flowbite-react' import BottomPopup from '@/core/components/elements/Popup/BottomPopup' const SELF_PICKUP_ID = 32 diff --git a/src/lib/home/components/PreferredBrand.jsx b/src/lib/home/components/PreferredBrand.jsx index 55abe0b7..571c4745 100644 --- a/src/lib/home/components/PreferredBrand.jsx +++ b/src/lib/home/components/PreferredBrand.jsx @@ -6,7 +6,9 @@ import useDevice from '@/core/hooks/useDevice' import Link from '@/core/components/elements/Link/Link' const PreferredBrand = () => { - const { preferredBrands } = usePreferredBrand() + let query = 'level_s' + let params = 'prioritas' + const { preferredBrands } = usePreferredBrand(query) const { isMobile, isDesktop } = useDevice() return ( @@ -22,7 +24,7 @@ const PreferredBrand = () => { {preferredBrands.isLoading && <PreferredBrandSkeleton />} {!preferredBrands.isLoading && ( <Swiper slidesPerView={isMobile ? 3.5 : 7.5} spaceBetween={isMobile ? 12 : 24} freeMode> - {preferredBrands.data?.manufactures.map((brand) => ( + {preferredBrands.data?.data.map((brand) => ( <SwiperSlide key={brand.id}> <BrandCard brand={brand} /> </SwiperSlide> diff --git a/src/lib/home/components/ServiceList.jsx b/src/lib/home/components/ServiceList.jsx new file mode 100644 index 00000000..b8799d7d --- /dev/null +++ b/src/lib/home/components/ServiceList.jsx @@ -0,0 +1,105 @@ +import Image from 'next/image' +import Link from '@/core/components/elements/Link/Link' + +const ServiceList = () => { + return ( + <div className='px-4 sm:px-0'> + <div className='grid md:grid-cols-4 grid-cols-2 justify-between gap-2 items-center'> + <div className='w-full'> + <Link + href='/tentang-kami' + className='border border-gray-200 p-2 flex items-center gap-x-2 rounded-lg' + > + <div className=''> + <Image + width={24} + height={24} + quality={100} + src='/images/icon_service/ONE-STOP-SOLUTIONS.svg' + alt='' + className='h-20 w-20 rounded' + /> + </div> + <div className=''> + <h1 className='text-gray-900 font-semibold text-base'>One Stop Solution</h1> + <p className='text-xs md:text-sm text-gray-500'> + Temukan Solusi Lengkap Anda dalam Satu Tempat. + </p> + </div> + </Link> + </div> + <div className='w-full'> + <Link + href='/tentang-kami' + className='border border-gray-200 p-2 flex items-center gap-x-2 rounded-lg' + > + <div className=''> + <Image + width={24} + height={24} + quality={100} + src='/images/icon_service/WARRANTY.svg' + alt='' + className='h-20 w-20 rounded' + /> + </div> + <div> + <h1 className='text-gray-900 font-semibold text-base'>Garansi Resmi</h1> + <p className='text-xs md:text-sm text-gray-500'> + Garansi Keaslian Barang dan Jaminan Purna Jual. + </p> + </div> + </Link> + </div> + <div className='w-full '> + <Link + href='/tentang-kami' + className='border border-gray-200 p-2 flex items-center gap-x-2 rounded-lg' + > + <div className=''> + <Image + width={24} + height={24} + quality={100} + src='/images/icon_service/DUE-PAYMENT.svg' + alt='' + className='h-20 w-20 rounded' + /> + </div> + <div> + <h1 className='text-gray-900 font-semibold text-base'>Pembayaran Tempo</h1> + <p className='text-xs md:text-sm text-gray-500'> + Lebih mudah mengatur pembelian dengan pembayaran tempo. + </p> + </div> + </Link> + </div> + <div className='w-full'> + <Link + href='/tentang-kami' + className='border border-gray-200 p-2 flex items-center gap-x-2 rounded-lg' + > + <div className=''> + <Image + width={24} + height={24} + quality={100} + src='/images/icon_service/TAX.svg' + alt='' + className='h-20 w-20 rounded' + /> + </div> + <div> + <h1 className='text-gray-900 font-semibold text-base'>Faktur Pajak</h1> + <p className='text-xs md:text-sm text-gray-500'> + Dapat Faktur pajak untuk setiap transaksi dengan indoteknik.com + </p> + </div> + </Link> + </div> + </div> + </div> + ) +} + +export default ServiceList diff --git a/src/lib/home/components/Skeleton/PopularProductSkeleton.jsx b/src/lib/home/components/Skeleton/PopularProductSkeleton.jsx index 29fda966..754bdd57 100644 --- a/src/lib/home/components/Skeleton/PopularProductSkeleton.jsx +++ b/src/lib/home/components/Skeleton/PopularProductSkeleton.jsx @@ -11,7 +11,8 @@ const PopularProductSkeleton = () => ( </div> </MobileView> <DesktopView> - <div className='grid grid-cols-5 gap-x-3'> + <div className='grid grid-cols-6 gap-x-3'> + <ProductCardSkeleton /> <ProductCardSkeleton /> <ProductCardSkeleton /> <ProductCardSkeleton /> diff --git a/src/lib/home/hooks/usePreferredBrand.js b/src/lib/home/hooks/usePreferredBrand.js index e56d361f..b7d707e6 100644 --- a/src/lib/home/hooks/usePreferredBrand.js +++ b/src/lib/home/hooks/usePreferredBrand.js @@ -1,3 +1,4 @@ +import axios from 'axios' import preferredBrandApi from '../api/preferredBrandApi' import { useQuery } from 'react-query' @@ -10,4 +11,14 @@ const usePreferredBrand = () => { } } -export default usePreferredBrand +const GetBrands = (query) => { + const fetchingbrand = async () => + await axios(`${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/brands?params=` + query) + + const { data, isLoading } = useQuery('preferredBrand', fetchingbrand) + return { + preferredBrands: { data, isLoading } + } +} + +export default GetBrands diff --git a/src/lib/product/components/Product/ColumnsSLA.jsx b/src/lib/product/components/Product/ColumnsSLA.jsx index 33da703a..e5296f96 100644 --- a/src/lib/product/components/Product/ColumnsSLA.jsx +++ b/src/lib/product/components/Product/ColumnsSLA.jsx @@ -1,8 +1,9 @@ import odooApi from '@/core/api/odooApi' import { createSlug } from '@/core/utils/slug' import whatsappUrl from '@/core/utils/whatsappUrl' -import { Button, Spinner } from 'flowbite-react' -import { memo, useEffect, useState } from 'react' +import { Box, Skeleton, Tooltip } from '@chakra-ui/react' +import { Info } from 'lucide-react' +import { memo } from 'react' import { useQuery } from 'react-query' const ColumnSLA = ({ variant, product }) => { @@ -12,67 +13,35 @@ const ColumnSLA = ({ variant, product }) => { return ( <> <td> - {dataSLA.isFetching ? ( - <div className='text-center'> - <Spinner aria-label='Center-aligned spinner example' /> - </div> - ) : dataSLA?.data?.qty > 0 ? ( - dataSLA?.data?.qty - ) : ( - <a - href={whatsappUrl('product', { - name: variant.name, - manufacture: product.manufacture?.name, - url: createSlug('/shop/product/', product.name, product.id, true) - })} - className='text-danger-500 font-medium' - target='_blank' - rel='noreferrer noopener' - > - Tanya Admin - </a> - )} + <Skeleton isLoaded={!dataSLA.isFetching} w='full'> + {dataSLA?.data?.qty > 0 ? ( + dataSLA?.data?.qty + ) : ( + <a + href={whatsappUrl('product', { + name: variant.name, + manufacture: product.manufacture?.name, + url: createSlug('/shop/product/', product.name, product.id, true) + })} + className='text-danger-500 font-medium' + target='_blank' + rel='noreferrer noopener' + > + Tanya Admin + </a> + )} + </Skeleton> </td> + <td className='flex justify-center'> - {dataSLA.isFetching ? ( - <Button color='gray'> - <Spinner aria-label='Alternate spinner button example' /> - <span className='pl-3'>Loading...</span> - </Button> - ) : dataSLA?.data?.slaDate != '-' ? ( - <button - type='button' - title={`Masa Persiapan Barang ${dataSLA?.data?.slaDate}`} - className={`flex gap-x-1 items-center p-2 rounded-lg w-full ${ - dataSLA?.data?.slaDate === 'indent' ? 'bg-indigo-900' : 'btn-light' - }`} - > - <div - className={`flex-1 text-caption-1 ${ - dataSLA?.data?.slaDate === 'indent' ? 'text-white' : '' - }`} - > + <Skeleton isLoaded={!dataSLA.isFetching} w='75%'> + <Tooltip placement='top' label={`Masa Persiapan Barang ${dataSLA?.data?.slaDate}`}> + <Box className='border border-gray_r-7 rounded-md p-2 flex justify-center items-center gap-x-2'> {dataSLA?.data?.slaDate} - </div> - <div className='flex-end'> - <svg - aria-hidden='true' - fill='none' - stroke='currentColor' - stroke-width='1.5' - className={`w-7 h-7 ${dataSLA?.data?.slaDate === 'indent' ? 'text-white' : ''}`} - > - <path - d='M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z' - stroke-linecap='round' - stroke-linejoin='round' - ></path> - </svg> - </div> - </button> - ) : ( - '-' - )} + <Info size={16} /> + </Box> + </Tooltip> + </Skeleton> </td> </> ) diff --git a/src/lib/product/components/Product/ProductDesktop.jsx b/src/lib/product/components/Product/ProductDesktop.jsx index 6da289bc..0df60673 100644 --- a/src/lib/product/components/Product/ProductDesktop.jsx +++ b/src/lib/product/components/Product/ProductDesktop.jsx @@ -15,7 +15,6 @@ import ProductCard from '../ProductCard' import productSimilarApi from '../../api/productSimilarApi' import whatsappUrl from '@/core/utils/whatsappUrl' import odooApi from '@/core/api/odooApi' -import { Button, Spinner } from 'flowbite-react' import PromotionType from '@/lib/promotinProgram/components/PromotionType' import useAuth from '@/core/hooks/useAuth' import ImageNext from 'next/image' @@ -23,6 +22,8 @@ import CountDown2 from '@/core/components/elements/CountDown/CountDown2' import { LazyLoadComponent } from 'react-lazy-load-image-component' import ColumnsSLA from './ColumnsSLA' import { useProductCartContext } from '@/contexts/ProductCartContext' +import { Box, Skeleton, Tooltip } from '@chakra-ui/react' +import { Info } from 'lucide-react' const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { const router = useRouter() @@ -40,7 +41,7 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { const [selectVariantPromoActive, setSelectVariantPromoActive] = useState(null) const [backgorundFlashSale, setBackgorundFlashSale] = useState(null) - const {setRefreshCart , refreshCart} = useProductCartContext() + const { setRefreshCart, refreshCart } = useProductCartContext() const getLowestPrice = useCallback(() => { const prices = product.variants.map((variant) => variant.price) @@ -256,16 +257,16 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { <h1 className='text-title-md leading-10 font-medium'>{product?.name}</h1> <div className='mt-10'> <div className='flex p-3'> - <div className='w-1/4 text-gray_r-12/70'>Nomor SKU</div> - <div className='w-3/4'>SKU-{product.id}</div> + <div className='w-4/12 text-gray_r-12/70'>Nomor SKU</div> + <div className='w-8/12'>SKU-{product.id}</div> </div> <div className='flex p-3 bg-gray_r-4'> - <div className='w-1/4 text-gray_r-12/70'>Part Number</div> - <div className='w-3/4'>{product.code || '-'}</div> + <div className='w-4/12 text-gray_r-12/70'>Part Number</div> + <div className='w-8/12'>{product.code || '-'}</div> </div> <div className='flex p-3'> - <div className='w-1/4 text-gray_r-12/70'>Manufacture</div> - <div className='w-3/4'> + <div className='w-4/12 text-gray_r-12/70'>Manufacture</div> + <div className='w-8/12'> {product.manufacture?.name ? ( <Link href={createSlug( @@ -282,9 +283,9 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { </div> </div> <div className='flex p-3 items-center bg-gray_r-4'> - <div className='w-1/4 text-gray_r-12/70'>Persiapan Barang</div> - <div className='w-3/4'> - {product.variants.length > 1 ? ( + <div className='w-4/12 text-gray_r-12/70'>Persiapan Barang</div> + <div className='w-8/12'> + {product.variants.length > 1 && ( <button type='button' onClick={goToVariantSection} @@ -292,62 +293,32 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { > <span className='text-red-600 text-sm'>Lihat Selengkapnya</span> </button> - ) : product.variants[0].sla ? ( - product.variants[0].sla?.slaDate != '-' ? ( - <button - type='button' - title={`Masa Persiapan Barang ${product.variants[0].sla?.slaDate}`} - className={`flex gap-x-1 items-center p-2 rounded-lg w-auto ${ - product.variants[0].sla?.slaDate === 'indent' - ? 'bg-indigo-900' - : 'btn-light' - }`} - > - <div - className={`flex-1 text-caption-1 ${ - product.variants[0].sla?.slaDate === 'indent' ? 'text-white' : '' - }`} + )} + + {product.variants.length === 1 && ( + <> + {!product.variants[0]?.sla && <Skeleton width='20%' height='16px' />} + {product.variants[0]?.sla && ( + <Tooltip + placement='top' + label={`Masa Persiapan Barang ${product.variants[0]?.sla?.slaDate}`} > - {product.variants[0].sla?.slaDate} - </div> - <div className='flex-end'> - <svg - aria-hidden='true' - fill='none' - stroke='currentColor' - stroke-width='1.5' - className={`w-7 h-7 ${ - product.variants[0].sla?.slaDate === 'indent' ? 'text-white' : '' - }`} - > - <path - d='M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z' - stroke-linecap='round' - stroke-linejoin='round' - ></path> - </svg> - </div> - </button> - ) : ( - '-' - ) - ) : ( - <Button color='gray'> - <Spinner aria-label='Alternate spinner button example' /> - <span className='pl-3'>Loading...</span> - </Button> + <Box className='w-fit flex items-center gap-x-2'> + {product.variants[0]?.sla?.slaDate} + <Info size={16} /> + </Box> + </Tooltip> + )} + </> )} </div> </div> + {product.variants.length === 1 && ( <div className='flex p-3 '> - <div className='w-1/4 text-gray_r-12/70'>Stock</div> - <div className='w-3/4'> - {isLoadingSLA && ( - <div className=''> - <Spinner aria-label='Center-aligned spinner example' /> - </div> - )} + <div className='w-4/12 text-gray_r-12/70'>Stock</div> + <div className='w-8/12'> + {!product.variants[0]?.sla && <Skeleton width='10%' height='16px' />} {product?.variants[0].sla?.qty > 0 && ( <span>{product?.variants[0].sla?.qty}</span> )} @@ -366,9 +337,10 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { </div> </div> )} + <div className={`flex p-3 ${product.variants.length > 1 ? '' : 'bg-gray_r-4'} `}> - <div className='w-1/4 text-gray_r-12/70'>Berat Barang</div> - <div className='w-3/4'> + <div className='w-4/12 text-gray_r-12/70'>Berat Barang</div> + <div className='w-8/12'> {product?.weight > 0 && <span>{product?.weight} KG</span>} {product?.weight == 0 && ( <a @@ -441,13 +413,13 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { <div className='text-gray_r-12/80'>Harga mulai dari: </div> )} - {lowestPrice?.discountPercentage > 0 && ( + {/* {lowestPrice?.discountPercentage > 0 && ( <div className='flex gap-x-1 items-center mt-2'> <div className='badge-solid-red text-caption-1'> {lowestPrice?.discountPercentage}% </div> - <div className='text-gray_r-11 line-through text-caption-1'> - {currencyFormat(lowestPrice?.price)} + <div className='text-gray_r-9 text-caption-1'> + Include PPN {currencyFormat(lowestPrice?.price * process.env.NEXT_PUBLIC_PPN)} </div> {product.flashSale.remainingTime > 0 && ( <div className='bg-red-600 rounded-full mb-1 p-2 pl-3 pr-3 flex w-fit items-center gap-x-1'> @@ -464,28 +436,54 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { </div> )} </div> + )} */} + + {product?.flashSale?.remainingTime > 0 ? ( + <> + <div className='flex gap-x-1 items-center mt-2'> + <div className='badge-solid-red text-caption-1'> + {lowestPrice?.discountPercentage}% + </div> + <div className='text-gray_r-9 line-through text-caption-1'> + {currencyFormat(lowestPrice?.price)} + </div> + <div className='text-danger-500 font-semibold text-xl'> + {currencyFormat(lowestPrice?.priceDiscount)} + </div> + </div> + <div className='text-gray_r-9 text-base font-normal mt-1'> + Termasuk PPN: {currencyFormat(lowestPrice?.priceDiscount * process.env.NEXT_PUBLIC_PPN)} + </div> + </> + ) : ( + <h3 className='text-danger-500 font-semibold mt-1 text-title-md'> + {lowestPrice?.price > 0 ? ( + <> + {currencyFormat(lowestPrice?.price)} + <div className='text-gray_r-9 text-base font-normal mt-1'> + Termasuk PPN: {currencyFormat(lowestPrice?.price * process.env.NEXT_PUBLIC_PPN)} + </div> + </> + ) : ( + <span className='text-gray_r-12/90 font-normal text-h-sm'> + Hubungi kami untuk dapatkan harga terbaik, + <a + href={whatsappUrl('product', { + name: product.name, + manufacture: product.manufacture?.name, + url: createSlug('/shop/product/', product.name, product.id, true) + })} + className='text-danger-500 underline' + rel='noopener noreferrer' + target='_blank' + > + klik disini + </a> + </span> + )} + </h3> )} - <h3 className='text-danger-500 font-semibold mt-1 text-title-md'> - {lowestPrice?.priceDiscount > 0 ? ( - currencyFormat(lowestPrice?.priceDiscount) - ) : ( - <span className='text-gray_r-12/90 font-normal text-h-sm'> - Hubungi kami untuk dapatkan harga terbaik, - <a - href={whatsappUrl('product', { - name: product.name, - manufacture: product.manufacture?.name, - url: createSlug('/shop/product/', product.name, product.id, true) - })} - className='text-danger-500 underline' - rel='noopener noreferrer' - target='_blank' - > - klik disini - </a> - </span> - )} - </h3> + {product.variants.length > 1 ? ( <button type='button' diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx index 940ba46f..51739bc9 100644 --- a/src/lib/product/components/Product/ProductDesktopVariant.jsx +++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx @@ -16,7 +16,9 @@ import productSimilarApi from '../../api/productSimilarApi' import whatsappUrl from '@/core/utils/whatsappUrl' import useAuth from '@/core/hooks/useAuth' import odooApi from '@/core/api/odooApi' -import { Button, Spinner } from 'flowbite-react' +import { useProductCartContext } from '@/contexts/ProductCartContext' +import { Box, Skeleton, Tooltip } from '@chakra-ui/react' +import { Info } from 'lucide-react' const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) => { const router = useRouter() @@ -28,6 +30,8 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) const [addCartAlert, setAddCartAlert] = useState(false) const [isLoadingSLA, setIsLoadingSLA] = useState(true) + const { setRefreshCart } = useProductCartContext() + const getLowestPrice = useCallback(() => { const lowest = product.price /* const lowest = prices.reduce((lowest, price) => { @@ -71,6 +75,8 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) programLineId: null, selected: true, source: null + }).then(() => { + setRefreshCart(true) }) setAddCartAlert(true) } @@ -144,16 +150,16 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) <h1 className='text-title-md leading-10 font-medium'>{product?.name}</h1> <div className='mt-10'> <div className='flex p-3'> - <div className='w-1/4 text-gray_r-12/70'>Nomor SKU</div> - <div className='w-3/4'>SKU-{product.id}</div> + <div className='w-4/12 text-gray_r-12/70'>Nomor SKU</div> + <div className='w-8/12'>SKU-{product.id}</div> </div> <div className='flex p-3 bg-gray_r-4'> - <div className='w-1/4 text-gray_r-12/70'>Part Number</div> - <div className='w-3/4'>{product.code || '-'}</div> + <div className='w-4/12 text-gray_r-12/70'>Part Number</div> + <div className='w-8/12'>{product.code || '-'}</div> </div> <div className='flex p-3'> - <div className='w-1/4 text-gray_r-12/70'>Manufacture</div> - <div className='w-3/4'> + <div className='w-4/12 text-gray_r-12/70'>Manufacture</div> + <div className='w-8/12'> {product.manufacture?.name ? ( <Link href={createSlug( @@ -169,68 +175,36 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) )} </div> </div> + <div className='flex p-3 items-center bg-gray_r-4'> - <div className='w-1/4 text-gray_r-12/70'>Persiapan Barang</div> - <div className='w-3/4'> - {product.sla ? ( - product.sla?.slaDate != '-' ? ( - <button - type='button' - title={`Masa Persiapan Barang ${product.sla?.slaDate}`} - className={`flex gap-x-1 items-center p-2 rounded-lg w-auto ${ - product.sla?.slaDate === 'indent' ? 'bg-indigo-900' : 'btn-light' - }`} - > - <div - className={`flex-1 text-caption-1 ${ - product.sla?.slaDate === 'indent' ? 'text-white' : '' - }`} - > - {product.sla?.slaDate} - </div> - <div className='flex-end'> - <svg - aria-hidden='true' - fill='none' - stroke='currentColor' - stroke-width='1.5' - className={`w-7 h-7 ${ - product.sla?.slaDate === 'indent' ? 'text-white' : '' - }`} - > - <path - d='M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z' - stroke-linecap='round' - stroke-linejoin='round' - ></path> - </svg> - </div> - </button> - ) : ( - '-' - ) - ) : ( - <Button color='gray'> - <Spinner aria-label='Alternate spinner button example' /> - <span className='pl-3'>Loading...</span> - </Button> + <div className='w-4/12 text-gray_r-12/70'>Persiapan Barang</div> + <div className='w-8/12'> + {!product?.sla && <Skeleton width='20%' height='16px' />} + {product?.sla && ( + <Tooltip + placement='top' + label={`Masa Persiapan Barang ${product?.sla?.slaDate}`} + > + <Box className='w-fit flex items-center gap-x-2'> + {product?.sla?.slaDate} + <Info size={16} /> + </Box> + </Tooltip> )} </div> </div> + <div className='flex p-3'> - <div className='w-1/4 text-gray_r-12/70'>Stock</div> - <div className='w-3/4'> - {isLoadingSLA && ( - <div className=''> - <Spinner aria-label='Center-aligned spinner example' /> - </div> - )} + <div className='w-4/12 text-gray_r-12/70'>Stock</div> + <div className='w-8/12'> + {!product?.sla && <Skeleton width='10%' height='16px' />} {product?.sla?.qty > 0 && <span>{product?.sla?.qty}</span>} {product?.sla?.qty == 0 && ( <a href={whatsappUrl('product', { name: product.name, - url: createSlug('/shop/product/variant/', product.name, product.id, true) + manufacture: product?.manufacture?.name, + url: createSlug('/shop/product/', product.name, product.id, true) })} className='text-danger-500 font-medium' > @@ -240,8 +214,8 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) </div> </div> <div className='flex p-3 bg-gray_r-4'> - <div className='w-1/4 text-gray_r-12/70'>Berat Barang</div> - <div className='w-3/4'> + <div className='w-4/12 text-gray_r-12/70'>Berat Barang</div> + <div className='w-8/12'> {product?.weight > 0 && <span>{product?.weight} KG</span>} {product?.weight == 0 && ( <a @@ -296,44 +270,52 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) </div> */} </div> <div className='w-[25%]'> - {lowestPrice?.priceDiscount > 0 ? ( + {product?.flashSale?.remainingTime > 0 ? ( <> - <div className='flex gap-x-2 mb-3 items-center'> - <div className='flex'> - <span className='text-gray-400 text-md'>Harga Sebelum PPN : </span> - </div> - <div className='flex'> - <span className=' text-body-1 '> - {currencyFormat(lowestPrice?.priceDiscount)} - </span> - </div> - </div> - <span className='font-semibold'>Termasuk PPN :</span> - <div className='flex gap-x-1 items-center mt-2 '> + <div className='flex gap-x-1 items-center mt-2'> <div className='badge-solid-red text-caption-1'> {lowestPrice?.discountPercentage}% </div> - <div className='text-gray_r-11 line-through text-caption-1'> - {currencyFormat(lowestPrice?.price * 1.11)} + <div className='text-gray_r-9 line-through text-caption-1'> + {currencyFormat(lowestPrice?.price)} + </div> + <div className='text-danger-500 font-semibold text-xl'> + {currencyFormat(lowestPrice?.priceDiscount)} </div> - <h3 className='text-danger-500 font-semibold text-title-sm'> - {currencyFormat(lowestPrice?.priceDiscount * 1.11)} - </h3> + </div> + <div className='text-gray_r-9 text-base font-normal mt-1'> + Termasuk PPN:{' '} + {currencyFormat(lowestPrice?.priceDiscount * process.env.NEXT_PUBLIC_PPN)} </div> </> ) : ( - <span className='text-gray_r-12/90 font-normal text-h-sm'> - Hubungi kami untuk dapatkan harga terbaik, - <a - href={whatsappUrl('product', { - name: product.name, - url: createSlug('/shop/product/', product.name, product.id, true) - })} - className='text-danger-500 underline' - > - klik disini - </a> - </span> + <h3 className='text-danger-500 font-semibold mt-1 text-title-md'> + {lowestPrice?.price > 0 ? ( + <> + {currencyFormat(lowestPrice?.price)} + <div className='text-gray_r-9 text-base font-normal mt-1'> + Termasuk PPN:{' '} + {currencyFormat(lowestPrice?.price * process.env.NEXT_PUBLIC_PPN)} + </div> + </> + ) : ( + <span className='text-gray_r-12/90 font-normal text-h-sm'> + Hubungi kami untuk dapatkan harga terbaik, + <a + href={whatsappUrl('product', { + name: product.name, + manufacture: product.manufacture?.name, + url: createSlug('/shop/product/', product.name, product.id, true) + })} + className='text-danger-500 underline' + rel='noopener noreferrer' + target='_blank' + > + klik disini + </a> + </span> + )} + </h3> )} <div className='flex gap-x-3 mt-4'> <input diff --git a/src/lib/product/components/Product/ProductMobile.jsx b/src/lib/product/components/Product/ProductMobile.jsx index 6b0b27a5..a9d34683 100644 --- a/src/lib/product/components/Product/ProductMobile.jsx +++ b/src/lib/product/components/Product/ProductMobile.jsx @@ -17,7 +17,6 @@ import whatsappUrl from '@/core/utils/whatsappUrl' import PromotionType from '@/lib/promotinProgram/components/PromotionType' import { gtagAddToCart } from '@/core/utils/googleTag' import odooApi from '@/core/api/odooApi' -import { Button, Spinner } from 'flowbite-react' import ImageNext from 'next/image' import CountDown2 from '@/core/components/elements/CountDown/CountDown2' @@ -101,7 +100,8 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => { price: variant.price, stock: variant.stock, weight: variant.weight, - hasProgram: variant.hasProgram + hasProgram: variant.hasProgram, + isFlashsale: variant.isFlashsale } setActiveVariant(newActiveVariant) @@ -152,6 +152,8 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => { router.push(`/shop/checkout?source=buy`) } + console.log('ini log', activeVariant) + const productSimilarQuery = [ product?.name, `fq=-product_id_i:${product.id}`, @@ -232,32 +234,48 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => { <div className='text-gray_r-12/80 text-caption-2 mt-2 mb-1'>Harga mulai dari: </div> )} - {activeVariant?.price?.discountPercentage > 0 && ( - <div className='flex gap-x-1 items-center'> - <div className='text-gray_r-11 line-through text-caption-1'> - {currencyFormat(activeVariant?.price?.price)} + {activeVariant.isFlashsale ? ( + <> + <div className='flex gap-x-1 items-center'> + <div className='badge-solid-red'>{activeVariant?.price?.discountPercentage}%</div> + <div className='text-gray_r-11 line-through text-caption-1'> + {currencyFormat(activeVariant?.price?.price)} + </div> + <div className='text-danger-500 font-semibold'> + {currencyFormat(activeVariant?.price?.priceDiscount)} + </div> </div> - <div className='badge-solid-red'>{activeVariant?.price?.discountPercentage}%</div> - </div> + <div className='text-gray_r-9 text-base font-normal mt-1'> + Termasuk PPN:{' '} + {currencyFormat(activeVariant?.price.priceDiscount * process.env.NEXT_PUBLIC_PPN)} + </div> + </> + ) : ( + <h3 className='text-danger-500 font-semibold mt-1'> + {activeVariant?.price?.priceDiscount > 0 ? ( + <> + {currencyFormat(activeVariant?.price?.priceDiscount)} + <div className='text-gray_r-9 text-base font-normal mt-1'> + Termasuk PPN:{' '} + {currencyFormat(activeVariant?.price.priceDiscount * process.env.NEXT_PUBLIC_PPN)} + </div> + </> + ) : ( + <span className='text-gray_r-11 leading-6 font-normal'> + Hubungi kami untuk dapatkan harga terbaik, + <a + href={whatsappUrl('product', { + name: product.name, + url: createSlug('/shop/product/', product.name, product.id, true) + })} + className='text-danger-500 underline' + > + klik disini + </a> + </span> + )} + </h3> )} - <h3 className='text-danger-500 font-semibold mt-1'> - {activeVariant?.price?.priceDiscount > 0 ? ( - currencyFormat(activeVariant?.price?.priceDiscount) - ) : ( - <span className='text-gray_r-11 leading-6 font-normal'> - Hubungi kami untuk dapatkan harga terbaik, - <a - href={whatsappUrl('product', { - name: product.name, - url: createSlug('/shop/product/', product.name, product.id, true) - })} - className='text-danger-500 underline' - > - klik disini - </a> - </span> - )} - </h3> </div> <Divider /> diff --git a/src/lib/product/components/Product/ProductMobileVariant.jsx b/src/lib/product/components/Product/ProductMobileVariant.jsx index e0ba90c3..a7b1a543 100644 --- a/src/lib/product/components/Product/ProductMobileVariant.jsx +++ b/src/lib/product/components/Product/ProductMobileVariant.jsx @@ -16,7 +16,7 @@ import BottomPopup from '@/core/components/elements/Popup/BottomPopup' import whatsappUrl from '@/core/utils/whatsappUrl' import { gtagAddToCart } from '@/core/utils/googleTag' import odooApi from '@/core/api/odooApi' -import { Button, Spinner } from 'flowbite-react' +import { Skeleton } from '@chakra-ui/react' const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { const router = useRouter() @@ -39,7 +39,8 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { name: product.name, price: getLowestPrice(), stock: product.stockTotal, - weight: product.weight + weight: product.weight, + isFlashSale: product.isFlashsale }) useEffect(() => { @@ -50,7 +51,8 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { name: product.name, price: product.price, stock: product.stock, - weight: product.weight + weight: product.weight, + isFlashSale: product.isFlashsale }) } }, [selectedVariant, product]) @@ -80,6 +82,7 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { }) setAddCartAlert(true) } + console.log('ini log', activeVariant) const handleClickBuy = () => { if (!validAction()) return @@ -89,7 +92,7 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { quantity, programLineId: null, selected: true, - source : 'buy' + source: 'buy' }) router.push(`/shop/checkout?source=buy`) } @@ -139,47 +142,47 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { </div> <h1 className='leading-6 font-medium mb-3'>{activeVariant?.name}</h1> - {activeVariant?.price?.priceDiscount > 0 ? ( + {activeVariant.isFlashsale ? ( <> <div className='flex gap-x-1 items-center'> - <div className='text-gray_r-11 text-caption-1'>Harga Sebelum PPN :</div> - <div className='text-gray_r-12 line-through text-caption-1'> - {' '} + <div className='badge-solid-red'>{activeVariant?.price?.discountPercentage}%</div> + <div className='text-gray_r-11 line-through text-caption-1'> + {currencyFormat(activeVariant?.price?.price)} + </div> + <div className='text-danger-500 font-semibold'> {currencyFormat(activeVariant?.price?.priceDiscount)} </div> </div> - <div className='mt-2'> - <span className='font-semibold '>Termasuk PPN :</span> - <div className='flex gap-x-2 items-center mt-2'> - {activeVariant?.price?.discountPercentage > 0 && ( - <> - <div className='badge-solid-red'> - {activeVariant?.price?.discountPercentage}% - </div> - <div className='text-gray_r-11 line-through text-caption-1'> - {currencyFormat(activeVariant?.price?.price * 1.11)} - </div> - </> - )} - <h3 className='text-danger-500 font-semibold'> - {currencyFormat(activeVariant?.price?.priceDiscount * 1.11)} - </h3> - </div> + <div className='text-gray_r-9 text-base font-normal mt-1'> + Termasuk PPN:{' '} + {currencyFormat(activeVariant?.price.priceDiscount * process.env.NEXT_PUBLIC_PPN)} </div> </> ) : ( - <span className='text-gray_r-11 leading-6 font-normal'> - Hubungi kami untuk dapatkan harga terbaik, - <a - href={whatsappUrl('product', { - name: product.name, - url: createSlug('/shop/product/', product.name, product.id, true) - })} - className='text-danger-500 underline' - > - klik disini - </a> - </span> + <h3 className='text-danger-500 font-semibold mt-1'> + {activeVariant?.price?.priceDiscount > 0 ? ( + <> + {currencyFormat(activeVariant?.price?.priceDiscount)} + <div className='text-gray_r-9 text-base font-normal mt-1'> + Termasuk PPN:{' '} + {currencyFormat(activeVariant?.price.priceDiscount * process.env.NEXT_PUBLIC_PPN)} + </div> + </> + ) : ( + <span className='text-gray_r-11 leading-6 font-normal'> + Hubungi kami untuk dapatkan harga terbaik, + <a + href={whatsappUrl('product', { + name: product.name, + url: createSlug('/shop/product/', product.name, product.id, true) + })} + className='text-danger-500 underline' + > + klik disini + </a> + </span> + )} + </h3> )} </div> @@ -230,10 +233,7 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { <SpecificationContent label='Ketersediaan'> <span> {isLoadingSLA ? ( - <Button color='gray'> - <Spinner aria-label='Alternate spinner button example' /> - <span className='pl-3'>Loading...</span> - </Button> + <Skeleton width='100px' height='full' /> ) : product?.sla?.slaDate != '-' ? ( <button type='button' @@ -267,7 +267,7 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { </svg> </div> </button> - ): ( + ) : ( '-' )} </span> diff --git a/src/lib/product/components/ProductCard.jsx b/src/lib/product/components/ProductCard.jsx index 10ffdaec..16c63c00 100644 --- a/src/lib/product/components/ProductCard.jsx +++ b/src/lib/product/components/ProductCard.jsx @@ -82,30 +82,47 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { )} <Link href={createSlug('/shop/product/', product?.name, product?.id)} - className={`mb-2 !text-gray_r-12 leading-6 block ${ + className={`mb-3 !text-gray_r-12 leading-6 block ${ simpleTitle ? 'line-clamp-2 h-12' : 'line-clamp-3 h-[64px]' }`} title={product?.name} > {product?.name} </Link> - {product?.lowestPrice.discountPercentage > 0 && ( - <div className='flex gap-x-1 mb-1 items-center'> - <div className='text-gray_r-11 line-through text-[11px] sm:text-caption-2'> - {currencyFormat(product.lowestPrice.price)} + {product?.flashSale?.id > 0 ? ( + <> + {product?.lowestPrice.discountPercentage > 0 && ( + <div className='flex gap-x-1 mb-1 items-center'> + <div className='text-gray_r-11 line-through text-[11px] sm:text-caption-2'> + {currencyFormat(product.lowestPrice.price)} + </div> + <div className='badge-solid-red'>{product?.lowestPrice.discountPercentage}%</div> + </div> + )} + + <div className='text-danger-500 font-semibold mb-2'> + {product?.lowestPrice.priceDiscount > 0 ? ( + currencyFormat(product?.lowestPrice.priceDiscount) + ) : ( + <a href={callForPriceWhatsapp}>Call for price</a> + )} </div> - <div className='badge-solid-red'>{product?.lowestPrice.discountPercentage}%</div> + </> + ) : ( + <div className='text-danger-500 font-semibold mb-2 min-h-[40px]'> + {product?.lowestPrice.price > 0 ? ( + <> + {currencyFormat(product?.lowestPrice.price)} + <div className='text-gray_r-9 text-[11px] font-normal sm:text-caption-2 mt-2'> + + PPN: {currencyFormat(product.lowestPrice.price * process.env.NEXT_PUBLIC_PPN)} + </div> + </> + ) : ( + <a href={callForPriceWhatsapp}>Call for price</a> + )} </div> )} - <div className='text-danger-500 font-semibold mb-2'> - {product?.lowestPrice.priceDiscount > 0 ? ( - currencyFormat(product?.lowestPrice.priceDiscount) - ) : ( - <a href={callForPriceWhatsapp}>Call for price</a> - )} - </div> - {product?.stockTotal > 0 && ( <div className='flex gap-x-1'> <div className='badge-solid-red'>Ready Stock</div> @@ -169,30 +186,46 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { )} <Link href={createSlug('/shop/product/', product?.name, product?.id)} - className={`mb-2 !text-gray_r-12 leading-6 ${ + className={`mb-3 !text-gray_r-12 leading-6 ${ simpleTitle ? 'line-clamp-2' : 'line-clamp-3' }`} > {product?.name} </Link> + {product?.flashSale?.id > 0 ? ( + <> + {product?.lowestPrice.discountPercentage > 0 && ( + <div className='flex gap-x-1 mb-1 items-center'> + <div className='badge-solid-red'>{product?.lowestPrice?.discountPercentage}%</div> + <div className='text-gray_r-11 line-through text-caption-2'> + {currencyFormat(product?.lowestPrice?.price)} + </div> + </div> + )} - {product?.lowestPrice?.discountPercentage > 0 && ( - <div className='flex gap-x-1 mb-1 items-center'> - <div className='badge-solid-red'>{product?.lowestPrice?.discountPercentage}%</div> - <div className='text-gray_r-11 line-through text-caption-2'> - {currencyFormat(product?.lowestPrice?.price)} + <div className='text-danger-500 font-semibold mb-2'> + {product?.lowestPrice?.priceDiscount > 0 ? ( + currencyFormat(product?.lowestPrice?.priceDiscount) + ) : ( + <a href={callForPriceWhatsapp}>Call for price</a> + )} </div> + </> + ) : ( + <div className='text-danger-500 font-semibold mb-2 min-h-[40px]'> + {product?.lowestPrice.price > 0 ? ( + <> + {currencyFormat(product?.lowestPrice.price)} + <div className='text-gray_r-9 text-[11px] sm:text-caption-2 font-normal mt-2'> + + PPN: {currencyFormat(product.lowestPrice.price * process.env.NEXT_PUBLIC_PPN)} + </div> + </> + ) : ( + <a href={callForPriceWhatsapp}>Call for price</a> + )} </div> )} - <div className='text-danger-500 font-semibold mb-2'> - {product?.lowestPrice?.priceDiscount > 0 ? ( - currencyFormat(product?.lowestPrice?.priceDiscount) - ) : ( - <a href={callForPriceWhatsapp}>Call for price</a> - )} - </div> - {product?.stockTotal > 0 && ( <div className='flex gap-x-1'> <div className='badge-solid-red'>Ready Stock</div> diff --git a/src/lib/product/components/ProductFilterDesktop.jsx b/src/lib/product/components/ProductFilterDesktop.jsx index ce6c12ed..b64349c7 100644 --- a/src/lib/product/components/ProductFilterDesktop.jsx +++ b/src/lib/product/components/ProductFilterDesktop.jsx @@ -2,7 +2,21 @@ import { useRouter } from 'next/router' import { useState } from 'react' import _ from 'lodash' import { toQuery } from 'lodash-contrib' -import { Accordion, Checkbox, Label, TextInput } from 'flowbite-react' +import { + Accordion, + AccordionButton, + AccordionIcon, + AccordionItem, + AccordionPanel, + Box, + Button, + Checkbox, + Input, + InputGroup, + InputLeftAddon, + Stack, + VStack +} from '@chakra-ui/react' const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = null }) => { const router = useRouter() @@ -13,7 +27,7 @@ const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = nu const [priceFrom, setPriceFrom] = useState(query?.priceFrom) const [priceTo, setPriceTo] = useState(query?.priceTo) - const handleCategorysChange = (event) => { + const handleCategoriesChange = (event) => { const value = event.target.value const isChecked = event.target.checked if (isChecked) { @@ -48,80 +62,95 @@ const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = nu return ( <> - <Accordion flush={true} alwaysOpen={true}> - <Accordion.Panel> - <Accordion.Title>Kategori</Accordion.Title> - <Accordion.Content className='overflow-auto max-h-[200px]'> - <div className='flex flex-col gap-4 scroll-snap' id='checkbox'> + <Accordion defaultIndex={[0]} allowMultiple> + <AccordionItem> + <AccordionButton padding={[2, 4]}> + <Box as='span' flex='1' textAlign='left' fontWeight='semibold'> + Brand + </Box> + <AccordionIcon /> + </AccordionButton> + + <AccordionPanel> + <Stack gap={3} direction='column' maxH={'240px'} overflow='auto'> + {brands.map((brand, index) => ( + <div className='flex items-center gap-2' key={index}> + <Checkbox + isChecked={brandValues.includes(brand)} + onChange={handleBrandsChange} + value={brand} + size='md' + > + {brand} + </Checkbox> + </div> + ))} + </Stack> + </AccordionPanel> + </AccordionItem> + + <AccordionItem> + <AccordionButton padding={[2, 4]}> + <Box as='span' flex='1' textAlign='left' fontWeight='semibold'> + Kategori + </Box> + <AccordionIcon /> + </AccordionButton> + + <AccordionPanel> + <Stack gap={3} direction='column' maxH={'240px'} overflow='auto'> {categories.map((category, index) => ( <div className='flex items-center gap-2' key={index}> <Checkbox - id={`categoryOption${index}`} - checked={categoryValues.includes(category)} - onChange={handleCategorysChange} + isChecked={categoryValues.includes(category)} + onChange={handleCategoriesChange} value={category} - /> - <Label htmlFor={`categoryOption${index}`} className='dark:text-gray_r-12/80'> + size='md' + > {category} - </Label> + </Checkbox> </div> ))} - </div> - </Accordion.Content> - </Accordion.Panel> - <Accordion.Panel> - {!defaultBrand && ( - <> - <Accordion.Title>Brand</Accordion.Title> - <Accordion.Content className='overflow-auto max-h-[200px]'> - <div className='flex flex-col gap-4 scroll-snap' id='checkbox'> - {brands.map((brand, index) => ( - <div className='flex items-center gap-2' key={index}> - <Checkbox - id={`brandOption${index}`} - checked={brandValues.includes(brand)} - onChange={handleBrandsChange} - value={brand} - /> - <Label htmlFor={`brandOption${index}`} className='dark:text-gray_r-12/80'> - {brand} - </Label> - </div> - ))} - </div> - </Accordion.Content> - </> - )} - </Accordion.Panel> - <Accordion.Panel> - <Accordion.Title>Harga</Accordion.Title> - <Accordion.Content> - <div className='mb-3'> - <TextInput - placeholder='Harga Minimum' - addon='Rp' - type='number' - value={priceFrom} - onChange={(e) => setPriceFrom(e.target.value)} - /> - </div> - <div className='mb-3'> - <TextInput - placeholder='Harga Maximum' - addon='Rp' - type='number' - value={priceTo} - onChange={(e) => setPriceTo(e.target.value)} - /> - </div> - </Accordion.Content> - </Accordion.Panel> + </Stack> + </AccordionPanel> + </AccordionItem> + + <AccordionItem> + <AccordionButton padding={[2, 4]}> + <Box as='span' flex='1' textAlign='left' fontWeight='semibold'> + Harga + </Box> + <AccordionIcon /> + </AccordionButton> + + <AccordionPanel paddingY={4}> + <VStack gap={4}> + <InputGroup> + <InputLeftAddon>Rp</InputLeftAddon> + <Input + type='number' + placeholder='Harga minimum' + value={priceFrom} + onChange={(e) => setPriceFrom(e.target.value)} + /> + </InputGroup> + <InputGroup> + <InputLeftAddon>Rp</InputLeftAddon> + <Input + type='number' + placeholder='Harga maximum' + value={priceTo} + onChange={(e) => setPriceTo(e.target.value)} + /> + </InputGroup> + </VStack> + </AccordionPanel> + </AccordionItem> </Accordion> - <div className='p-5'> - <button type='button' className='btn-solid-red w-full mt-6' onClick={handleSubmit}> - Terapkan - </button> - </div> + + <Button className='w-full mt-6' colorScheme='red' onClick={handleSubmit}> + Terapkan + </Button> </> ) } diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index ae9618d2..df9aa91b 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -39,9 +39,11 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => { const oddIndexSuggestions = response.data.spellcheck.suggestions.filter( (_, index) => index % 2 === 1 ) + const oddIndexCollations = response.data.spellcheck.collations.filter( (_, index) => index % 2 === 1 ) + const dataSpellings = oddIndexSuggestions.reduce((acc, curr) => { oddIndexCollations.forEach((collation) => { acc.push(collation.collationQuery) @@ -52,7 +54,9 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => { return acc }, []) - setQ(dataSpellings[0]) + if (dataSpellings.length > 0) { + setQ(dataSpellings[0]) + } setSpellings(dataSpellings) }) @@ -183,7 +187,7 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => { defaultBrand={defaultBrand} /> </div> - <div className='w-9/12 p-3'> + <div className='w-9/12 pl-6'> <h1 className='text-2xl mb-2 font-semibold'>Hasil Pencarian</h1> <div className='flex justify-between items-center mb-2'> <div className='mb-2 leading-6 text-gray_r-11'> diff --git a/src/lib/product/components/ProductSlider.jsx b/src/lib/product/components/ProductSlider.jsx index dedbd6ab..54f209cc 100644 --- a/src/lib/product/components/ProductSlider.jsx +++ b/src/lib/product/components/ProductSlider.jsx @@ -10,7 +10,7 @@ import MobileView from '@/core/components/views/MobileView' import DesktopView from '@/core/components/views/DesktopView' const bannerClassName = - 'absolute rounded-r top-0 left-0 h-full w-auto md:w-[20%] idt-transition border border-gray_r-6' + 'absolute rounded-r top-0 left-0 h-full w-auto md:w-[20%] border border-gray_r-6' const ProductSlider = ({ products, simpleTitle = false, bannerMode = false }) => { const bannerRef = useRef('') diff --git a/src/pages/_app.jsx b/src/pages/_app.jsx index 0062f7fc..afebc293 100644 --- a/src/pages/_app.jsx +++ b/src/pages/_app.jsx @@ -1,36 +1,27 @@ import '../styles/globals.css' import 'react-loading-skeleton/dist/skeleton.css' + import NextProgress from 'next-progress' import { useRouter, Router } from 'next/router' import { AnimatePresence, motion } from 'framer-motion' import { Toaster } from 'react-hot-toast' import { QueryClient, QueryClientProvider } from 'react-query' import useDevice from '@/core/hooks/useDevice' -import { createContext, useContext, useEffect, useState } from 'react' +import { useEffect, useState } from 'react' import LogoSpinner from '@/core/components/elements/Spinner/LogoSpinner' import { SessionProvider } from 'next-auth/react' -import { getAuth } from '@/core/utils/auth' import { ProductProvider } from '@/contexts/ProductContext' import { ProductCartProvider } from '@/contexts/ProductCartContext' +import { ChakraProvider } from '@chakra-ui/react' +import theme from '../../chakra.theme' const queryClient = new QueryClient() -export const AuthContext = createContext({ - authenticated: false, - setAuthenticated: (auth) => {} -}) - function MyApp({ Component, pageProps: { session, ...pageProps } }) { const router = useRouter() const { isMobile } = useDevice() const [animateLoader, setAnimateLoader] = useState(false) - const [authenticated, setAuthenticated] = useState(null) - const auth = getAuth() - - // useEffect(() => { - // setAuthenticated(auth) - // }, [auth]) useEffect(() => { const handleRouteChangeStart = () => setAnimateLoader(true) @@ -63,14 +54,13 @@ function MyApp({ Component, pageProps: { session, ...pageProps } }) { }, [isMobile]) return ( - // <AuthContext.Provider value={{authenticated, setAuthenticated}}> <SessionProvider session={session}> <AnimatePresence> {animateLoader && ( <motion.div - initial={{ opacity: 0 }} + initial={{ opacity: 0.4 }} animate={{ opacity: 1 }} - exit={{ opacity: 0 }} + exit={{ opacity: 0.4 }} transition={{ duration: 0.1 }} @@ -90,20 +80,15 @@ function MyApp({ Component, pageProps: { session, ...pageProps } }) { /> <NextProgress color='#F01C21' options={{ showSpinner: false }} /> <QueryClientProvider client={queryClient}> - <AnimatePresence - mode='popLayout' - initial={false} - onExitComplete={() => window.scrollTo(0, 0)} - > - <ProductProvider> - <ProductCartProvider> - {!animateLoader && <Component {...pageProps} key={router.asPath} />} - </ProductCartProvider> - </ProductProvider> - </AnimatePresence> + <ProductProvider> + <ProductCartProvider> + <ChakraProvider theme={theme}> + <Component {...pageProps} key={router.asPath} /> + </ChakraProvider> + </ProductCartProvider> + </ProductProvider> </QueryClientProvider> </SessionProvider> - // </AuthContext.Provider> ) } diff --git a/src/pages/api/shop/brands.js b/src/pages/api/shop/brands.js new file mode 100644 index 00000000..e93fe2c9 --- /dev/null +++ b/src/pages/api/shop/brands.js @@ -0,0 +1,44 @@ +import axios from 'axios' + +export default async function handler(req, res) { + try { + let params = '*:*' + let sort = 'sort=if(exists(sequence_i),0,1) asc,sequence_i asc, if(exists(image_s),0,1) asc ' + let rows = 2000 + + if (req.query.params) { + rows = 100 + switch (req?.query?.params) { + case 'level_s': + params = 'level_s:prioritas' + break + default: + params = `name_s:${req.query.params}` + } + } + let brands = await axios( + process.env.SOLR_HOST + + `/solr/brands/select?q=${params}&q.op=OR&indent=true&rows=${rows}&${sort}` + ) + + let dataBrands = responseMap(brands.data.response.docs) + + res.status(200).json(dataBrands) + } catch (error) { + console.error('Error fetching data from Solr:', error) + res.status(500).json({ error: 'Internal Server Error' }) + } +} + +const responseMap = (brands) => { + return brands.map((brand) => { + let brandMapping = { + id: brand.id, + name: brand.display_name_s, + logo: brand.image_s || '', + sequance: brand.sequence_i || '' + } + + return brandMapping + }) +} diff --git a/src/pages/api/shop/search.js b/src/pages/api/shop/search.js index d465d94b..7b44ef37 100644 --- a/src/pages/api/shop/search.js +++ b/src/pages/api/shop/search.js @@ -49,7 +49,8 @@ export default async function handler(req, res) { 'qf=name_s', `start=${offset}`, `rows=${limit}`, - `sort=${paramOrderBy}` + `sort=${paramOrderBy}`, + `fq=-publish_b:false` ] if (priceFrom > 0 || priceTo > 0) { @@ -103,17 +104,19 @@ const escapeSolrQuery = (query) => { const productResponseMap = (products, pricelist) => { return products.map((product) => { - let price = product.price_f || 0 + let price = product.price_tier1_v2_f || 0 let priceDiscount = product.price_discount_f || 0 let discountPercentage = product.discount_f || 0 if (pricelist) { - const pricelistDiscount = product?.[`price_${pricelist}_f`] || false - const pricelistDiscountPerc = product?.[`discount_${pricelist}_f`] || false + // const pricelistDiscount = product?.[`price_${pricelist}_f`] || false + // const pricelistDiscountPerc = product?.[`discount_${pricelist}_f`] || false - if (pricelistDiscount && pricelistDiscount > 0) priceDiscount = pricelistDiscount - if (pricelistDiscountPerc && pricelistDiscountPerc > 0) - discountPercentage = pricelistDiscountPerc + // if (pricelistDiscount && pricelistDiscount > 0) priceDiscount = pricelistDiscount + // if (pricelistDiscountPerc && pricelistDiscountPerc > 0) + // discountPercentage = pricelistDiscountPerc + + price = product?.[`price_${pricelist}_v2_f`] || 0 } if (product?.flashsale_id_i > 0) { diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 47a0a493..64f3ac10 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -31,6 +31,7 @@ const FlashSale = dynamic(() => import('@/lib/flashSale/components/FlashSale'), const BannerSection = dynamic(() => import('@/lib/home/components/BannerSection')) const CategoryHomeId = dynamic(() => import('@/lib/home/components/CategoryHomeId')) const CustomerReviews = dynamic(() => import('@/lib/review/components/CustomerReviews')) +const ServiceList = dynamic(() => import('@/lib/home/components/ServiceList')) export default function Home() { const bannerRef = useRef(null) @@ -72,6 +73,7 @@ export default function Home() { </div> <div className='my-16 flex flex-col gap-y-16'> + <ServiceList /> <PreferredBrand /> <FlashSale /> <PromotinProgram /> @@ -88,6 +90,9 @@ export default function Home() { </DelayRender> <div className='flex flex-col gap-y-12 my-6'> <DelayRender renderAfter={400}> + <ServiceList /> + </DelayRender> + <DelayRender renderAfter={400}> <PreferredBrand /> </DelayRender> <DelayRender renderAfter={600}> diff --git a/tailwind.config.js b/tailwind.config.js index 97e23d04..86e1e769 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,6 +1,6 @@ /** @type {import('tailwindcss').Config} */ module.exports = { - content: ['./node_modules/flowbite-react/**/*.js', './src/**/*.{js,ts,jsx,tsx}'], + content: ['./src/**/*.{js,ts,jsx,tsx}'], plugins: [require('flowbite/plugin')], darkMode: 'class', theme: { @@ -56,59 +56,59 @@ module.exports = { 12: '#171717' }, primary: { - 100: "#FDDACC", - 200: "#FCAE99", - 300: "#F67766", - 400: "#ED4540", - 500: "#E20613", - 600: "#C20420", - 700: "#A20329", - 800: "#83012C", - 900: "#6C012D", + 100: '#FDDACC', + 200: '#FCAE99', + 300: '#F67766', + 400: '#ED4540', + 500: '#E20613', + 600: '#C20420', + 700: '#A20329', + 800: '#83012C', + 900: '#6C012D' }, success: { - 100: "#ECFBD2", - 200: "#D4F8A6", - 300: "#B1EB77", - 400: "#8ED853", - 500: "#5EBF22", - 600: "#45A418", - 700: "#308911", - 800: "#1E6E0A", - 900: "#125B06", + 100: '#ECFBD2', + 200: '#D4F8A6', + 300: '#B1EB77', + 400: '#8ED853', + 500: '#5EBF22', + 600: '#45A418', + 700: '#308911', + 800: '#1E6E0A', + 900: '#125B06' }, info: { - 100: "#CAFDF8", - 200: "#97FBF9", - 300: "#62EDF5", - 400: "#3BD5EC", - 500: "#00B3E0", - 600: "#008BC0", - 700: "#0068A1", - 800: "#004A81", - 900: "#00356B", + 100: '#CAFDF8', + 200: '#97FBF9', + 300: '#62EDF5', + 400: '#3BD5EC', + 500: '#00B3E0', + 600: '#008BC0', + 700: '#0068A1', + 800: '#004A81', + 900: '#00356B' }, warning: { - 100: "#FEF8CD", - 200: "#FEEF9C", - 300: "#FCE26B", - 400: "#FAD646", - 500: "#F8C20A", - 600: "#D5A107", - 700: "#B28305", - 800: "#8F6503", - 900: "#775101", + 100: '#FEF8CD', + 200: '#FEEF9C', + 300: '#FCE26B', + 400: '#FAD646', + 500: '#F8C20A', + 600: '#D5A107', + 700: '#B28305', + 800: '#8F6503', + 900: '#775101' }, danger: { - 100: "#FCE0D1", - 200: "#F9BBA5", - 300: "#EF8B76", - 400: "#E05E52", - 500: "#CC2020", - 600: "#AF1724", - 700: "#921026", - 800: "#760A26", - 900: "#610625" + 100: '#FCE0D1', + 200: '#F9BBA5', + 300: '#EF8B76', + 400: '#E05E52', + 500: '#CC2020', + 600: '#AF1724', + 700: '#921026', + 800: '#760A26', + 900: '#610625' } } } |
