From f56cebf376e6e041f97acb802376b399ab4174c6 Mon Sep 17 00:00:00 2001 From: Thanh Hoang <126055913+hofang42@users.noreply.github.com> Date: Sun, 18 May 2025 22:18:42 +0700 Subject: [PATCH 1/3] [Common] Add common UI (#8) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [FLN-6][Trung][UI] add header and footer #16.05.2025 (#5) * [FLN-6][Trung][UI] add header and footer #16.05.2025 Add header and footer component * [FLN-6][Trung][UI] Update SearchBar.jsx Comment english * [FLN-6][Trung][UI] Update Header.jsx Comment english * [FLN-8][Dat][UI] Create Searchbox #16.05.2025 (#4) * [FLN-3][Duc][UI] Add UI Hover Popup And Course (#3) * [FLN-3][Duc][UI] Add UI Hover Popup And Course #16.05.2025 * [FLN-3][Duc][UI] Add UI Hover Popup And Course #16.05.2025 * [FLN-3][Duc][UI] Reverse App.js #16.05.2025 * [FLN-4][Hoang][UI] Add CustomButton Common (#7) * [FLN-4][Hoang][UI] Add CustomButton Common #16.05.2025 * [FLN-4][Hoang][UI] Update CustomButton Common #16.05.2025 * [SMS-4][Hoang][UI] Update comment #17.05.2025 * [FLN-4][Hoang][UI] Add CustomButton Common #17.05.2025 * [FLN-4][Hoang][UI] Resolve conflict #17.05.2025 * [FLN-7][Thien][UI][feat] Add input components (#6) * [FLN-7][Thien][UI] Add multiple types of input components #17.05.2025 * [FLN-7][Thien][UI] Add multiple types of input components #17.05.2025 * App.js * [Hoang] Remove .env, package-lock.json, update gitignore --------- Co-authored-by: Nguyễn Ngọc Trung Co-authored-by: Ryuseikai Co-authored-by: Nguyen Doan Trong Duc <89635693+trongducdoan25@users.noreply.github.com> Co-authored-by: Huynh Dinh Thien <136036261+Nomsociuu@users.noreply.github.com> --- .gitignore | 4 +- FrontEnd/.gitignore | 23 + FrontEnd/package.json | 24 +- FrontEnd/public/favicon.ico | Bin 3870 -> 795 bytes FrontEnd/public/icons/appStore.png | Bin 0 -> 3346 bytes FrontEnd/public/icons/bell.png | Bin 0 -> 682 bytes FrontEnd/public/icons/cart.png | Bin 0 -> 572 bytes FrontEnd/public/icons/chplay.png | Bin 0 -> 8081 bytes FrontEnd/public/icons/clock.png | Bin 0 -> 659 bytes FrontEnd/public/icons/folder.png | Bin 0 -> 479 bytes FrontEnd/public/icons/heart.png | Bin 0 -> 682 bytes FrontEnd/public/icons/play.png | Bin 0 -> 648 bytes FrontEnd/public/images/Logo.png | Bin 0 -> 3311 bytes FrontEnd/public/images/defaultImageUser.png | Bin 0 -> 14676 bytes FrontEnd/public/images/logo_black_bg.png | Bin 0 -> 3542 bytes FrontEnd/public/index.html | 4 +- FrontEnd/public/manifest.json | 5 +- FrontEnd/src/App.js | 25 +- FrontEnd/src/assets/footer/footer.css | 30 ++ FrontEnd/src/assets/header/header.css | 142 ++++++ FrontEnd/src/components/common/Card/Card.css | 469 ++++++++++++++++++ FrontEnd/src/components/common/Card/Card.js | 183 +++++++ .../src/components/common/Card/PopupCard.js | 78 +++ .../common/CustomButton/CustomButton.jsx | 61 +++ .../common/CustomButton/CustomButton.scss | 251 ++++++++++ FrontEnd/src/components/common/Input.jsx | 234 +++++++++ FrontEnd/src/components/common/input.css | 85 ++++ .../search/CategoryButton/CategoryButton.js | 32 ++ .../CategoryButton/CategoryButton.module.css | 20 + .../search/DropdownItem/DropdownItem.js | 12 + .../DropdownItem/DropdownItem.module.css | 9 + .../search/DropdownList/DropdownList.js | 0 .../DropdownList/DropdownList.module.css | 9 + .../components/common/search/Input/Input.js | 19 + .../common/search/Input/Input.module.css | 14 + .../common/search/SearchBox/SearchBox.js | 81 +++ .../search/SearchBox/SearchBox.module.css | 5 + .../common/search/SearchInput/SearchInput.js | 52 ++ .../search/SearchInput/SearchInput.module.css | 37 ++ .../src/components/footer/DownloadApp.jsx | 36 ++ FrontEnd/src/components/footer/Footer.jsx | 33 ++ FrontEnd/src/components/footer/LogoLeft.jsx | 37 ++ FrontEnd/src/components/footer/QuickLink.jsx | 41 ++ .../src/components/footer/QuickLinkMobile.jsx | 65 +++ FrontEnd/src/components/header/Browse.jsx | 24 + FrontEnd/src/components/header/Header.jsx | 61 +++ .../src/components/header/HeaderRight.jsx | 54 ++ FrontEnd/src/components/header/LogoHeader.jsx | 13 + .../src/components/header/MobileHeader.jsx | 73 +++ .../src/components/header/NavigationBar.jsx | 44 ++ FrontEnd/src/components/header/SearchBar.jsx | 20 + .../components/sumaryCourse/SumaryHeader.jsx | 53 ++ FrontEnd/src/index.js | 7 +- FrontEnd/src/routes/TestInputComponent.jsx | 80 +++ package.json | 0 55 files changed, 2525 insertions(+), 24 deletions(-) create mode 100644 FrontEnd/.gitignore create mode 100644 FrontEnd/public/icons/appStore.png create mode 100644 FrontEnd/public/icons/bell.png create mode 100644 FrontEnd/public/icons/cart.png create mode 100644 FrontEnd/public/icons/chplay.png create mode 100644 FrontEnd/public/icons/clock.png create mode 100644 FrontEnd/public/icons/folder.png create mode 100644 FrontEnd/public/icons/heart.png create mode 100644 FrontEnd/public/icons/play.png create mode 100644 FrontEnd/public/images/Logo.png create mode 100644 FrontEnd/public/images/defaultImageUser.png create mode 100644 FrontEnd/public/images/logo_black_bg.png create mode 100644 FrontEnd/src/assets/footer/footer.css create mode 100644 FrontEnd/src/assets/header/header.css create mode 100644 FrontEnd/src/components/common/Card/Card.css create mode 100644 FrontEnd/src/components/common/Card/Card.js create mode 100644 FrontEnd/src/components/common/Card/PopupCard.js create mode 100644 FrontEnd/src/components/common/CustomButton/CustomButton.jsx create mode 100644 FrontEnd/src/components/common/CustomButton/CustomButton.scss create mode 100644 FrontEnd/src/components/common/Input.jsx create mode 100644 FrontEnd/src/components/common/input.css create mode 100644 FrontEnd/src/components/common/search/CategoryButton/CategoryButton.js create mode 100644 FrontEnd/src/components/common/search/CategoryButton/CategoryButton.module.css create mode 100644 FrontEnd/src/components/common/search/DropdownItem/DropdownItem.js create mode 100644 FrontEnd/src/components/common/search/DropdownItem/DropdownItem.module.css rename BackEnd/.env => FrontEnd/src/components/common/search/DropdownList/DropdownList.js (100%) create mode 100644 FrontEnd/src/components/common/search/DropdownList/DropdownList.module.css create mode 100644 FrontEnd/src/components/common/search/Input/Input.js create mode 100644 FrontEnd/src/components/common/search/Input/Input.module.css create mode 100644 FrontEnd/src/components/common/search/SearchBox/SearchBox.js create mode 100644 FrontEnd/src/components/common/search/SearchBox/SearchBox.module.css create mode 100644 FrontEnd/src/components/common/search/SearchInput/SearchInput.js create mode 100644 FrontEnd/src/components/common/search/SearchInput/SearchInput.module.css create mode 100644 FrontEnd/src/components/footer/DownloadApp.jsx create mode 100644 FrontEnd/src/components/footer/Footer.jsx create mode 100644 FrontEnd/src/components/footer/LogoLeft.jsx create mode 100644 FrontEnd/src/components/footer/QuickLink.jsx create mode 100644 FrontEnd/src/components/footer/QuickLinkMobile.jsx create mode 100644 FrontEnd/src/components/header/Browse.jsx create mode 100644 FrontEnd/src/components/header/Header.jsx create mode 100644 FrontEnd/src/components/header/HeaderRight.jsx create mode 100644 FrontEnd/src/components/header/LogoHeader.jsx create mode 100644 FrontEnd/src/components/header/MobileHeader.jsx create mode 100644 FrontEnd/src/components/header/NavigationBar.jsx create mode 100644 FrontEnd/src/components/header/SearchBar.jsx create mode 100644 FrontEnd/src/components/sumaryCourse/SumaryHeader.jsx create mode 100644 FrontEnd/src/routes/TestInputComponent.jsx create mode 100644 package.json diff --git a/.gitignore b/.gitignore index 4d29575..f1fd6c5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,9 @@ # dependencies /node_modules -/.pnp +/Frontend/node_modules +/Backend/node_modules +/Backend/.env .pnp.js # testing diff --git a/FrontEnd/.gitignore b/FrontEnd/.gitignore new file mode 100644 index 0000000..4d29575 --- /dev/null +++ b/FrontEnd/.gitignore @@ -0,0 +1,23 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/FrontEnd/package.json b/FrontEnd/package.json index d8bfe50..1d28763 100644 --- a/FrontEnd/package.json +++ b/FrontEnd/package.json @@ -3,13 +3,23 @@ "version": "0.1.0", "private": true, "dependencies": { + "@fortawesome/fontawesome-free": "^6.7.2", + "@fortawesome/fontawesome-svg-core": "^6.7.2", + "@fortawesome/free-brands-svg-icons": "^6.7.2", + "@fortawesome/free-regular-svg-icons": "^6.7.2", + "@fortawesome/free-solid-svg-icons": "^6.7.2", + "@fortawesome/react-fontawesome": "^0.2.2", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.3.0", "@testing-library/user-event": "^13.5.0", + "bootstrap": "^5.3.6", + "bootstrap-icons": "^1.13.1", "react": "^19.1.0", "react-dom": "^19.1.0", + "react-router-dom": "^7.6.0", "react-scripts": "5.0.1", + "styled-components": "^6.1.18", "web-vitals": "^2.1.4" }, "scripts": { @@ -35,5 +45,17 @@ "last 1 firefox version", "last 1 safari version" ] - } + }, + + "devDependencies": { + "css-loader": "^7.1.2", + "postcss-loader": "^8.1.1", + "resolve-url-loader": "^5.0.0", + "sass": "^1.89.0", + "sass-loader": "^16.0.5" + }, + "main": "index.js", + "author": "", + "license": "ISC", + "description": "" } diff --git a/FrontEnd/public/favicon.ico b/FrontEnd/public/favicon.ico index a11777cc471a4344702741ab1c8a588998b1311a..6fba6d139823a9cdf15431d249038add83d755f4 100644 GIT binary patch literal 795 zcmeAS@N?(olHy`uVBq!ia0vp^PC)Fy!3-p4It5+?QjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`(*k@#T!Hle1cU#nrvKB-peV%z#04UtcnX-229_;w_@80%A0i7>oNf+M z4-`o=2MI#7Lo@=V;37bFvawQHunEv6rIH}OUu6K%suZg82s= z3i|8MpEuZFu>Qh?fQ5@XTY#!L3p^r=85sBugD~Uq{1qt-3`_!^E{-7)?r*2XmNyyj zw0SdLRJ_)?ga7%RfB)y-$yCVoxExegR`#@7)$^Ca+1m|4{C}5o#eTZr^>WoZ?X!!u zx2(*%uwHR?8Vf_p;mwkZ7*@aS3)ji`-r{}xWn!39*Iwol_R9}l?Uq<<+wtsY0`s#c z3ddzQ7{9PJ%T2l{lid>dyz$s(#S9j{4N@_Bj2~;)Ff~m5-!3>?z~PIYoRUeq#KLAX z7m?O8JqD*)CgloAD6YMrwn%W!k;;SCb6z~2F|};E!xXLH22E|pIlfaac?d_#p10!H z2tBfkr7N|w^G)iOs|uRZvpn)lwN9K;u+vWns;HznSiXdrIkm;*0{4& uDePhRcy{sX6#Ko0GPee84*V7Vi}CzkrS+$8-Pi$4FbtlqelF{r5}E*Gh+vWc literal 3870 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 baj7?x%VD!5Cxk2YbYLNVeiXvvpMCWYo=by@ diff --git a/FrontEnd/public/icons/appStore.png b/FrontEnd/public/icons/appStore.png new file mode 100644 index 0000000000000000000000000000000000000000..9cc5c41d01d731490eed9267ce5d2bec509ef4ce GIT binary patch literal 3346 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 R=7@W87(Ou7tJHNy{Ral=)N}v< literal 0 HcmV?d00001 diff --git a/FrontEnd/public/icons/bell.png b/FrontEnd/public/icons/bell.png new file mode 100644 index 0000000000000000000000000000000000000000..7eda544977c81585513f6253b6437906ac3aeb92 GIT binary patch literal 682 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCikD0(?STfwX{vf|P=?w1T>ff|`ti3K*%%g4n9k3aSzc3P3gxNhoN@ff(v= zDIix)L0ti)Kvhmb1;|xUP=#=TB0wYqRSYx=q*p;f10o`=paE8(Cas_XG>zG{FBRwx zosuBGU5nJ&p)u?yu*2g2LTE1*B4wc ztCW}w)W=!i5n0T@z;_sg8IR|$NCA4h+|$J|#KZgU)Z1lE1_BJ%xvZiD9j|0{Uln`# z_W%F&>UX$KJH=O9`CED4@bxfL`ak95-7BA${d1|FeKN=IXj0|+#kFaxe-*kLTrNCX z^-zx6eB$$?vx`n-Oj=uAyXp4y|KHl5Oc#7D+QOe(EF-&-Pr zAC{zc^2=-yv1Hgcja75b*5V}w*UxQat75f`Ny`@VuDG^NrFChUQjuZ$gBv%u#yxc1 zEhHbeRe0isbs;WB99x719ac+Or`%>j#>OTaL|DzU`FV884vKEO<;f@hHcRi?y$=f4 z)~Rhv(tL93>Yhkxn=NW#6A$jbXJ)D5wROi={@9eMHw)feHL1Acb!Xvgv)LIRc1-

+V|=9aFYq(((z{TDR0)=iTMM+tua6&0eV=_VHIupEtT) zQp*gQ+>H;|FafbthM*9 RKQLYxJYD@<);T3K0RVg@`oRDI literal 0 HcmV?d00001 diff --git a/FrontEnd/public/icons/cart.png b/FrontEnd/public/icons/cart.png new file mode 100644 index 0000000000000000000000000000000000000000..fd27b67e9d5c5aa70c60dbb2e0c01cba6bc1c199 GIT binary patch literal 572 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 literal 0 HcmV?d00001 diff --git a/FrontEnd/public/icons/clock.png b/FrontEnd/public/icons/clock.png new file mode 100644 index 0000000000000000000000000000000000000000..c993e38dc59f0f5eb1065e10c3cb6f89c97d553f GIT binary patch literal 659 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU3?z3ec*FxK#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;y0X`wFK>B;T!mlpr-`z6*8x;QZ$o}b-|Jw&bzj|f=_R0Yn|N7+r^vVD3 zll#*z`=?*wcfZ2lUJ&}<4?=%>6@GUs`~tE;<^W}7fVzJ7%Khn;{RNcj1uBsH4pi1B z2Q=pwP`n4omItZn0U0QITd*DI2SeR+dLoMy#Mx((vulpv%*%^A9>`MJ$Gro@TNZ# zA1pYYI;$sT^+hR-u$2ajyl2OS&t6^?yms!Y;NzRNa+|H?FR%W+d*-5RtDBx>JUgT7 zQ2OiAg(FuOWRE>hj{I>-mhn^lG=~-G4e8%x>QZkq=_@{1w5s8{z>OwXo|YRz8q?l1 zZWr(f+{;|aVb^ee#-t?fIZh4{$9E9)G)h&Ti9B2lhNFmsJB`DZxiH?&iyl^g^NR0eNO76;@-C#d8bc4VezRg{>eG+ zBi~NVo!(Ko(Yiia(V1sKQ0`2>PaSeql7g1R`YuG`p^IBN{tOIUn=(o+rFurxyk-#_WLh?yPsve-etF8^SAGR a80PH}J+OG?Lt9`ZFnGH9xvX!lvI6-b0X`wFK>B}z!T%JK|7m9bQ%yl6gaH)HumG`vQb0z!IfwyNfUE|>h6tvZ z{x5IP zFi;(5fk$L90|OtB&3Bmbc>anMpx_%%7sn6_|F@G*^EE37xE{RL{b=#p%USaO|Ig>u zIMbkbx8(Y~sVC=h1pbzZ%sltbooq!aHklb=&ETiI{u&3BJd;Q7sXV8&Txr;t|+ z4^n0ndxos_{l^mO8S*zZiR1dB83r|;Yw{LyH}>qz-F^1xu_dJpt6Nt*&r4NlaGAf7 zkG*o^#ORq-GdD08cb8xDSaU8h@jAbHR#UFI+)8t1?r!%5C5MwXiDzH9mE-SImc(ka zxw2vM+>FN`tu1bL9?+caZc!=f9qO`4yc$(1igKz}oMy85}Sb4q9e0Nakq@c;k- literal 0 HcmV?d00001 diff --git a/FrontEnd/public/icons/heart.png b/FrontEnd/public/icons/heart.png new file mode 100644 index 0000000000000000000000000000000000000000..936041601b3df1a928d7d84678827e51316ce4f2 GIT binary patch literal 682 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCilu1AIbUfwX{vg0zCVjDngh49O^{N-L;JC@9D%sK|oZvI^>Q3hD|98VU;9 zKoKC4P|%PAsaFP*Y6=PpK1hf} zRrIDz+UV@m{{R0zIme#VWRAPf*R4@M>2YXVkoiB?l5+n8PZF()MTNQ)X89*XTw&}J z`uWjts~>|2x2B&>{s_PT@DFba)nbN zkxgNH*1sbO;_2T%XoWJazHoH!f#W-imM$)LmQgCQPWaJQ!G0@<;gIh-L$l0UNY0K e_U*BXe+>6kMP)uk8E69Igu&C*&t;ucLK6Up*!^+< literal 0 HcmV?d00001 diff --git a/FrontEnd/public/icons/play.png b/FrontEnd/public/icons/play.png new file mode 100644 index 0000000000000000000000000000000000000000..71d797df9f17f375e030e471a786c76b03a3450f GIT binary patch literal 648 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU3?z3ec*FxK#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6-P0X`wFKsq4cd#Km15TD-x0sq5%|AhGi(O)16_5Bs%2V#Wz{|oc`6YBRn z0w^2sCnDf?NWkB)fWHv||3d@*garH!4fquXRO$CS6r}49m_EFUN`m}?859g01OnE-|DRBQ|Nemq2>}lE4GIYk1`Q4G z6A~6QY}miwp+8`Qfr9@uhD4wq&H|6fVg?4j!ywFfJby(B(4(oIE{-7<{%1o1tD6;g zmN1{*s&(zwt+RQnbFaVs|Nn690tcqN^|x&ui{cb41s};LepOi-l4;VYbxn$|YOm*H z!7S^|YEy1cF>nqui=CZz-E3J|$jl<0Z`%^Y`N}PBy%%%QJ^#VF#QTixg4-rHUiWA+ z);?0~p3L^cQd{Bj<`<2V=B4x7OxA5=j61Q->E-mU=|NJ?Q*4;m*ZplP5*2dlC||%a zn_FN~@+D!`m_u%h`LexJ7KQWFtz-~>r0iuUBz*d-!81@~uEm-WLSfy>X zynDvmMp<<$<+GDqo=usy@Ajp-AYTIav6uq zQ$C5S9Y20r{eIDG;r%|7_fOV!OmYZa>NijEAWLj`yL?^ik)N^#DYJs~E$siB-)%6u zcSOhhV8`X(n-0v@ZN50?>G7K>%t-*G44$rjF6*2UngA9s6mkFn literal 0 HcmV?d00001 diff --git a/FrontEnd/public/images/Logo.png b/FrontEnd/public/images/Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f24724acaa0c1222fee3f93b2f5d1a5390551266 GIT binary patch literal 3311 zcmX9=c{~*VA70|?DA!8FvV&dgh{zq*ZaH?XW!-J|e-$8U|y_hk6S4 z0cdsoyj~Ao*n+K1Pr=Ii5KGVvhc}*#hrue+4*qfFgr41|nA;jdILk$q<)Ojy)Z8nm z_tM&{zsTS9FXE%ag33!%0ze}GIRtC@M5iR!T|=%JVlcG-ux$a^Kqm0tv-~EHKc1_XfJF?`_{x zYaiU(>E8^Hgyp3TyauPqyyI; zmCXpT2c!k8tUBW#l?S>8s8Y()XLH}X;NC~W11~ocfB-SDERi*x7!o^5;L(eW6G^0R+cj7>xhT-pST+xySXjpc-?<^+6uPMpd|j&1bT>aNGXt$Tc< z679`7NmiaMWo`5z%X=!-Rc8u5Dgc$ImAc#BwOS#xhkbevHw))=zjg4@th=eXAd&XG z_-mLtlb&>BD-s zen<6^27%#AbnqE6s=%0poK30FNO_?3;2+|$W=Mv_f6IiYiB?)2*;)^HiK5P;BcnNP zra>0Tm0gDZCq=+BtA2=%>)Jl+ZEJg&p8p`YTv6lpNAS<@^tLlKBL&97vcYbd_j&?dW=_szY(86ylZcsDn!}hRS0o$oZ&fdemwx6TV&;x9Oqhuo2)kboPloF| zXXm}B%KC7AD*17*1uaX~w)0iON7baqWQYC$^`v$w@@&(Ixx20jR3T-%V~d}A>0%1B z=_mYy^AY*I7S><3k8oT@Qwv_iSv)>{Nkc}d@TV6E7`$wCx~=|2`{;;A;McF8ehu)2 zY9Lb#~ z#2vwaMR_{Y1IjD3Ol;weox!j`ZMep;H5k+v64_OIKDfk@;K#tE@Kw$SdTfJPo2kCK zq`@+k;fwfZeHeuW`P3QBrG}x*Je_Orr4?q*cRVP0r`?;*(%deU0Txa@H@OXSRE_cl9DeF&F|^wDU&*v z=CKihj(U`XOWXWC#3)@MMA7uMF;W->cl}hPOME1VXgclIrlu&kXQAH$=d?zXRvT9PeCnT6zVh4mOv?JUnQ}m9T^IjN;)a6pFX(bJxX5 zgPYIuB$BV#zC@W;_D$cek-vs;fR}diAXaGATx{4!xz-0oaIaA3LdLVY(9zOLcXD6Ful)jl{rGPGopB1b6({H)uO0X`0DhrL zYo3;r!9g3Ad=ZqpcuIgo+%~HIQLlckgYiYt!^)C$QfX%l^9nrSPh3t@Y_199<5O8a zY?XU}t5Edr@*_ihpcyzmu~3o8j#4nSoAE1iVSrdWHV5MGXJfPJMS^-`ypBt5sBCk^ zY5L%wDn&9WuE9xHS%Em~GyQ@_QV$_UtoN;$Ss`Xd{gT@b4y4TFrh&(x6Y)9@X0 z&2aR_Z~?3UY#Q*pM_n7F`A1ncg5kjh|=kELpo%l%Bp9>|N z*s+beP{~ai6f+g3%^Stz9FpcTCeP{DmkB?0D|u9-DJFTb92YzLyfn1Ntq!B@*&oXjy#kL^tcTqUBA)tRi&yN3i{wp|)x1JcpjkMon5opZoek*tqr+`wdW@$hoo(d ze`^T2egD05qKc(Qy3OFRrEfK1y8geA6IXst)LlPNk!9-~MC>ko`Y*^t!iZZ~L#|ul z38#}hbG`_mX2aoCg-l}vpYn%PG&n3B$#6yJZ6Lr*vl4JMZ6f!qv zf)56ji=xPJu9-Je`nG!wW1TIxb#hR|-SO`3ZZpZ_rW`~XY>-bcoLY5Na>}{f0E-_) zsXmwKYN~8my{1hb3p@$l0(@m2^*G61g&Pq2ndGmYZ@gs)bnfj^C$5~FYFSRAFnfbE zDMtH&B`#eJ7}PCdhLAwroz7j&w%Z~5IBQL&wUwHdu|hQym(@Uwq~d_n}v!=Q$< vGAXm8n_IN&EwcftqvXlNk2oOU6qD-}L2dU+mx3Sk!wDlATNss{a*6vtJ~`AD literal 0 HcmV?d00001 diff --git a/FrontEnd/public/images/defaultImageUser.png b/FrontEnd/public/images/defaultImageUser.png new file mode 100644 index 0000000000000000000000000000000000000000..69cf8638f92252ab1391e62bd1332a662f4b0769 GIT binary patch literal 14676 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 literal 0 HcmV?d00001 diff --git a/FrontEnd/public/images/logo_black_bg.png b/FrontEnd/public/images/logo_black_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..048834b4f20fee4be598434eaa72248f1c9f0cc6 GIT binary patch literal 3542 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 CRvE(p literal 0 HcmV?d00001 diff --git a/FrontEnd/public/index.html b/FrontEnd/public/index.html index aa069f2..cabbc4d 100644 --- a/FrontEnd/public/index.html +++ b/FrontEnd/public/index.html @@ -7,7 +7,7 @@ - React App + Flearning diff --git a/FrontEnd/public/manifest.json b/FrontEnd/public/manifest.json index 080d6c7..558dc67 100644 --- a/FrontEnd/public/manifest.json +++ b/FrontEnd/public/manifest.json @@ -1,6 +1,7 @@ { - "short_name": "React App", - "name": "Create React App Sample", + "short_name": "Flearning", + "name": "Flearning", + "description": "A platform for learning and sharing knowledge.", "icons": [ { "src": "favicon.ico", diff --git a/FrontEnd/src/App.js b/FrontEnd/src/App.js index 3784575..59b96e2 100644 --- a/FrontEnd/src/App.js +++ b/FrontEnd/src/App.js @@ -1,25 +1,16 @@ import logo from './logo.svg'; import './App.css'; - +import Header from './components/header/Header'; +import SumaryHeader from './components/sumaryCourse/SumaryHeader'; +import Footer from './components/footer/Footer'; function App() { return ( -

-
- logo -

- Edit src/App.js and save to reload. -

-
- Learn React - -
+
+
+ +
); } -export default App; +export default App; \ No newline at end of file diff --git a/FrontEnd/src/assets/footer/footer.css b/FrontEnd/src/assets/footer/footer.css new file mode 100644 index 0000000..2e42414 --- /dev/null +++ b/FrontEnd/src/assets/footer/footer.css @@ -0,0 +1,30 @@ +.social-icon{ + background-color: rgb(68, 66, 66) !important; + transition: all 0.3s ease-in-out !important; +} +.social-icon:hover{ + background-color: #FF6F32 !important; +} +.footer-link{ + text-decoration: none !important; +} +.list-links li{ + margin-bottom: 10px; +} +@media screen and (min-width: 768px) { + + .mobile-view{ + display: none; + } + .desktop-view{ + display: block; + } +} +@media screen and (max-width: 768px) { + .mobile-view{ + display: block; + } + .desktop-view{ + display: none; + } +} \ No newline at end of file diff --git a/FrontEnd/src/assets/header/header.css b/FrontEnd/src/assets/header/header.css new file mode 100644 index 0000000..e9a5568 --- /dev/null +++ b/FrontEnd/src/assets/header/header.css @@ -0,0 +1,142 @@ +.nav--link { + padding: 10px 20px !important; +} + +.nav--link.active { + border-top: 3px solid #FF6F32; +} + +.nav--link:not(.active) { + padding-top: 13px !important; +} + +.logo { + width: 100%; +} + +.navbar--brand { + width: 14%; +} + +.dropdown-1 { + margin-left: 3%; +} + +.dropdown-1 button { + border-radius: 0px; + color: #565353; +} + +/* for SearchBar */ +.search-btn { + background-color: unset; + border: none; + position: absolute; + left: 3%; + top: 30%; +} +.search-input:focus { + box-shadow: none !important; + border-color: #FF6F32 !important; +} +/* for HeaderRight */ +.icon{ + width: 20px; + height: 20px; +} +.icon-btn{ + width: 45px; + height: 45px; +} +.create-account-btn{ + background-color: #FFEEE8; + border: none; + color: #FF6F32; + font-weight: 500; +} +.sign-in-btn{ + background-color: #FF6F32; + border: none; + color: white; + font-weight: 500; +} +.fade{ + box-shadow: 0px 0px 6px #7c736f; +} +.dropdown-item-hover:hover{ + background-color: #FFEEE8!important; + color: #FF6F32!important; + transition: 0.4s ease; +} + +/* sumary header */ +.summary-header{ + background-color: #f7f5f4f9; + padding: 15px 0px; +} +.mini-icon{ + width: 20px; + height: 20px; +} +.review-course-btn{ + background-color: white; + border: none; + color: #FF6F32; + font-weight: 500; +} +/* end sumary header */ +/* For mobile navbar */ +.offcanvas-menu{ + width: 80%; + background-color: #5f5e5ee9 !important; +} +.nav-mobile-link{ + padding: 10px 20px !important; + border-radius: 5px; +} +.nav-mobile-link.active{ + background-color: #FF6F32; +} +/* end */ + +@media screen and (max-width: 768px) { + .mobile-item-view{ + width: 300%; + } + .desktop-item-view{ + display: none; + } +} +@media screen and (min-width: 768px) { + .mobile-item-view{ + display: none; + } + .desktop-item-view{ + display: block; + } +} +@media screen and (min-width: 1024px) { + .tablet-view-nav{ + display: none; + } + .desktop-view-nav{ + display: block; + } + .search-input{ + border-radius: 0px; + } +} +@media screen and (max-width: 1024px) { + .tablet-view-nav{ + display: block; + } + .desktop-view-nav{ + display: none; + } + .navbar--brand { + width: 25%; + } + .search-input{ + border-radius: 20px !important; + } +} \ No newline at end of file diff --git a/FrontEnd/src/components/common/Card/Card.css b/FrontEnd/src/components/common/Card/Card.css new file mode 100644 index 0000000..9646d2d --- /dev/null +++ b/FrontEnd/src/components/common/Card/Card.css @@ -0,0 +1,469 @@ +/* Card Styles */ +.orange-gradient { + background: linear-gradient(90deg, #ff7a00 0%, #ff9a00 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.card-container { + width: 312px; + min-height: 388px; + height: auto; + background: #fff; + border-radius: 16px; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08); + overflow: hidden; + display: flex; + flex-direction: column; + transition: transform 0.3s ease, box-shadow 0.3s ease; +} + +.card-container:hover { + transform: translateY(-4px); + box-shadow: 0 12px 40px rgba(0, 0, 0, 0.12); +} + +.card-image { + width: 100%; + height: 234px; + background-size: cover; + background-position: center; + position: relative; + overflow: hidden; +} + +.card-image::after { + content: ""; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 40%; + background: linear-gradient(transparent, rgba(0, 0, 0, 0.1)); +} + +.divider { + width: 100%; + height: 1px; + background: linear-gradient( + 90deg, + transparent 0%, + rgba(255, 122, 0, 0.3) 50%, + transparent 100% + ); +} + +.card-body { + flex: 1; + display: flex; + flex-direction: column; + padding: 16px 20px; +} + +.row { + display: flex; + align-items: center; + justify-content: space-between; + margin-top: 8px; +} + +.category { + display: inline-block; + background: linear-gradient(90deg, #fff4e6 0%, #ffe7d7 100%); + color: #ff7a00; + font-size: 12px; + font-weight: 600; + border-radius: 16px; + padding: 4px 12px; + letter-spacing: 0.5px; + box-shadow: 0 2px 4px rgba(255, 122, 0, 0.1); +} + +.price { + color: #ff7a00; + font-size: 22px; + font-weight: 700; + text-shadow: 0 2px 4px rgba(255, 122, 0, 0.1); +} + +.title { + font-size: 18px; + font-weight: 700; + color: #1d2026; + margin: 16px 0; + line-height: 1.4; + text-align: left; + /* Remove text truncation */ + display: block; + overflow: visible; + white-space: normal; + /* Note: line-clamp is only supported with -webkit prefix currently. + The standard property is still in draft specification. */ + line-clamp: initial; + -webkit-line-clamp: initial; + -webkit-box-orient: initial; + transition: color 0.2s ease; +} + +.card-container:hover .title { + color: #ff7a00; +} + +.footer { + display: flex; + align-items: center; + justify-content: space-between; /* This will push items to opposite sides */ + gap: 24px; + margin-top: auto; + padding: 16px 0 8px 0; + border-top: 1px dashed rgba(123, 123, 123, 0.2); +} + +.rating { + display: flex; + align-items: center; + font-size: 16px; + color: #ffb400; + font-weight: 600; + gap: 4px; +} + +.students { + display: flex; + align-items: center; + font-size: 16px; + color: #7b7b7b; + font-weight: 500; + gap: 4px; + margin-left: auto; /* This will push it to the right */ +} + +/* Detailed Card Styles */ +.detailed-card-container { + width: 400px; + background: #fff; + border-radius: 20px; + box-shadow: 0 12px 48px rgba(0, 0, 0, 0.12); + overflow: hidden; + display: flex; + flex-direction: column; + transition: transform 0.3s ease; +} + +.detailed-card-container:hover { + transform: translateY(-4px); +} + +.detailed-card-image { + width: 100%; + height: 240px; + background-size: cover; + background-position: center; + position: relative; +} + +.detailed-card-image::before { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient( + 135deg, + rgba(255, 122, 0, 0.1) 0%, + rgba(255, 122, 0, 0) 100% + ); +} + +.detailed-card-body { + display: flex; + flex-direction: column; + padding: 24px; + text-align: left; +} + +.detailed-title { + font-size: 22px; + font-weight: 700; + color: #1d2026; + margin: 0 0 16px 0; + line-height: 1.3; + position: relative; + padding-bottom: 12px; +} + +.detailed-title::after { + content: ""; + position: absolute; + bottom: 0; + left: 0; + width: 48px; + height: 3px; + background: linear-gradient(90deg, #ff7a00 0%, #ff9a00 100%); + border-radius: 3px; +} + +.author-row { + display: flex; + align-items: center; + margin-bottom: 20px; + justify-content: space-between; + width: 100%; +} + +.author-info { + display: flex; + align-items: center; + gap: 12px; +} + +.author-avatar { + width: 36px; + height: 36px; + border-radius: 50%; + background-size: cover; + background-position: center; + border: 2px solid #fff4e6; + box-shadow: 0 2px 8px rgba(255, 122, 0, 0.1); +} + +.author-name { + display: flex; + flex-direction: column; + font-size: 14px; + color: #6e7a8a; +} + +.author-name strong { + color: #1d2026; + font-weight: 600; +} + +.rating-info { + display: flex; + align-items: center; + gap: 4px; + color: #ffb400; + font-size: 14px; + font-weight: 600; + margin-left: auto; +} + +.rating-info span span { + margin-left: 2px; +} + +.stats-row { + display: flex; + align-items: center; + gap: 24px; + margin-bottom: 20px; +} + +.stat-item { + display: flex; + align-items: center; + gap: 8px; + font-size: 14px; + color: #6e7a8a; +} + +.stat-item svg { + width: 16px; + height: 16px; +} + +/* Icon color changes */ +/* Student icon (blue) */ +.stats-row .stat-item:nth-child(1) svg path { + stroke: #3b82f6; +} + +.stats-row .stat-item:nth-child(1) svg circle { + stroke: #3b82f6; +} + +/* Level icon (red) */ +.stats-row .stat-item:nth-child(2) svg path { + stroke: #ef4444; +} + +/* Clock icon (green) */ +.stats-row .stat-item:nth-child(3) svg path { + stroke: #22c55e; +} + +.stats-row .stat-item:nth-child(3) svg circle { + stroke: #22c55e; +} + +.price-row { + display: flex; + align-items: center; + gap: 16px; + margin-bottom: 24px; + padding: 12px 0; + border-top: 1px dashed rgba(110, 122, 138, 0.2); + border-bottom: 1px dashed rgba(110, 122, 138, 0.2); +} + +.current-price { + color: #ff7a00; + font-size: 28px; + font-weight: 700; +} + +.old-price { + color: #6e7a8a; + font-size: 16px; + text-decoration: line-through; +} + +.discount { + background: linear-gradient(90deg, #ffe7d7 0%, #fff4e6 100%); + color: #ff7a00; + padding: 4px 12px; + border-radius: 20px; + font-size: 14px; + font-weight: 700; + box-shadow: 0 2px 4px rgba(255, 122, 0, 0.1); +} + +.learn-list { + padding-left: 0; + margin: 16px 0 24px 0; + list-style: none; +} + +.learn-item { + font-size: 14px; + color: #6e7a8a; + margin-bottom: 12px; + line-height: 1.4; + position: relative; + padding-left: 20px; + display: flex; + align-items: flex-start; +} + +.learn-item::before { + display: none; +} + +.learn-item::after { + content: ""; + position: absolute; + left: 0; + top: 5px; + width: 8px; + height: 5px; + border: solid #22c55e; + border-width: 0 0 2px 2px; + transform: rotate(-45deg); +} + +.button { + width: 100%; + padding: 14px; + background: linear-gradient(90deg, #ff7a00 0%, #ff9a00 100%); + color: white; + border: none; + border-radius: 12px; + font-size: 16px; + font-weight: 600; + margin-top: 8px; + cursor: pointer; + transition: all 0.3s ease; + box-shadow: 0 4px 12px rgba(255, 122, 0, 0.3); +} + +.button:hover { + transform: translateY(-2px); + box-shadow: 0 6px 16px rgba(255, 122, 0, 0.4); +} + +.button:active { + transform: translateY(0); +} + +.detail-button { + width: 100%; + padding: 14px; + background: white; + color: #ff7a00; + border: 1px solid #ff7a00; + border-radius: 12px; + font-size: 16px; + font-weight: 600; + margin-top: 12px; + cursor: pointer; + transition: all 0.3s ease; +} + +.detail-button:hover { + background: rgba(255, 122, 0, 0.05); +} + +/* PopupCard Styles */ +.card-wrapper { + position: relative; + width: 312px; + height: 388px; + display: inline-block; +} + +.popup-wrapper { + position: absolute; + left: calc(100% + 8px); + top: 0; + transform: translateY(0); + z-index: 1000; + transition: all 0.2s cubic-bezier(0.2, 0, 0.1, 1); + filter: drop-shadow(0 8px 30px rgba(0, 0, 0, 0.15)); +} + +.popup-wrapper.visible { + opacity: 1; + pointer-events: auto; + transform: translateY(0) translateX(0); +} + +.popup-wrapper.hidden { + opacity: 0; + pointer-events: none; + transform: translateY(0) translateX(-10px); +} + +.popup-wrapper::before { + content: ""; + position: absolute; + right: 100%; + top: 0; + width: 12px; + height: 100%; +} + +.pointer { + position: absolute; + left: -8px; + top: 50%; + transform: translateY(-50%); + width: 0; + height: 0; + border-top: 8px solid transparent; + border-bottom: 8px solid transparent; + border-right: 8px solid white; + z-index: 1001; + filter: drop-shadow(-2px 0 2px rgba(0, 0, 0, 0.05)); +} + +.detailed-title + div { + margin-top: 24px; + font-size: 14px; + font-weight: 600; + color: #1d2026; + text-transform: uppercase; + letter-spacing: 0.5px; +} diff --git a/FrontEnd/src/components/common/Card/Card.js b/FrontEnd/src/components/common/Card/Card.js new file mode 100644 index 0000000..f574413 --- /dev/null +++ b/FrontEnd/src/components/common/Card/Card.js @@ -0,0 +1,183 @@ +import React from "react"; +import "./Card.css"; + +// SVG Components +export const StarIcon = () => ( + + + +); + +export const UserIcon = () => ( + + + + + + +); + +export const ClockIcon = () => ( + + + + +); + +export const LevelIcon = () => ( + + + + + +); + +const Card = ({ image, category, price, title, rating, students }) => ( +
+
+
+
+
+
{category}
+
+ {price} +
+
+
{title}
+
+
+ + {rating} +
+
+ + {students} +
+
+
+
+); + +export const DetailedCard = ({ + title, + author, + authorAvatar, + rating, + ratingCount, + students, + level, + duration, + price, + oldPrice, + discount, + learnList, +}) => ( +
+
+

{title}

+ +
+
+
+
+ Course by + {author} +
+
+
+ + {rating} + ({ratingCount}) +
+
+ +
+
+ + {students} students +
+ +
+ + {level} +
+ +
+ + {duration} +
+
+ +
+
+ {price} +
+
{oldPrice}
+
{discount}
+
+ +
+
+ What you'll learn +
+
    + {learnList.map((item, index) => ( +
  • + {item} +
  • + ))} +
+
+ + + +
+
+); + +export default Card; diff --git a/FrontEnd/src/components/common/Card/PopupCard.js b/FrontEnd/src/components/common/Card/PopupCard.js new file mode 100644 index 0000000..7faf2a2 --- /dev/null +++ b/FrontEnd/src/components/common/Card/PopupCard.js @@ -0,0 +1,78 @@ +import React, { useState, useRef, useEffect } from "react"; +import Card, { DetailedCard } from "./Card"; +import "./Card.css"; + +const PopupCard = ({ cardProps, detailedProps, hoverDelay = 200 }) => { + const [showPopup, setShowPopup] = useState(false); + const timerRef = useRef(null); + const wrapperRef = useRef(null); + const cardRef = useRef(null); + + const handleMouseEnter = () => { + timerRef.current = setTimeout(() => { + setShowPopup(true); + }, hoverDelay); + }; + + const handleMouseLeave = (e) => { + // Check if we're moving to the popup or its children + const relatedTarget = e.relatedTarget; + if ( + !relatedTarget || + !(relatedTarget instanceof Node) || + !wrapperRef.current || + !cardRef.current + ) { + clearTimer(); + setShowPopup(false); + return; + } + + const isMovingToPopup = + wrapperRef.current.contains(relatedTarget) || + relatedTarget === wrapperRef.current; + + const isMovingToCard = + cardRef.current.contains(relatedTarget) || + relatedTarget === cardRef.current; + + if (!isMovingToPopup && !isMovingToCard) { + clearTimer(); + setShowPopup(false); + } + }; + + const clearTimer = () => { + if (timerRef.current) { + clearTimeout(timerRef.current); + timerRef.current = null; + } + }; + + useEffect(() => { + return () => { + clearTimer(); + }; + }, []); + + return ( +
+
+ +
+
+ +
+ ); +}; + +export default PopupCard; diff --git a/FrontEnd/src/components/common/CustomButton/CustomButton.jsx b/FrontEnd/src/components/common/CustomButton/CustomButton.jsx new file mode 100644 index 0000000..2f8a0e9 --- /dev/null +++ b/FrontEnd/src/components/common/CustomButton/CustomButton.jsx @@ -0,0 +1,61 @@ +import React from "react"; +import PropTypes from "prop-types"; +import "./CustomButton.scss"; + +const CustomButton = ({ + size = "medium", //small, medium, large + color = "primary", // primary, secondary, success,gray, error, warning + disabled = false, // true, false + iconUrl = null, // URL of the icon + iconPosition = "left", // left, right + filter = false, // true, false + filterCount = 0, // number of items in the filter + type = "normal", // normal, underline, square, circle + isTransparent = false, // true, false + onClick = () => {}, + children, +}) => { + const className = `btn ${size} ${color} ${filter ? "filter" : ""} ${type} ${ + isTransparent ? "transparent" : "" + }`; + + return ( + + ); +}; + +CustomButton.propTypes = { + size: PropTypes.oneOf(["small", "medium", "large"]), + color: PropTypes.string, + disabled: PropTypes.bool, + iconUrl: PropTypes.string, + iconPosition: PropTypes.oneOf(["left", "right"]), + filter: PropTypes.bool, + filterCount: PropTypes.number, + type: PropTypes.oneOf(["normal", "underline", "square", "circle"]), + isTransparent: PropTypes.bool, + onClick: PropTypes.func, + children: PropTypes.node, +}; + +export default CustomButton; diff --git a/FrontEnd/src/components/common/CustomButton/CustomButton.scss b/FrontEnd/src/components/common/CustomButton/CustomButton.scss new file mode 100644 index 0000000..8907e3e --- /dev/null +++ b/FrontEnd/src/components/common/CustomButton/CustomButton.scss @@ -0,0 +1,251 @@ +@use "sass:color"; + +.btn { + display: inline-flex; + align-items: center; + justify-content: center; + font-weight: 500; + border: none; + border-radius: 2px; + padding: 0.5rem 1rem; + cursor: pointer; + transition: background-color 0.3s, opacity 0.3s; + position: relative; + + &.filter { + backdrop-filter: blur(5px); + border: 1.5px solid #ff6636; + background-color: white; + color: #ff6636; + font-weight: 600; + } + + &.large { + font-size: 1.125rem; + padding: 0.75rem 1.5rem; + } + + &.medium { + font-size: 1rem; + padding: 0.5rem 1rem; + } + + &.small { + font-size: 0.875rem; + padding: 0.25rem 0.75rem; + } + + // Color Variants + &.primary { + --underline-color: #ff6636; + --main-color-rgb: 255, 102, 54; + background-color: #ff6636; + color: white; + + &:hover:not(:disabled) { + background-color: color.adjust(#ff6636, $lightness: -10%); + } + } + + &.secondary { + --underline-color: #564ffd; + --main-color-rgb: 86, 79, 253; + background-color: #564ffd; + color: white; + + &:hover:not(:disabled) { + background-color: color.adjust(#564ffd, $lightness: -10%); + } + } + + &.grey { + --underline-color: #1d2026; + --main-color-rgb: 29, 32, 38; + background-color: #1d2026; + color: white; + + &:hover:not(:disabled) { + background-color: #363b47; + } + } + + &.success { + --underline-color: #23bd33; + --main-color-rgb: 35, 189, 51; + background-color: #23bd33; + color: white; + + &:hover:not(:disabled) { + background-color: color.adjust(#23bd33, $lightness: -10%); + } + } + + &.warning { + --underline-color: #fd8e1f; + --main-color-rgb: 253, 142, 31; + background-color: #fd8e1f; + color: white; + + &:hover:not(:disabled) { + background-color: color.adjust(#fd8e1f, $lightness: -10%); + } + } + + &.error { + --underline-color: #e34444; + --main-color-rgb: 227, 68, 68; + background-color: #e34444; + color: white; + + &:hover:not(:disabled) { + background-color: color.adjust(#e34444, $lightness: -10%); + } + } + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + } + + .btn-text { + display: inline-block; + } + + .icon { + width: 18px; + height: 18px; + object-fit: contain; + color: inherit; + + &.left { + margin-right: 0.5rem; + } + + &.right { + margin-left: 0.5rem; + } + + &.only-icon { + margin: 0; + } + } + + .filter-badge { + background-color: #ff6636; + color: white; + font-size: 0.75rem; + font-weight: bold; + border-radius: 4px; + padding: 2px 6px; + margin-left: 8px; + } + + &.underline { + background-color: transparent; + border: none; + color: var(--underline-color, #ff6636); + padding: 0.5rem; + position: relative; + + &:hover { + background-color: transparent !important; + } + + .btn-content { + display: inline-flex; + align-items: center; + position: relative; + + &::after { + content: ""; + position: absolute; + bottom: -2px; + left: 0; + width: 100%; + height: 2px; + background-color: var(--underline-color, #ff6636); + transform: scaleX(0); + transform-origin: left; + transition: transform 0.3s ease; + } + } + + &:hover .btn-content::after { + transform: scaleX(1); + } + } + + &.transparent { + background-color: transparent; + color: var(--underline-color, #ff6636); + border: none; + + &:hover:not(:disabled) { + background-color: rgba(var(--main-color-rgb, 255, 102, 54), 0.15); + } + + .icon { + filter: none; + color: inherit; + + .btn:hover .only-icon { + filter: brightness(0) invert(1); + } + } + + &.underline { + .btn-content::after { + background-color: var(--underline-color, #ff6636); + } + + &:hover { + background-color: transparent !important; + } + } + } + + // Square and circle - transparent version with transparent text & icon + &.square.transparent, + &.circle.transparent { + background-color: rgba(var(--main-color-rgb, 255, 102, 54), 0); + color: transparent; + box-shadow: none; + padding: 0.5rem; + + .icon.only-icon { + width: 16px; + height: 16px; + filter: none; + color: transparent; + } + + &:hover:not(:disabled) { + background-color: rgba(var(--main-color-rgb, 255, 102, 54), 0.3); + } + } + + // Square and circle - solid version + &.square:not(.transparent), + &.circle:not(.transparent) { + background-color: rgba(var(--main-color-rgb), 0.2); + color: white; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); + padding: 0.5rem; + } + + &.square { + border-radius: 4px; + } + + &.circle { + border-radius: 50%; + } + + // Fix: Properly nest hover icon invert filter + &:not(.transparent):not(.underline):hover { + .icon.only-icon { + filter: brightness(0) invert(1); + transition: filter 0.3s ease; + } + } +} diff --git a/FrontEnd/src/components/common/Input.jsx b/FrontEnd/src/components/common/Input.jsx new file mode 100644 index 0000000..73a5740 --- /dev/null +++ b/FrontEnd/src/components/common/Input.jsx @@ -0,0 +1,234 @@ +import React, { useState, useRef, useEffect } from "react"; +import "bootstrap/dist/css/bootstrap.min.css"; +import "./input.css"; + +const Input = ({ + text = "Input", + variant, + icon, + counter, + maxCount, + rightIcon, + price, + currency, + placeholder, + options, + success, + error, + type = "text", + textarea, + value, + onChange, + className, + ...props +}) => { + const [selectedText, setSelectedText] = useState(text); + const [showDropdown, setShowDropdown] = useState(false); + const dropdownRef = useRef(null); + + useEffect(() => { + const handleClickOutside = (e) => { + if (dropdownRef.current && !dropdownRef.current.contains(e.target)) { + setShowDropdown(false); + } + }; + document.addEventListener("mousedown", handleClickOutside); + return () => document.removeEventListener("mousedown", handleClickOutside); + }, []); + + const handleSelect = (option) => { + setSelectedText(option); + setShowDropdown(false); + }; + + const renderInput = () => { + if (textarea) { + return ( +