diff --git a/et --hard HEAD@{2} b/et --hard HEAD@{2} new file mode 100644 index 0000000000000000000000000000000000000000..080506ee11eb7b72adccd7694b14aa7fc112bc78 --- /dev/null +++ b/et --hard HEAD@{2} @@ -0,0 +1,485 @@ +[33m6234e68[m[33m ([m[1;36mHEAD -> [m[1;32missue/271.1-create-new-backend-routes-connection[m[33m)[m HEAD@{0}: rebase (continue) (finish): returning to refs/heads/issue/271.1-create-new-backend-routes-connection +[33m6234e68[m[33m ([m[1;36mHEAD -> [m[1;32missue/271.1-create-new-backend-routes-connection[m[33m)[m HEAD@{1}: rebase (continue): rebase +[33m347541c[m HEAD@{2}: rebase (continue): rebase +[33m97779d6[m HEAD@{3}: rebase (continue): ok +[33m05dace3[m HEAD@{4}: rebase (continue) (pick): ok +[33me3b8b31[m HEAD@{5}: rebase (continue) (pick): Issue #287: UPDATE mecred statistics on about page +[33m5e83680[m HEAD@{6}: rebase (continue): Issue #289: ADD Icons on profile page (verified) +[33mcda5c94[m HEAD@{7}: rebase (continue) (pick): Issue #290: FIX Style of the share profile button +[33md893a7a[m HEAD@{8}: rebase (continue) (pick): Issue #291: User card: update information +[33m8d8c38b[m HEAD@{9}: rebase (continue): Issue #288: UPDATE change order icons sidebar +[33m82b17e3[m HEAD@{10}: rebase (pick): Issue #280: FIX remove profile icon offline +[33md70485c[m HEAD@{11}: rebase (pick): FIX Correction of the random color vector and other details, plus removal of statistics +[33mc48bb0a[m HEAD@{12}: rebase (pick): Issue #282: FIX profile edition on HC +[33m0685262[m[33m ([m[1;31morigin/issue/271.gus[m[33m, [m[1;32missue/271.gus[m[33m)[m HEAD@{13}: rebase (start): checkout issue/271.gus +[33mae8f559[m HEAD@{14}: checkout: moving from issue/271.gus to issue/271.1-create-new-backend-routes-connection +[33m0685262[m[33m ([m[1;31morigin/issue/271.gus[m[33m, [m[1;32missue/271.gus[m[33m)[m HEAD@{15}: checkout: moving from issue/271.1-create-new-backend-routes-connection to issue/271.gus +[33mae8f559[m HEAD@{16}: rebase (finish): returning to refs/heads/issue/271.1-create-new-backend-routes-connection +[33mae8f559[m HEAD@{17}: rebase (pick): rebase +[33mc09911e[m HEAD@{18}: rebase (pick): rebase +[33m6a29086[m HEAD@{19}: rebase (pick): ok +[33m9535dd5[m HEAD@{20}: rebase (pick): ok +[33mc2308b4[m HEAD@{21}: rebase (pick): Issue #287: UPDATE mecred statistics on about page +[33mb624b7b[m HEAD@{22}: rebase (pick): Issue #289: ADD Icons on profile page (verified) +[33m22ea969[m HEAD@{23}: rebase (pick): Issue #290: FIX Style of the share profile button +[33m87445ec[m HEAD@{24}: rebase (pick): Issue #291: User card: update information +[33mf9c42e9[m HEAD@{25}: rebase (pick): Issue #288: UPDATE change order icons sidebar +[33m5d6caf1[m HEAD@{26}: rebase (pick): Issue #280: FIX remove profile icon offline +[33mfa46ddd[m HEAD@{27}: rebase (pick): FIX Correction of the random color vector and other details, plus removal of statistics +[33me5f98f1[m HEAD@{28}: rebase (pick): Issue #282: FIX profile edition on HC +[33m9d10585[m[33m ([m[1;31morigin/issue/271.3-update-routes-new-backend[m[33m, [m[1;32missue/271.3-update-routes-new-backend[m[33m)[m HEAD@{29}: rebase (start): checkout issue/271.3-update-routes-new-backend +[33m1f909f1[m[33m ([m[1;31morigin/issue/271.1-create-new-backend-routes-connection[m[33m)[m HEAD@{30}: checkout: moving from issue/271.3-update-routes-new-backend to issue/271.1-create-new-backend-routes-connection +[33m9d10585[m[33m ([m[1;31morigin/issue/271.3-update-routes-new-backend[m[33m, [m[1;32missue/271.3-update-routes-new-backend[m[33m)[m HEAD@{31}: checkout: moving from issue/271.1-create-new-backend-routes-connection to issue/271.3-update-routes-new-backend +[33m1f909f1[m[33m ([m[1;31morigin/issue/271.1-create-new-backend-routes-connection[m[33m)[m HEAD@{32}: rebase (continue) (finish): returning to refs/heads/issue/271.1-create-new-backend-routes-connection +[33m1f909f1[m[33m ([m[1;31morigin/issue/271.1-create-new-backend-routes-connection[m[33m)[m HEAD@{33}: rebase (continue): rebase +[33mf8f0b33[m HEAD@{34}: rebase (continue) (pick): ADD persistent login +[33ma5ec1e3[m HEAD@{35}: rebase (continue): rebase +[33m4d8dd6c[m HEAD@{36}: rebase (pick): ok +[33mfca864c[m HEAD@{37}: rebase (pick): ADD zustand and new backend login +[33mb4f38f6[m[33m ([m[1;32mdevelop[m[33m)[m HEAD@{38}: rebase (start): checkout develop +[33m70c1272[m HEAD@{39}: checkout: moving from develop to issue/271.1-create-new-backend-routes-connection +[33mb4f38f6[m[33m ([m[1;32mdevelop[m[33m)[m HEAD@{40}: pull (finish): returning to refs/heads/develop +[33mb4f38f6[m[33m ([m[1;32mdevelop[m[33m)[m HEAD@{41}: pull (pick): ok +[33mf2ca3ec[m HEAD@{42}: pull (start): checkout f2ca3ec0437aca4415077207441905f7ad0ea0ff +[33m1e76287[m HEAD@{43}: checkout: moving from issue/271.1-create-new-backend-routes-connection to develop +[33m70c1272[m HEAD@{44}: pull (finish): returning to refs/heads/issue/271.1-create-new-backend-routes-connection +[33m70c1272[m HEAD@{45}: pull (pick): rebase +[33m13fde09[m HEAD@{46}: pull (pick): ADD persistent login +[33m47b021e[m HEAD@{47}: pull (start): checkout 47b021ee3e0538d8f8015c7b7a05ebfb761396ae +[33m8b6eff8[m HEAD@{48}: commit: rebase +[33mea6b9e7[m HEAD@{49}: rebase (finish): returning to refs/heads/issue/271.1-create-new-backend-routes-connection +[33mea6b9e7[m HEAD@{50}: rebase (pick): rebase +[33m021900e[m HEAD@{51}: rebase (pick): ok +[33m9d10585[m[33m ([m[1;31morigin/issue/271.3-update-routes-new-backend[m[33m, [m[1;32missue/271.3-update-routes-new-backend[m[33m)[m HEAD@{52}: rebase (start): checkout issue/271.3-update-routes-new-backend +[33m47b021e[m HEAD@{53}: checkout: moving from issue/271.3-update-routes-new-backend to issue/271.1-create-new-backend-routes-connection +[33m9d10585[m[33m ([m[1;31morigin/issue/271.3-update-routes-new-backend[m[33m, [m[1;32missue/271.3-update-routes-new-backend[m[33m)[m HEAD@{54}: pull: Fast-forward +[33md6ffb7b[m HEAD@{55}: checkout: moving from issue/271.1-create-new-backend-routes-connection to issue/271.3-update-routes-new-backend +[33m47b021e[m HEAD@{56}: commit: rebase +[33mc682d43[m HEAD@{57}: rebase (finish): returning to refs/heads/issue/271.1-create-new-backend-routes-connection +[33mc682d43[m HEAD@{58}: rebase (fixup): ok +[33m826a265[m HEAD@{59}: rebase (fixup): # This is a combination of 2 commits. +[33m411e37c[m HEAD@{60}: rebase (pick): ok +[33md6ffb7b[m HEAD@{61}: rebase (start): checkout issue/271.3-update-routes-new-backend +[33m05a1946[m HEAD@{62}: checkout: moving from issue/271.3-update-routes-new-backend to issue/271.1-create-new-backend-routes-connection +[33md6ffb7b[m HEAD@{63}: checkout: moving from issue/271.1-create-new-backend-routes-connection to issue/271.3-update-routes-new-backend +[33m05a1946[m HEAD@{64}: commit: ok +[33mdcfed71[m HEAD@{65}: rebase (finish): returning to refs/heads/issue/271.1-create-new-backend-routes-connection +[33mdcfed71[m HEAD@{66}: rebase (pick): routes-created-and-fixed +[33m1e76287[m HEAD@{67}: rebase (start): checkout develop +[33mb7fc31a[m HEAD@{68}: checkout: moving from develop to issue/271.1-create-new-backend-routes-connection +[33m1e76287[m HEAD@{69}: pull (finish): returning to refs/heads/develop +[33m1e76287[m HEAD@{70}: pull (pick): ok +[33m8823613[m HEAD@{71}: pull (start): checkout 882361329901314da9a514860097eec5c34fdcc7 +[33m4a496bd[m HEAD@{72}: checkout: moving from issue/271.1-create-new-backend-routes-connection to develop +[33mb7fc31a[m HEAD@{73}: commit: routes-created-and-fixed +[33m4a496bd[m HEAD@{74}: Branch: renamed refs/heads/issue/271.1-create-new-backend-routes-conection to refs/heads/issue/271.1-create-new-backend-routes-connection +[33m4a496bd[m HEAD@{76}: Branch: renamed refs/heads/issue/271.1-create-new-backend-routes-coneciton to refs/heads/issue/271.1-create-new-backend-routes-conection +[33m4a496bd[m HEAD@{78}: Branch: renamed refs/heads/issue/271.1-update-collection-routes to refs/heads/issue/271.1-create-new-backend-routes-coneciton +[33m4a496bd[m HEAD@{80}: Branch: renamed refs/heads/Issue/271.1 to refs/heads/issue/271.1-update-collection-routes +[33m4a496bd[m HEAD@{82}: checkout: moving from develop to Issue/271.1 +[33m4a496bd[m HEAD@{83}: rebase (continue) (finish): returning to refs/heads/develop +[33m4a496bd[m HEAD@{84}: rebase (continue): ok +[33mffa3940[m HEAD@{85}: pull (start): checkout ffa39400246a243d9f43f8d9071e4037b75e48af +[33m7d9f13f[m HEAD@{86}: rebase (continue) (finish): returning to refs/heads/develop +[33m7d9f13f[m HEAD@{87}: rebase (continue) (finish): refs/heads/develop onto ffa39400246a243d9f43f8d9071e4037b75e48af +[33m7d9f13f[m HEAD@{88}: checkout: moving from ffa39400246a243d9f43f8d9071e4037b75e48af to develop +[33mffa3940[m HEAD@{89}: pull (start): checkout ffa39400246a243d9f43f8d9071e4037b75e48af +[33m7d9f13f[m HEAD@{90}: checkout: moving from develop to develop +[33m7d9f13f[m HEAD@{91}: checkout: moving from arrumar to develop +[33meec953e[m[33m ([m[1;31morigin/arrumar[m[33m, [m[1;32marrumar[m[33m)[m HEAD@{92}: rebase (finish): returning to refs/heads/arrumar +[33meec953e[m[33m ([m[1;31morigin/arrumar[m[33m, [m[1;32marrumar[m[33m)[m HEAD@{93}: rebase (reword): Alteração feita +[33m591a2f3[m HEAD@{94}: rebase: fast-forward +[33m7d9f13f[m HEAD@{95}: rebase (start): checkout develop +[33m591a2f3[m HEAD@{96}: checkout: moving from develop to arrumar +[33m7d9f13f[m HEAD@{97}: checkout: moving from arrumar to develop +[33m591a2f3[m HEAD@{98}: commit: ok +[33m7d9f13f[m HEAD@{99}: checkout: moving from develop to arrumar +[33m7d9f13f[m HEAD@{100}: commit: ok +[33mb2ca474[m HEAD@{101}: pull: Fast-forward +[33mba98771[m HEAD@{102}: checkout: moving from issue/250-change-about-page to develop +[33m5c1abb3[m[33m ([m[1;31morigin/issue/250-change-about-page[m[33m, [m[1;32missue/250-change-about-page[m[33m)[m HEAD@{103}: rebase (finish): returning to refs/heads/issue/250-change-about-page +[33m5c1abb3[m[33m ([m[1;31morigin/issue/250-change-about-page[m[33m, [m[1;32missue/250-change-about-page[m[33m)[m HEAD@{104}: rebase (fixup): Issue #250/FIX-About-page +[33m0a72404[m HEAD@{105}: rebase (fixup): # This is a combination of 4 commits. +[33m51f2869[m HEAD@{106}: rebase (fixup): # This is a combination of 3 commits. +[33m09f1e1e[m HEAD@{107}: rebase (fixup): # This is a combination of 2 commits. +[33mbca4771[m HEAD@{108}: rebase (reword): Issue #250/FIX-About-page +[33mbc34395[m HEAD@{109}: rebase (reword): Issue #245/Credits-screen +[33mba98771[m HEAD@{110}: rebase (start): checkout develop +[33macaa2cf[m HEAD@{111}: checkout: moving from develop to issue/250-change-about-page +[33mba98771[m HEAD@{112}: checkout: moving from issue/250-change-about-page to develop +[33macaa2cf[m HEAD@{113}: commit: Done +[33m21d386b[m HEAD@{114}: checkout: moving from develop to issue/250-change-about-page +[33mba98771[m HEAD@{115}: checkout: moving from issue-247/update-header-text to develop +[33m9a5c0bd[m[33m ([m[1;31morigin/issue-247/update-header-text[m[33m, [m[1;32missue-247/update-header-text[m[33m)[m HEAD@{116}: rebase (finish): returning to refs/heads/issue-247/update-header-text +[33m9a5c0bd[m[33m ([m[1;31morigin/issue-247/update-header-text[m[33m, [m[1;32missue-247/update-header-text[m[33m)[m HEAD@{117}: rebase (pick): Issue #247: CHANGED header in mobile version +[33m5dfb808[m HEAD@{118}: rebase (pick): Issue #248: ADD Stats gamification +[33m7469b4e[m HEAD@{119}: rebase (pick): Issue #245/Credits-screen +[33mba98771[m HEAD@{120}: rebase (start): checkout develop +[33m2d4a62a[m HEAD@{121}: checkout: moving from develop to issue-247/update-header-text +[33mba98771[m HEAD@{122}: checkout: moving from fix to develop +[33m61220db[m[33m ([m[1;31morigin/fix[m[33m, [m[1;32mfix[m[33m)[m HEAD@{123}: rebase (finish): returning to refs/heads/fix +[33m61220db[m[33m ([m[1;31morigin/fix[m[33m, [m[1;32mfix[m[33m)[m HEAD@{124}: rebase (fixup): Issue #245/Credits-screen +[33m2091574[m HEAD@{125}: rebase (fixup): # This is a combination of 3 commits. +[33m2cc544c[m HEAD@{126}: rebase (fixup): # This is a combination of 2 commits. +[33m6837f38[m HEAD@{127}: rebase (pick): Issue #245/Credits-screen +[33mba98771[m HEAD@{128}: rebase (start): checkout develop +[33mf0702ca[m HEAD@{129}: rebase (abort): updating HEAD +[33m16d357c[m HEAD@{130}: rebase (pick): Issue #247: CHANGED header in mobile version +[33mc33ddee[m HEAD@{131}: rebase (pick): Issue #248: ADD Stats gamification +[33m500f180[m HEAD@{132}: rebase (pick): Issue #245/Credits-screen +[33mba98771[m HEAD@{133}: rebase (start): checkout develop +[33mf0702ca[m HEAD@{134}: checkout: moving from develop to fix +[33mba98771[m HEAD@{135}: pull (finish): returning to refs/heads/develop +[33mba98771[m HEAD@{136}: pull (start): checkout ba98771b62ede2cef14224f8bfb5a63f4d01d88b +[33m5d4bb5c[m HEAD@{137}: checkout: moving from fix to develop +[33mf0702ca[m HEAD@{138}: commit: HOTFIX: Commit history on dev + api ref +[33m5d4bb5c[m HEAD@{139}: checkout: moving from develop to fix +[33m5d4bb5c[m HEAD@{140}: checkout: moving from issue/250-change-about-page to develop +[33m21d386b[m HEAD@{141}: checkout: moving from develop to issue/250-change-about-page +[33m5d4bb5c[m HEAD@{142}: checkout: moving from issue/250-change-about-page to develop +[33m21d386b[m HEAD@{143}: commit: Issue #250: FIX About page +[33m5d4bb5c[m HEAD@{144}: checkout: moving from develop to issue/250-change-about-page +[33m5d4bb5c[m HEAD@{145}: checkout: moving from issue/250-change-about-page to develop +[33m5d4bb5c[m HEAD@{146}: checkout: moving from develop to issue/250-change-about-page +[33m5d4bb5c[m HEAD@{147}: pull: Fast-forward +[33mcfb4aab[m HEAD@{148}: checkout: moving from issue-247/update-header-text to develop +[33m2d4a62a[m HEAD@{149}: rebase (finish): returning to refs/heads/issue-247/update-header-text +[33m2d4a62a[m HEAD@{150}: rebase (fixup): Issue #247: CHANGED header in mobile version +[33m6391f47[m HEAD@{151}: rebase (pick): Issue #247: CHANGED header in mobile version +[33mcfb4aab[m HEAD@{152}: rebase (start): checkout develop +[33m1085e0e[m HEAD@{153}: checkout: moving from develop to issue-247/update-header-text +[33mcfb4aab[m HEAD@{154}: pull: Fast-forward +[33m131951b[m HEAD@{155}: checkout: moving from issue-247/update-header-text to develop +[33m1085e0e[m HEAD@{156}: commit: done +[33mb2d65e7[m HEAD@{157}: rebase (continue) (finish): returning to refs/heads/issue-247/update-header-text +[33mb2d65e7[m HEAD@{158}: rebase (continue) (fixup): Issue #247: CHANGED header in mobile version +[33me284390[m HEAD@{159}: rebase (continue): Issue #247: CHANGED header in mobile version +[33m131951b[m HEAD@{160}: rebase (start): checkout develop +[33m37fd1d3[m HEAD@{161}: checkout: moving from develop to issue-247/update-header-text +[33m131951b[m HEAD@{162}: pull: Fast-forward +[33m9170068[m HEAD@{163}: checkout: moving from issue-247/update-header-text to develop +[33m37fd1d3[m HEAD@{164}: checkout: moving from develop to issue-247/update-header-text +[33m9170068[m HEAD@{165}: checkout: moving from issue/245-credits-screen to develop +[33m427ebc3[m[33m ([m[1;31morigin/issue/245-credits-screen[m[33m, [m[1;32missue/245-credits-screen[m[33m)[m HEAD@{166}: rebase (finish): returning to refs/heads/issue/245-credits-screen +[33m427ebc3[m[33m ([m[1;31morigin/issue/245-credits-screen[m[33m, [m[1;32missue/245-credits-screen[m[33m)[m HEAD@{167}: rebase (fixup): Issue #245/Credits-screen +[33m3a5125b[m HEAD@{168}: rebase (fixup): # This is a combination of 2 commits. +[33m3610a07[m HEAD@{169}: rebase (reword): Issue #245/Credits-screen +[33m6b5d22e[m HEAD@{170}: rebase (reword): para nao perder +[33m9170068[m HEAD@{171}: rebase (start): checkout develop +[33m0e2d735[m HEAD@{172}: checkout: moving from develop to issue/245-credits-screen +[33m9170068[m HEAD@{173}: pull: Fast-forward +[33mb204e06[m HEAD@{174}: checkout: moving from issue/245-credits-screen to develop +[33m0e2d735[m HEAD@{175}: commit: done +[33m6eb0220[m HEAD@{176}: commit: responsive ok +[33m41c0687[m HEAD@{177}: commit: para nao perder +[33mb204e06[m HEAD@{178}: checkout: moving from develop to issue/245-credits-screen +[33mb204e06[m HEAD@{179}: pull: Fast-forward +[33m176ac2d[m HEAD@{180}: checkout: moving from issue/239-cards-divorce to develop +[33m96f81ab[m[33m ([m[1;31morigin/issue/239-cards-divorce[m[33m, [m[1;32missue/239-cards-divorce[m[33m)[m HEAD@{181}: rebase (finish): returning to refs/heads/issue/239-cards-divorce +[33m96f81ab[m[33m ([m[1;31morigin/issue/239-cards-divorce[m[33m, [m[1;32missue/239-cards-divorce[m[33m)[m HEAD@{182}: rebase (fixup): preciso rebasear +[33m5505157[m HEAD@{183}: rebase (start): checkout develop +[33mcf0671f[m HEAD@{184}: checkout: moving from develop to issue/239-cards-divorce +[33m176ac2d[m HEAD@{185}: checkout: moving from issue/239-cards-divorce to develop +[33mcf0671f[m HEAD@{186}: rebase (continue) (finish): returning to refs/heads/issue/239-cards-divorce +[33mcf0671f[m HEAD@{187}: rebase (continue): rebase +[33m5505157[m HEAD@{188}: rebase (continue): preciso rebasear +[33m176ac2d[m HEAD@{189}: rebase (start): checkout develop +[33meb4aee5[m HEAD@{190}: checkout: moving from develop to issue/239-cards-divorce +[33m176ac2d[m HEAD@{191}: pull: Fast-forward +[33m3b90816[m HEAD@{192}: checkout: moving from issue/239-cards-divorce to develop +[33meb4aee5[m HEAD@{193}: reset: moving to HEAD +[33meb4aee5[m HEAD@{194}: rebase (finish): returning to refs/heads/issue/239-cards-divorce +[33meb4aee5[m HEAD@{195}: rebase (start): checkout develop +[33meb4aee5[m HEAD@{196}: checkout: moving from develop to issue/239-cards-divorce +[33m3b90816[m HEAD@{197}: checkout: moving from issue/239-cards-divorce to develop +[33meb4aee5[m HEAD@{198}: commit: rebase +[33m464536b[m HEAD@{199}: rebase (continue) (finish): returning to refs/heads/issue/239-cards-divorce +[33m464536b[m HEAD@{200}: rebase (continue): preciso rebasear +[33m3b90816[m HEAD@{201}: rebase (start): checkout develop +[33m92b94ba[m HEAD@{202}: checkout: moving from develop to issue/239-cards-divorce +[33m3b90816[m HEAD@{203}: pull: Fast-forward +[33mc7dcecf[m HEAD@{204}: checkout: moving from issue/239-cards-divorce to develop +[33m92b94ba[m HEAD@{205}: commit: preciso rebasear +[33mc7dcecf[m HEAD@{206}: checkout: moving from develop to issue/239-cards-divorce +[33mc7dcecf[m HEAD@{207}: checkout: moving from issue/239-cards-divorce to develop +[33mc7dcecf[m HEAD@{208}: checkout: moving from develop to issue/239-cards-divorce +[33mc7dcecf[m HEAD@{209}: pull: Fast-forward +[33m1704eb1[m HEAD@{210}: checkout: moving from issue/225-aligment to develop +[33m7d799a2[m[33m ([m[1;31morigin/issue/225-aligment[m[33m, [m[1;32missue/225-aligment[m[33m)[m HEAD@{211}: rebase (finish): returning to refs/heads/issue/225-aligment +[33m7d799a2[m[33m ([m[1;31morigin/issue/225-aligment[m[33m, [m[1;32missue/225-aligment[m[33m)[m HEAD@{212}: rebase (reword): Issue #225/aligment +[33m2001295[m HEAD@{213}: rebase (reword): ok +[33m1704eb1[m HEAD@{214}: rebase (start): checkout develop +[33me61f0b8[m HEAD@{215}: checkout: moving from develop to issue/225-aligment +[33m1704eb1[m HEAD@{216}: pull: Fast-forward +[33m334adae[m HEAD@{217}: checkout: moving from issue/225-aligment to develop +[33me61f0b8[m HEAD@{218}: commit: ok +[33m334adae[m HEAD@{219}: checkout: moving from develop to issue/225-aligment +[33m334adae[m HEAD@{220}: checkout: moving from issue/225-alignment to develop +[33mbb96091[m[33m ([m[1;31morigin/issue/225-alignment[m[33m, [m[1;32missue/225-alignment[m[33m)[m HEAD@{221}: checkout: moving from develop to issue/225-alignment +[33m334adae[m HEAD@{222}: pull: Fast-forward +[33m02a4569[m HEAD@{223}: checkout: moving from issue/225-alignment to develop +[33mbb96091[m[33m ([m[1;31morigin/issue/225-alignment[m[33m, [m[1;32missue/225-alignment[m[33m)[m HEAD@{224}: rebase (finish): returning to refs/heads/issue/225-alignment +[33mbb96091[m[33m ([m[1;31morigin/issue/225-alignment[m[33m, [m[1;32missue/225-alignment[m[33m)[m HEAD@{225}: rebase (reword): Issue #225/Aligment +[33m6731cdc[m HEAD@{226}: rebase (reword): Feito +[33m02a4569[m HEAD@{227}: rebase (start): checkout develop +[33m988d099[m HEAD@{228}: checkout: moving from develop to issue/225-alignment +[33m02a4569[m HEAD@{229}: pull: Fast-forward +[33m26949de[m HEAD@{230}: checkout: moving from issue/225-alignment to develop +[33m988d099[m HEAD@{231}: commit: Feito +[33m1f3ba1c[m HEAD@{232}: rebase (finish): returning to refs/heads/issue/225-alignment +[33m1f3ba1c[m HEAD@{233}: rebase (fixup): Issue #225-Aligment +[33mbd0ce61[m HEAD@{234}: rebase (fixup): # This is a combination of 3 commits. +[33m54f9fcc[m HEAD@{235}: rebase (fixup): # This is a combination of 2 commits. +[33m9406554[m HEAD@{236}: rebase (reword): Issue #225-Aligment +[33m94bbc4d[m HEAD@{237}: rebase (reword): Mesclando +[33m26949de[m HEAD@{238}: rebase (start): checkout develop +[33meaeb503[m HEAD@{239}: checkout: moving from develop to issue/225-alignment +[33m26949de[m HEAD@{240}: checkout: moving from issue/225-alignment to develop +[33meaeb503[m HEAD@{241}: commit: finished +[33ma330880[m HEAD@{242}: pull (finish): returning to refs/heads/issue/225-alignment +[33ma330880[m HEAD@{243}: pull (start): checkout a330880eb58b3458db220419dd56cff7060e3c19 +[33mf75d033[m HEAD@{244}: checkout: moving from develop to issue/225-alignment +[33m26949de[m HEAD@{245}: pull: Fast-forward +[33m499d26b[m[33m ([m[1;32missue/224-hotfix-resources[m[33m)[m HEAD@{246}: reset: moving to HEAD +[33m499d26b[m[33m ([m[1;32missue/224-hotfix-resources[m[33m)[m HEAD@{247}: checkout: moving from issue/224-hotfix-resources to develop +[33m499d26b[m[33m ([m[1;32missue/224-hotfix-resources[m[33m)[m HEAD@{248}: checkout: moving from develop to issue/224-hotfix-resources +[33m499d26b[m[33m ([m[1;32missue/224-hotfix-resources[m[33m)[m HEAD@{249}: checkout: moving from HOTFIX-button to develop +[33m7a641e9[m[33m ([m[1;31morigin/HOTFIX-button[m[33m, [m[1;32mHOTFIX-button[m[33m)[m HEAD@{250}: rebase (finish): returning to refs/heads/HOTFIX-button +[33m7a641e9[m[33m ([m[1;31morigin/HOTFIX-button[m[33m, [m[1;32mHOTFIX-button[m[33m)[m HEAD@{251}: rebase (reword): Issue #223/ HOTFIX-button +[33m0f9a5c3[m HEAD@{252}: rebase: fast-forward +[33m499d26b[m[33m ([m[1;32missue/224-hotfix-resources[m[33m)[m HEAD@{253}: rebase (start): checkout develop +[33m0f9a5c3[m HEAD@{254}: checkout: moving from develop to HOTFIX-button +[33m499d26b[m[33m ([m[1;32missue/224-hotfix-resources[m[33m)[m HEAD@{255}: checkout: moving from HOTFIX-button to develop +[33m0f9a5c3[m HEAD@{256}: commit: button-fixed +[33m499d26b[m[33m ([m[1;32missue/224-hotfix-resources[m[33m)[m HEAD@{257}: checkout: moving from develop to HOTFIX-button +[33m499d26b[m[33m ([m[1;32missue/224-hotfix-resources[m[33m)[m HEAD@{258}: pull: Fast-forward +[33m62ba0a5[m HEAD@{259}: checkout: moving from issue/225-alignment to develop +[33mf75d033[m HEAD@{260}: commit: ajuda +[33mcd4b0cb[m HEAD@{261}: commit: contato-page +[33m4447d1c[m HEAD@{262}: commit: publicar-page +[33mb983ba5[m HEAD@{263}: commit: sobre-page +[33md0f1447[m HEAD@{264}: checkout: moving from develop to issue/225-alignment +[33m62ba0a5[m HEAD@{265}: pull: Fast-forward +[33m90a6865[m HEAD@{266}: checkout: moving from issue/207-HOTFIX-complaint-tag to develop +[33m6edfdd7[m[33m ([m[1;31morigin/issue/207-HOTFIX-complaint-tag[m[33m, [m[1;32missue/207-HOTFIX-complaint-tag[m[33m)[m HEAD@{267}: rebase (finish): returning to refs/heads/issue/207-HOTFIX-complaint-tag +[33m6edfdd7[m[33m ([m[1;31morigin/issue/207-HOTFIX-complaint-tag[m[33m, [m[1;32missue/207-HOTFIX-complaint-tag[m[33m)[m HEAD@{268}: rebase (fixup): Issue #207/Complaints-homologation-page +[33m1bad2b0[m HEAD@{269}: rebase (fixup): # This is a combination of 2 commits. +[33mac0310b[m HEAD@{270}: rebase (start): checkout develop +[33m74e8f57[m HEAD@{271}: commit: done +[33m7880bde[m HEAD@{272}: checkout: moving from develop to issue/207-HOTFIX-complaint-tag +[33m90a6865[m HEAD@{273}: checkout: moving from issue/207-HOTFIX-complaint-tag to develop +[33m7880bde[m HEAD@{274}: commit: ok +[33mac0310b[m HEAD@{275}: rebase (continue) (finish): returning to refs/heads/issue/207-HOTFIX-complaint-tag +[33mac0310b[m HEAD@{276}: rebase (continue): Issue #207/Complaints-homologation-page +[33m90a6865[m HEAD@{277}: rebase (start): checkout develop +[33m2ec770c[m HEAD@{278}: checkout: moving from develop to issue/207-HOTFIX-complaint-tag +[33m90a6865[m HEAD@{279}: pull: Fast-forward +[33m82504e2[m HEAD@{280}: checkout: moving from issue/207-HOTFIX-complaint-tag to develop +[33m2ec770c[m HEAD@{281}: commit: ok +[33m82504e2[m HEAD@{282}: checkout: moving from develop to issue/207-HOTFIX-complaint-tag +[33m82504e2[m HEAD@{283}: pull: Fast-forward +[33m8171780[m HEAD@{284}: checkout: moving from issue/176-HOTFIX-resource-tag to develop +[33m1a29408[m[33m ([m[1;31morigin/issue/176-HOTFIX-resource-tag[m[33m, [m[1;32missue/176-HOTFIX-resource-tag[m[33m)[m HEAD@{285}: rebase (continue) (finish): returning to refs/heads/issue/176-HOTFIX-resource-tag +[33m1a29408[m[33m ([m[1;31morigin/issue/176-HOTFIX-resource-tag[m[33m, [m[1;32missue/176-HOTFIX-resource-tag[m[33m)[m HEAD@{286}: rebase (continue): ai +[33m8171780[m HEAD@{287}: rebase (start): checkout develop +[33m6bcba4e[m HEAD@{288}: checkout: moving from develop to issue/176-HOTFIX-resource-tag +[33m8171780[m HEAD@{289}: pull: Fast-forward +[33m5c37def[m HEAD@{290}: checkout: moving from issue/176-HOTFIX-resource-tag to develop +[33m6bcba4e[m HEAD@{291}: commit: ai +[33m5c37def[m HEAD@{292}: checkout: moving from develop to issue/176-HOTFIX-resource-tag +[33m5c37def[m HEAD@{293}: checkout: moving from issue/175-HOTFIX to develop +[33m34cf5fb[m[33m ([m[1;31morigin/issue/175-HOTFIX[m[33m, [m[1;32missue/175-HOTFIX[m[33m)[m HEAD@{294}: rebase (finish): returning to refs/heads/issue/175-HOTFIX +[33m34cf5fb[m[33m ([m[1;31morigin/issue/175-HOTFIX[m[33m, [m[1;32missue/175-HOTFIX[m[33m)[m HEAD@{295}: rebase (reword): Issue #175/HOTFIX +[33mcda84b7[m HEAD@{296}: rebase (reword): done +[33m5c37def[m HEAD@{297}: rebase (start): checkout develop +[33m456859e[m HEAD@{298}: checkout: moving from develop to issue/175-HOTFIX +[33m5c37def[m HEAD@{299}: pull: Fast-forward +[33m3a58570[m HEAD@{300}: checkout: moving from issue/175-HOTFIX to develop +[33m456859e[m HEAD@{301}: commit: done +[33m3a58570[m HEAD@{302}: checkout: moving from develop to issue/175-HOTFIX +[33m3a58570[m HEAD@{303}: checkout: moving from issues/200/190-HOTFIX to develop +[33m61d06b0[m[33m ([m[1;31morigin/issues/200/190-HOTFIX[m[33m, [m[1;32missues/200/190-HOTFIX[m[33m)[m HEAD@{304}: rebase (finish): returning to refs/heads/issues/200/190-HOTFIX +[33m61d06b0[m[33m ([m[1;31morigin/issues/200/190-HOTFIX[m[33m, [m[1;32missues/200/190-HOTFIX[m[33m)[m HEAD@{305}: rebase (pick): Issue #190/#200-HOTFIX +[33m3a58570[m HEAD@{306}: rebase (start): checkout develop +[33m7499204[m HEAD@{307}: checkout: moving from develop to issues/200/190-HOTFIX +[33m3a58570[m HEAD@{308}: pull: Fast-forward +[33m2136eb2[m HEAD@{309}: checkout: moving from issues/200/190-HOTFIX to develop +[33m7499204[m HEAD@{310}: rebase (finish): returning to refs/heads/issues/200/190-HOTFIX +[33m7499204[m HEAD@{311}: rebase (reword): Issue #190/#200-HOTFIX +[33m14073c5[m HEAD@{312}: rebase (reword): done +[33m2136eb2[m HEAD@{313}: rebase (start): checkout develop +[33mbef8e1e[m HEAD@{314}: checkout: moving from develop to issues/200/190-HOTFIX +[33m2136eb2[m HEAD@{315}: pull: Fast-forward +[33m4fa1ef5[m HEAD@{316}: checkout: moving from issues/200/190-HOTFIX to develop +[33mbef8e1e[m HEAD@{317}: commit: done +[33m4fa1ef5[m HEAD@{318}: rebase (finish): returning to refs/heads/issues/200/190-HOTFIX +[33m4fa1ef5[m HEAD@{319}: rebase (start): checkout develop +[33md63b0d0[m HEAD@{320}: reset: moving to HEAD +[33md63b0d0[m HEAD@{321}: checkout: moving from develop to issues/200/190-HOTFIX +[33m4fa1ef5[m HEAD@{322}: pull: Fast-forward +[33md63b0d0[m HEAD@{323}: checkout: moving from issues/200/190-HOTFIX to develop +[33md63b0d0[m HEAD@{324}: checkout: moving from develop to issues/200/190-HOTFIX +[33md63b0d0[m HEAD@{325}: checkout: moving from issue/193/194-HOTFIX to develop +[33md7dbfc0[m[33m ([m[1;31morigin/issue/193/194-HOTFIX[m[33m, [m[1;32missue/193/194-HOTFIX[m[33m)[m HEAD@{326}: rebase (finish): returning to refs/heads/issue/193/194-HOTFIX +[33md7dbfc0[m[33m ([m[1;31morigin/issue/193/194-HOTFIX[m[33m, [m[1;32missue/193/194-HOTFIX[m[33m)[m HEAD@{327}: rebase (reword): Issue #193#104-HOTFIX +[33m335aeac[m HEAD@{328}: rebase (reword): done +[33md63b0d0[m HEAD@{329}: rebase (start): checkout develop +[33m9d04c2d[m HEAD@{330}: checkout: moving from develop to issue/193/194-HOTFIX +[33md63b0d0[m HEAD@{331}: pull: Fast-forward +[33m32299fc[m HEAD@{332}: checkout: moving from issue/193/194-HOTFIX to develop +[33m9d04c2d[m HEAD@{333}: commit: done +[33mf8e4018[m[33m ([m[1;31morigin/issue/203/198/HOTFIX[m[33m, [m[1;32missue/203/198/HOTFIX[m[33m)[m HEAD@{334}: checkout: moving from issue/203/198/HOTFIX to issue/193/194-HOTFIX +[33mf8e4018[m[33m ([m[1;31morigin/issue/203/198/HOTFIX[m[33m, [m[1;32missue/203/198/HOTFIX[m[33m)[m HEAD@{335}: rebase (finish): returning to refs/heads/issue/203/198/HOTFIX +[33mf8e4018[m[33m ([m[1;31morigin/issue/203/198/HOTFIX[m[33m, [m[1;32missue/203/198/HOTFIX[m[33m)[m HEAD@{336}: rebase (reword): Issue #198#203/HOTFIX +[33md9a1b37[m HEAD@{337}: rebase (reword): done +[33m32299fc[m HEAD@{338}: rebase (start): checkout develop +[33ma166174[m HEAD@{339}: checkout: moving from develop to issue/203/198/HOTFIX +[33m32299fc[m HEAD@{340}: pull: Fast-forward +[33m61308b7[m HEAD@{341}: checkout: moving from issue/203/198/HOTFIX to develop +[33ma166174[m HEAD@{342}: commit: done +[33m61308b7[m HEAD@{343}: checkout: moving from develop to issue/203/198/HOTFIX +[33m61308b7[m HEAD@{344}: pull: Fast-forward +[33mae927a6[m HEAD@{345}: checkout: moving from issue/196-HOTFIX-collection-modal to develop +[33m63abe42[m[33m ([m[1;31morigin/issue/196-HOTFIX-collection-modal[m[33m, [m[1;32missue/196-HOTFIX-collection-modal[m[33m)[m HEAD@{346}: rebase (finish): returning to refs/heads/issue/196-HOTFIX-collection-modal +[33m63abe42[m[33m ([m[1;31morigin/issue/196-HOTFIX-collection-modal[m[33m, [m[1;32missue/196-HOTFIX-collection-modal[m[33m)[m HEAD@{347}: rebase (fixup): Issue #196#198/HOTFIX +[33m86affb9[m HEAD@{348}: rebase (start): checkout develop +[33m1b2ecb6[m HEAD@{349}: commit: done1 +[33m86affb9[m HEAD@{350}: rebase (finish): returning to refs/heads/issue/196-HOTFIX-collection-modal +[33m86affb9[m HEAD@{351}: rebase (fixup): Issue #196#198/HOTFIX +[33m0eb8e89[m HEAD@{352}: rebase (reword): Issue #196#198/HOTFIX +[33m76ba4e1[m HEAD@{353}: rebase (reword): done +[33mae927a6[m HEAD@{354}: rebase (start): checkout develop +[33mbbb59ff[m HEAD@{355}: checkout: moving from develop to issue/196-HOTFIX-collection-modal +[33mae927a6[m HEAD@{356}: pull: Fast-forward +[33m919173f[m HEAD@{357}: checkout: moving from issue/196-HOTFIX-collection-modal to develop +[33mbbb59ff[m HEAD@{358}: commit: done +[33mb2fa5c7[m HEAD@{359}: commit: done +[33m919173f[m HEAD@{360}: checkout: moving from develop to issue/196-HOTFIX-collection-modal +[33m919173f[m HEAD@{361}: checkout: moving from issue/183-HOTFIX-carousel to develop +[33me326144[m[33m ([m[1;31morigin/issue/183-HOTFIX-carousel[m[33m, [m[1;32missue/183-HOTFIX-carousel[m[33m)[m HEAD@{362}: rebase (finish): returning to refs/heads/issue/183-HOTFIX-carousel +[33me326144[m[33m ([m[1;31morigin/issue/183-HOTFIX-carousel[m[33m, [m[1;32missue/183-HOTFIX-carousel[m[33m)[m HEAD@{363}: rebase (pick): Issue #183/HOTFIX-about-page +[33m919173f[m HEAD@{364}: rebase (start): checkout develop +[33m7a91ab3[m HEAD@{365}: checkout: moving from develop to issue/183-HOTFIX-carousel +[33m919173f[m HEAD@{366}: pull: Fast-forward +[33mb27a638[m HEAD@{367}: checkout: moving from issue/183-HOTFIX-carousel to develop +[33m7a91ab3[m HEAD@{368}: rebase (finish): returning to refs/heads/issue/183-HOTFIX-carousel +[33m7a91ab3[m HEAD@{369}: rebase (fixup): Issue #183/HOTFIX-about-page +[33m65ff23c[m HEAD@{370}: rebase (fixup): # This is a combination of 2 commits. +[33m0464120[m HEAD@{371}: rebase (reword): Issue #183/HOTFIX-about-page +[33mbe9c3ad[m HEAD@{372}: rebase: fast-forward +[33mb27a638[m HEAD@{373}: rebase (start): checkout develop +[33mfbb4811[m HEAD@{374}: checkout: moving from develop to issue/183-HOTFIX-carousel +[33mb27a638[m HEAD@{375}: checkout: moving from issue/183-HOTFIX-carousel to develop +[33mfbb4811[m HEAD@{376}: commit: done +[33m59c4800[m HEAD@{377}: commit: done +[33mbe9c3ad[m HEAD@{378}: rebase (finish): returning to refs/heads/issue/183-HOTFIX-carousel +[33mbe9c3ad[m HEAD@{379}: rebase (reword): Issue #183/HOTFIX-carousel +[33m5e246a6[m HEAD@{380}: rebase: fast-forward +[33mb27a638[m HEAD@{381}: rebase (start): checkout develop +[33m5e246a6[m HEAD@{382}: checkout: moving from develop to issue/183-HOTFIX-carousel +[33mb27a638[m HEAD@{383}: checkout: moving from issue/183-HOTFIX-carousel to develop +[33m5e246a6[m HEAD@{384}: commit: done +[33mb27a638[m HEAD@{385}: checkout: moving from develop to issue/183-HOTFIX-carousel +[33mb27a638[m HEAD@{386}: pull: Fast-forward +[33mbb20958[m[33m ([m[1;32missue/169-HOTFIX-mobile-perfil[m[33m)[m HEAD@{387}: checkout: moving from issue/171-HOTFIX-collections-mobile to develop +[33m5da9975[m[33m ([m[1;31morigin/issue/171-HOTFIX-collections-mobile[m[33m, [m[1;32missue/171-HOTFIX-collections-mobile[m[33m)[m HEAD@{388}: commit: done +[33mbb20958[m[33m ([m[1;32missue/169-HOTFIX-mobile-perfil[m[33m)[m HEAD@{389}: checkout: moving from develop to issue/171-HOTFIX-collections-mobile +[33mbb20958[m[33m ([m[1;32missue/169-HOTFIX-mobile-perfil[m[33m)[m HEAD@{390}: checkout: moving from issue/169-HOTFIX-mobile-perfil to develop +[33mbb20958[m[33m ([m[1;32missue/169-HOTFIX-mobile-perfil[m[33m)[m HEAD@{391}: checkout: moving from develop to issue/169-HOTFIX-mobile-perfil +[33mbb20958[m[33m ([m[1;32missue/169-HOTFIX-mobile-perfil[m[33m)[m HEAD@{392}: pull: Fast-forward +[33m8c1d35a[m HEAD@{393}: checkout: moving from issue/166-HOTFIX-delete-collection to develop +[33mb7c531d[m[33m ([m[1;31morigin/issue/166-HOTFIX-delete-collection[m[33m, [m[1;32missue/166-HOTFIX-delete-collection[m[33m)[m HEAD@{394}: rebase (finish): returning to refs/heads/issue/166-HOTFIX-delete-collection +[33mb7c531d[m[33m ([m[1;31morigin/issue/166-HOTFIX-delete-collection[m[33m, [m[1;32missue/166-HOTFIX-delete-collection[m[33m)[m HEAD@{395}: rebase (reword): Issue #166:HOTFIX delete collection +[33m974e9c7[m HEAD@{396}: rebase: fast-forward +[33m8c1d35a[m HEAD@{397}: rebase (start): checkout develop +[33m974e9c7[m HEAD@{398}: checkout: moving from develop to issue/166-HOTFIX-delete-collection +[33m8c1d35a[m HEAD@{399}: checkout: moving from issue/166-HOTFIX-delete-collection to develop +[33m974e9c7[m HEAD@{400}: commit: done +[33m8c1d35a[m HEAD@{401}: rebase (finish): returning to refs/heads/issue/166-HOTFIX-delete-collection +[33m8c1d35a[m HEAD@{402}: rebase (start): checkout develop +[33m711b35d[m[33m ([m[1;31morigin/issue/162-HOTFIX-recurso[m[33m, [m[1;32missue/162-HOTFIX-recurso[m[33m)[m HEAD@{403}: reset: moving to HEAD +[33m711b35d[m[33m ([m[1;31morigin/issue/162-HOTFIX-recurso[m[33m, [m[1;32missue/162-HOTFIX-recurso[m[33m)[m HEAD@{404}: checkout: moving from develop to issue/166-HOTFIX-delete-collection +[33m8c1d35a[m HEAD@{405}: pull: Fast-forward +[33m711482c[m HEAD@{406}: checkout: moving from issue/166-HOTFIX-delete-collection to develop +[33m711b35d[m[33m ([m[1;31morigin/issue/162-HOTFIX-recurso[m[33m, [m[1;32missue/162-HOTFIX-recurso[m[33m)[m HEAD@{407}: checkout: moving from issue/162-HOTFIX-recurso to issue/166-HOTFIX-delete-collection +[33m711b35d[m[33m ([m[1;31morigin/issue/162-HOTFIX-recurso[m[33m, [m[1;32missue/162-HOTFIX-recurso[m[33m)[m HEAD@{408}: rebase (finish): returning to refs/heads/issue/162-HOTFIX-recurso +[33m711b35d[m[33m ([m[1;31morigin/issue/162-HOTFIX-recurso[m[33m, [m[1;32missue/162-HOTFIX-recurso[m[33m)[m HEAD@{409}: rebase (pick): Issue #162: HOTFIX resource +[33m711482c[m HEAD@{410}: rebase (start): checkout develop +[33mb856b1f[m HEAD@{411}: checkout: moving from develop to issue/162-HOTFIX-recurso +[33m711482c[m HEAD@{412}: checkout: moving from issue/162-HOTFIX-recurso to develop +[33mb856b1f[m HEAD@{413}: checkout: moving from develop to issue/162-HOTFIX-recurso +[33m711482c[m HEAD@{414}: pull: Fast-forward +[33m2c17be0[m HEAD@{415}: checkout: moving from develop to develop +[33m2c17be0[m HEAD@{416}: checkout: moving from issue/162-HOTFIX-recurso to develop +[33mb856b1f[m HEAD@{417}: rebase (finish): returning to refs/heads/issue/162-HOTFIX-recurso +[33mb856b1f[m HEAD@{418}: rebase (reword): Issue #162: HOTFIX resource +[33m4ad386b[m HEAD@{419}: rebase (reword): done +[33m2c17be0[m HEAD@{420}: rebase (start): checkout develop +[33m9898a07[m HEAD@{421}: checkout: moving from develop to issue/162-HOTFIX-recurso +[33m2c17be0[m HEAD@{422}: pull: Fast-forward +[33mf4c435e[m HEAD@{423}: checkout: moving from issue/162-HOTFIX-recurso to develop +[33m9898a07[m HEAD@{424}: commit: done +[33mf4c435e[m HEAD@{425}: checkout: moving from develop to issue/162-HOTFIX-recurso +[33mf4c435e[m HEAD@{426}: checkout: moving from issue/165-HOTFIX-home to develop +[33mb327101[m[33m ([m[1;31morigin/issue/165-HOTFIX-home[m[33m, [m[1;32missue/165-HOTFIX-home[m[33m)[m HEAD@{427}: rebase (finish): returning to refs/heads/issue/165-HOTFIX-home +[33mb327101[m[33m ([m[1;31morigin/issue/165-HOTFIX-home[m[33m, [m[1;32missue/165-HOTFIX-home[m[33m)[m HEAD@{428}: rebase (reword): Issue #165:HOTFIX home +[33m0e77362[m HEAD@{429}: rebase (reword): done +[33mf4c435e[m HEAD@{430}: rebase (start): checkout develop +[33m07645b3[m HEAD@{431}: checkout: moving from develop to issue/165-HOTFIX-home +[33mf4c435e[m HEAD@{432}: pull: Fast-forward +[33m58cf2a7[m HEAD@{433}: checkout: moving from issue/165-HOTFIX-home to develop +[33m07645b3[m HEAD@{434}: commit: done +[33m58cf2a7[m HEAD@{435}: checkout: moving from issue-164/Hotfix-colecao to issue/165-HOTFIX-home +[33m2c5f58a[m[33m ([m[1;31morigin/issue-164/Hotfix-colecao[m[33m, [m[1;32missue-164/Hotfix-colecao[m[33m)[m HEAD@{436}: checkout: moving from issue/165-HOTFIX-home to issue-164/Hotfix-colecao +[33m58cf2a7[m HEAD@{437}: checkout: moving from develop to issue/165-HOTFIX-home +[33m58cf2a7[m HEAD@{438}: checkout: moving from issue-164/Hotfix-colecao to develop +[33m2c5f58a[m[33m ([m[1;31morigin/issue-164/Hotfix-colecao[m[33m, [m[1;32missue-164/Hotfix-colecao[m[33m)[m HEAD@{439}: rebase (finish): returning to refs/heads/issue-164/Hotfix-colecao +[33m2c5f58a[m[33m ([m[1;31morigin/issue-164/Hotfix-colecao[m[33m, [m[1;32missue-164/Hotfix-colecao[m[33m)[m HEAD@{440}: rebase (reword): Issue #164/HOTFIX collection +[33me276d83[m HEAD@{441}: rebase (reword): done +[33m58cf2a7[m HEAD@{442}: rebase (start): checkout develop +[33m2a97aaa[m HEAD@{443}: checkout: moving from develop to issue-164/Hotfix-colecao +[33m58cf2a7[m HEAD@{444}: pull: Fast-forward +[33mb06cea0[m HEAD@{445}: checkout: moving from issue-164/Hotfix-colecao to develop +[33m2a97aaa[m HEAD@{446}: commit: done +[33mb06cea0[m HEAD@{447}: checkout: moving from develop to issue-164/Hotfix-colecao +[33mb06cea0[m HEAD@{448}: checkout: moving from issue-164/Hotfix-colecao to develop +[33mb06cea0[m HEAD@{449}: checkout: moving from develop to issue-164/Hotfix-colecao +[33mb06cea0[m HEAD@{450}: pull: Fast-forward +[33mfd5247e[m HEAD@{451}: checkout: moving from issue/158-fix-about-page to develop +[33mad77385[m[33m ([m[1;31morigin/issue/158-fix-about-page[m[33m, [m[1;32missue/158-fix-about-page[m[33m)[m HEAD@{452}: rebase (finish): returning to refs/heads/issue/158-fix-about-page +[33mad77385[m[33m ([m[1;31morigin/issue/158-fix-about-page[m[33m, [m[1;32missue/158-fix-about-page[m[33m)[m HEAD@{453}: rebase (pick): Issue #158/FIX about page +[33mfd5247e[m HEAD@{454}: rebase (start): checkout develop +[33me85b8e4[m HEAD@{455}: checkout: moving from develop to issue/158-fix-about-page +[33mfd5247e[m HEAD@{456}: pull: Fast-forward +[33m0762558[m HEAD@{457}: checkout: moving from issue/158-fix-about-page to develop +[33me85b8e4[m HEAD@{458}: rebase (finish): returning to refs/heads/issue/158-fix-about-page +[33me85b8e4[m HEAD@{459}: rebase (fixup): Issue #158/FIX about page +[33m9a55a4b[m HEAD@{460}: rebase (reword): Issue #158/FIX about page +[33m9eb9070[m HEAD@{461}: rebase: fast-forward +[33m0762558[m HEAD@{462}: rebase (start): checkout develop +[33mb91a62f[m HEAD@{463}: checkout: moving from develop to issue/158-fix-about-page +[33m0762558[m HEAD@{464}: checkout: moving from issue/158-fix-about-page to develop +[33mb91a62f[m HEAD@{465}: commit: fixed +[33m9eb9070[m HEAD@{466}: rebase (finish): returning to refs/heads/issue/158-fix-about-page +[33m9eb9070[m HEAD@{467}: rebase (reword): fixed +[33m55ec9be[m HEAD@{468}: rebase: fast-forward +[33m0762558[m HEAD@{469}: rebase (start): checkout develop +[33m55ec9be[m HEAD@{470}: checkout: moving from develop to issue/158-fix-about-page +[33m0762558[m HEAD@{471}: checkout: moving from issue/158-fix-about-page to develop +[33m55ec9be[m HEAD@{472}: commit: fixed +[33m0762558[m HEAD@{473}: checkout: moving from develop to issue/158-fix-about-page +[33m0762558[m HEAD@{474}: pull: Fast-forward +[33m8c42da0[m HEAD@{475}: pull: Fast-forward +[33mca14f32[m HEAD@{476}: checkout: moving from fix-detail to develop +[33m635ecb2[m[33m ([m[1;31morigin/fix-detail[m[33m, [m[1;32mfix-detail[m[33m)[m HEAD@{477}: rebase (finish): returning to refs/heads/fix-detail +[33m635ecb2[m[33m ([m[1;31morigin/fix-detail[m[33m, [m[1;32mfix-detail[m[33m)[m HEAD@{478}: rebase (reword): Simple change (no issue) +[33m948e1ee[m HEAD@{479}: rebase: fast-forward +[33mca14f32[m HEAD@{480}: rebase (start): checkout develop +[33m948e1ee[m HEAD@{481}: checkout: moving from develop to fix-detail +[33mca14f32[m HEAD@{482}: checkout: moving from fix-detail to develop +[33m948e1ee[m HEAD@{483}: commit: detail fixed +[33mca14f32[m HEAD@{484}: checkout: moving from develop to fix-detail +[33mca14f32[m HEAD@{485}: pull: Fast-forward +[33mc64803f[m HEAD@{486}: checkout: moving from issue/144-about-page-changes to develop +[33m004ea21[m[33m ([m[1;31morigin/issue/144-about-page-changes[m[33m, [m[1;32missue/144-about-page-changes[m[33m)[m HEAD@{487}: checkout: moving from develop to issue/144-about-page-changes +[33mc64803f[m HEAD@{488}: clone: from gitlab.c3sl.ufpr.br:mecred/frontend-mecred.git diff --git a/next.config.mjs b/next.config.mjs index 7fe6a5fa6fffdcfa49fe673b76216ad5f96b3af3..1c3824f5eed1a0c01605f125d68c34d79f1971c0 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -40,6 +40,12 @@ const nextConfig = { port: '443', pathname: '/**', }, + { + protocol: 'https', + hostname: 's3.c3sl.ufpr.br', + port: '', + pathname: '/**', + }, ], }, }; diff --git a/public/images/slide-1.png b/public/images/slide-1.png new file mode 100644 index 0000000000000000000000000000000000000000..f470c7f7a46a73a61f4b56e3fd70b12c06c3fe8e Binary files /dev/null and b/public/images/slide-1.png differ diff --git a/public/images/slide-2.png b/public/images/slide-2.png new file mode 100644 index 0000000000000000000000000000000000000000..8dbcd7bfcc951e810fb8571af40d2f7df837f7de Binary files /dev/null and b/public/images/slide-2.png differ diff --git a/public/images/slide-3.png b/public/images/slide-3.png new file mode 100644 index 0000000000000000000000000000000000000000..871cdd11147f76b91db45d46b6daaec530a7a1b7 Binary files /dev/null and b/public/images/slide-3.png differ diff --git a/public/images/slide-4.png b/public/images/slide-4.png new file mode 100644 index 0000000000000000000000000000000000000000..ef08474d3293dbab303eaa23bba18c870f5c8030 Binary files /dev/null and b/public/images/slide-4.png differ diff --git a/public/ocupacao.svg b/public/ocupacao.svg new file mode 100644 index 0000000000000000000000000000000000000000..9ea2d211d895a57422e08547580f08008c21d0fe --- /dev/null +++ b/public/ocupacao.svg @@ -0,0 +1,26 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="28" height="28" viewBox="0 0 28 28"> + <defs> + <style> + .cls-1 { + fill: #b9cccc; + } + + .cls-2 { + clip-path: url(#clip-path); + } + + .cls-3 { + fill: none; + } + </style> + <clipPath id="clip-path"> + <circle id="Ellipse_112" data-name="Ellipse 112" class="cls-1" cx="14" cy="14" r="14" transform="translate(563 361)"/> + </clipPath> + </defs> + <g id="Mask_Group_22" data-name="Mask Group 22" class="cls-2" transform="translate(-563 -361)"> + <g id="_3c465226d6ca6573adddd4eb85572565" data-name="3c465226d6ca6573adddd4eb85572565" transform="translate(563 361)"> + <path id="Path_203" data-name="Path 203" class="cls-3" d="M0,0H28V28H0Z"/> + <path id="Path_204" data-name="Path 204" class="cls-1" d="M23.333,7H18.667V4.667a2.325,2.325,0,0,0-2.333-2.333H11.667A2.325,2.325,0,0,0,9.333,4.667V7H4.667A2.315,2.315,0,0,0,2.345,9.333L2.333,22.167A2.325,2.325,0,0,0,4.667,24.5H23.333a2.325,2.325,0,0,0,2.333-2.333V9.333A2.325,2.325,0,0,0,23.333,7Zm-7,0H11.667V4.667h4.667Z"/> + </g> + </g> +</svg> diff --git a/public/usuario-perfil.svg b/public/usuario-perfil.svg new file mode 100644 index 0000000000000000000000000000000000000000..2c6b4326fa7f6bcd30a6e7dc5ab9d4b233459ba0 --- /dev/null +++ b/public/usuario-perfil.svg @@ -0,0 +1,4 @@ +<svg id="seguir" xmlns="http://www.w3.org/2000/svg" width="28.003" height="28.004" viewBox="0 0 28.003 28.004"> + <circle id="Ellipse_118" data-name="Ellipse 118" cx="7.239" cy="7.239" r="7.239" transform="translate(6.763 0)" fill="#b9cccc"/> + <path id="Path_46" data-name="Path 46" d="M28,30.189c0,5.313-28,5.313-28,0S6.266,20.57,14,20.57,28,24.875,28,30.189Z" transform="translate(0 -6.17)" fill="#b9cccc"/> +</svg> diff --git a/public/usuario-verificado.svg b/public/usuario-verificado.svg new file mode 100644 index 0000000000000000000000000000000000000000..40ae1c861483071dbe81ce5ba0ad4576d94a5f60 --- /dev/null +++ b/public/usuario-verificado.svg @@ -0,0 +1,21 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="28" height="28" viewBox="0 0 28 28"> + <defs> + <style> + .cls-1 { + fill: #b9cccc; + } + + .cls-2 { + clip-path: url(#clip-path); + } + </style> + <clipPath id="clip-path"> + <circle id="Ellipse_111" data-name="Ellipse 111" class="cls-1" cx="14" cy="14" r="14" transform="translate(563 309)"/> + </clipPath> + </defs> + <g id="Mask_Group_21" data-name="Mask Group 21" class="cls-2" transform="translate(-563 -309)"> + <g id="_0a659199c9168d499819ff89c5c39cc1" data-name="0a659199c9168d499819ff89c5c39cc1" transform="translate(563.016 309.02)"> + <path id="Path_202" data-name="Path 202" class="cls-1" d="M26.766,11.2q-.871-.843-1.744-1.7Q25,8.322,24.96,7.138A4.228,4.228,0,0,0,23.687,4.29a4.226,4.226,0,0,0-2.853-1.27q-1.186-.037-2.372-.061-.855-.871-1.7-1.739a3.805,3.805,0,0,0-5.566,0q-.845.87-1.7,1.743-1.186.024-2.372.061A4.37,4.37,0,0,0,3,7.142Q2.964,8.326,2.939,9.51q-.874.855-1.744,1.7a3.787,3.787,0,0,0,0,5.55q.871.842,1.748,1.7.023,1.185.061,2.37A4.361,4.361,0,0,0,7.129,24.94Q8.315,24.978,9.5,25q.855.87,1.7,1.738a3.811,3.811,0,0,0,5.57,0q.844-.869,1.7-1.741,1.186-.025,2.372-.062a4.369,4.369,0,0,0,4.126-4.118q.037-1.183.061-2.367.874-.855,1.745-1.7a3.779,3.779,0,0,0-.008-5.551ZM20.933,12.21c-2.358,2.45-4.754,4.955-7.11,7.44a2.051,2.051,0,0,1-1.489.643h-.009a2.089,2.089,0,0,1-1.491-.64Q8.944,17.7,7.042,15.765a2.04,2.04,0,0,1,.042-2.918,2.1,2.1,0,0,1,2.949.037q1.13,1.158,2.263,2.323c1.87-1.96,3.75-3.932,5.6-5.873a2.076,2.076,0,0,1,2.938-.043A2.046,2.046,0,0,1,20.933,12.21Z"/> + </g> + </g> +</svg> diff --git a/src/app/acessibilidade/page.js b/src/app/acessibilidade/page.js index 91bf4f1bf2e3e8d172453f10092d532ca36f63d2..57f081968163ba0886c1554d5f2eb71908fff1ab 100644 --- a/src/app/acessibilidade/page.js +++ b/src/app/acessibilidade/page.js @@ -4,7 +4,7 @@ export default function Help() { return ( <Overlay type="twoColumns"> <div className="flex w-full justify-center"> - <div className="max-w-screen-md bg-white-HC-dark rounded p-12"> + <div className="max-w-screen-md bg-white-HC-dark rounded p-12 outline outline-1 outline-ice-HC-white"> <div className="text-2xl mb-8 text-darkGray-HC-white font-bold">Acessibilidade</div> <div className="text-md mb-8 text-darkGray-HC-white"> O MECRED acredita na importância de uma educação de qualidade e acessível para todos. Por isso, adota os princípios do design universal para assegurar que sua plataforma seja inclusiva e de fácil navegação. Nesta página, você encontrará instruções detalhadas sobre como navegar pelo site sem o uso do mouse. Ao final da página, há um botão que direciona para a tela de contato, onde você pode relatar eventuais problemas diretamente à nossa equipe. @@ -17,9 +17,9 @@ export default function Help() { <div className="text-md text-darkGray-HC-white"><div className="font-bold font-mono inline mx-2">{"<Ctrl> + <0>"}</div>Restaurar o tamanho da fonte para o tamanho original.</div> </div> <div className="flex justify-center flex-col items-center"> - <div className="text-darkGray-HC-white-underline mt-4 text-xl font-bold">Quer saber mais?</div> - <div className="text-darkGray-HC-white-underline text-md mt-1 ml-3">Acesse a página de Ajuda e Suporte!</div> - <a href="/ajuda" className="mt-4 bg-turquoise text-md text-white-HC-dark-underline p-1 px-6 rounded-lg hover:bg-turquoise-hover">Ir para a página de Ajuda</a> + <div className="text-darkGray-HC-white mt-4 text-xl font-bold">Quer saber mais?</div> + <div className="text-darkGray-HC-white text-md mt-1 ml-3">Acesse a página de Ajuda e Suporte!</div> + <a href="/ajuda" className="mt-4 bg-turquoise-HC-white text-lg text-white-HC-dark-underline p-2 px-4 rounded-lg hover:bg-darkTurquoise-HC-dark hover:text-white outline outline-1">Ir para a página de Ajuda</a> </div> </div> </div> diff --git a/src/app/ajuda/page.js b/src/app/ajuda/page.js index d3ade305c7fe97982ac4f5e4d8ad80eb0a15346c..26b13a3cc6f981095957394a81967d055baee327 100644 --- a/src/app/ajuda/page.js +++ b/src/app/ajuda/page.js @@ -58,10 +58,10 @@ export default function Help() { <Overlay type="twoColumns"> <div className="overflow-y-auto scrollbar-none ml-6 max-md:mb-24 h-screen"> <div className="flex justify-center"> - <div className="text-darkGray-HC-white-underline text-2xl font-bold">Ajuda e Suporte</div> + <div className="text-darkGray-HC-white text-2xl font-bold">Ajuda e Suporte</div> </div> <div className="flex justify-center mt-4"> - <p className="text-darkGray-HC-white-underline text-lg max-sm:text-center">Entre em contato para enviar dúvidas, sugestões ou críticas.</p> + <p className="text-darkGray-HC-white text-lg max-sm:text-center">Entre em contato para enviar dúvidas, sugestões ou críticas.</p> </div> <div className="flex justify-center mt-8"> <div className=" max-xl:overflow-x-auto max-xl:ml-10 flex gap-10 max-sm:gap-4"> @@ -93,7 +93,7 @@ export default function Help() { onClick={() => router.push(`/topicosAjuda?section=${item.sectionPos}&pos=${idx}`) } - className="flex text-start text-sm mt-4 ml-3 hover:turquoise-HC-underline underline" + className="flex text-start text-sm mt-4 ml-3 hover:text-turquoise-HC-white-underline" > {question} </button> @@ -103,9 +103,9 @@ export default function Help() { </div> </div> <div className="flex flex-col items-center rounded-xl px-10 max-sm:px-0 max-sm:py-6 mx-20 max-sm:mx-4 max-md:pb-28"> - <div className="text-darkGray-HC-white-underline mt-5 max-sm:mt-0 text-xl font-bold text-center">Não encontrou o que precisa?</div> - <div className="text-darkGray-HC-white-underline text-md mt-4 ml-3 text-center">Entre em contato com nossa equipe</div> - <button onClick={() => router.push("/contato")} className="mt-4 bg-turquoise text-lg text-white-HC-dark-underline p-2 px-4 rounded-lg hover:bg-turquoise-hover">Página de contato</button> + <div className="text-darkGray-HC-white mt-5 max-sm:mt-0 text-xl font-bold text-center">Não encontrou o que precisa?</div> + <div className="text-darkGray-HC-white text-md mt-4 ml-3 text-center">Entre em contato com nossa equipe</div> + <button onClick={() => router.push("/contato")} className="mt-4 bg-turquoise-HC-white text-lg text-white-HC-dark-underline p-2 px-4 rounded-lg hover:bg-darkTurquoise-HC-dark hover:text-white outline outline-1">Página de contato</button> </div> </div> diff --git a/src/app/colecao/[id]/components/collectionItems.js b/src/app/colecao/[id]/components/collectionItems.js index 9cdadf17844f3add2ab6df8bf695601eb9c23434..ba20d57e755983ddc308075a6cb04a931799442d 100644 --- a/src/app/colecao/[id]/components/collectionItems.js +++ b/src/app/colecao/[id]/components/collectionItems.js @@ -1,27 +1,27 @@ import { useMediaQuery } from "@mui/material"; import Cards from "@/app/components/Cards"; -export default function CollectionItems({ collection }) { +export default function CollectionItems({ collection, resources }) { const isSm = useMediaQuery((theme) => theme.breakpoints.down('sm')); return ( <div className="flex flex-col bg-white-HC-dark p-4 rounded-lg"> <div className="text-darkGray-HC-white-underline font-bold text-xl mb-3">Recursos na coleção</div> <div className="flex flex-col gap-3"> - {collection.collection_items.sort((a,b) => a.position - b.position).map((item, index) => { + {resources?.sort((a,b) => a.position - b.position).map((item, index) => { return ( <Cards collectionSource={collection["id"]} horizontal={!isSm} noAvatar={!isSm} - id={item["collectionable"]["id"]} + id={item.id} key={index} - title={item["collectionable"]["name"]} - author={item["collectionable"]["publisher"]["name"]} - avatar={item["collectionable"]["publisher"]["avatar"]} - image={item["collectionable"]["thumbnail"]} - type={item["collectionable"]["object_type"]} - updated_at={item["collectionable"]["updated_at"]} + title={item.name} + author={item.author} + avatar={`https://s3.c3sl.ufpr.br/mecredteste/avatar/${collection.user_id}`} + image={`https://s3.c3sl.ufpr.br/mecredteste/thumbnail/resource/${item.id}`} + type={item.type} + updated_at={item.updated_at} thumbWidth={isSm ? "100%" : "230px"} thumbHeight="auto" width="100%" diff --git a/src/app/colecao/[id]/components/publisherInfoCollection.js b/src/app/colecao/[id]/components/publisherInfoCollection.js index ce21216aee7ee189056f540cb61487e9c4b9a30f..9b5c4c54efca84ed12334e23591c4c814aad1a99 100644 --- a/src/app/colecao/[id]/components/publisherInfoCollection.js +++ b/src/app/colecao/[id]/components/publisherInfoCollection.js @@ -23,7 +23,7 @@ export default function PublisherInfoCollection({ publisher, disabledButton = fa const followHandler = () => { loginBarrier(); mecredApi.put( - `users/${publisher.id}/follow/`, + `public/users/follow/${publisher.id}`, {}, { headers: { @@ -40,19 +40,16 @@ export default function PublisherInfoCollection({ publisher, disabledButton = fa function getRandomBg(id) { const colors = [ - "bg-turquoise", + "bg-turquoise-HC-white", "bg-orange-HC-white", - "bg-turquoise-hover", - "bg-darkOrange-HC-gray ", + "bg-darkTurquoise-HC-white", + "bg-darkOrange-HC-white", "bg-violet-HC-white", "bg-pink-HC-white", "bg-red-HC-white", "bg-darkGray-HC-white", "bg-darkGray-HC-white-underline", - "bg-ice-HC-dark ", - "bg-darkGray-HC-white", - "bg-darkGray-HC-white", - "bg-turquoise-HC-dark", + "bg-ice-HC-white", ] return colors[id % colors.length]; diff --git a/src/app/colecao/[id]/page.js b/src/app/colecao/[id]/page.js index 4ef56f1beff4765ed49d768fb1f79a8103dd2e82..c298e0b0c9be2b4e4ab0ae54e13b90f19542a10a 100644 --- a/src/app/colecao/[id]/page.js +++ b/src/app/colecao/[id]/page.js @@ -27,35 +27,27 @@ export default function Colecao({ params }) { useEffect(() => { const fetchData = async () => { try { - let headers = {}; + const collectionResponse = await mecredApi.get(`public/collections/${params.id}`); + const collection = collectionResponse.data; + const resourcesResponse = await mecredApi.get(`public/collections/${params.id}/resources`); + const resources = resourcesResponse.data; + const ownerResponse = await mecredApi.get(`public/userCollections/${params.id}/owner`) + const owner = ownerResponse.data; - if (isLoggedIn()) { - headers = { - "access-token": token, - "token-type": "Bearer", - client: client, - uid: uid, - Expires: 0, - }; - } - - const response = await mecredApi.get(`collections/${params.id}`); - - setCollection(response.data); + setCollection({ ...collection, resources: resources, owner: owner }); } catch (error) { + console.error("Erro ao buscar dados:", error); setError(true); } }; - fetchData(); - }, [params.id, client, token, uid]); + }, [params.id]); useEffect(() => { // Função para checar o tamanho da tela const checkScreenSize = () => { setIsSmallScreen(window.innerWidth < 1280); }; - checkScreenSize(); // Checa no primeiro render window.addEventListener("resize", checkScreenSize); // Adiciona o listener @@ -78,33 +70,33 @@ export default function Colecao({ params }) { <div className="bg-ice-HC-dark p-3 w-full"> <div className=" flex justify-center"> {/* Pré-visualização */} - <CollectionPreview collection={collection} /> + <CollectionPreview collection={collection.collection} resources={collection?.resources.resources} /> </div> <div> <div> <div className="text-darkGray-HC-white mt-5 text-2xl font-bold"> {/* Título */} - <h1>{collection.name}</h1> + <h1>{collection.collection.name}</h1> </div> <div className="text-darkGray-HC-white text-sm font-bold"> {/* tags */} - <Tags tags={collection.tags} /> + <Tags tags={collection.collection.tags} /> </div> </div> </div> <div className="flex flex-row gap-3 pb-4 pt-4"> - <DownloadButton id={collection.id} objects={collection.collection_items} /> - <ShareButton id={collection.id} type={"colecao"} /> + <DownloadButton id={collection.collection.id} objects={collection?.resources} /> + <ShareButton id={collection.collection.id} type={"colecao"} /> </div> <div> {/* Publicador */} - <PublisherInfoCollection publisher={collection?.owner} /> + <PublisherInfoCollection publisher={collection?.owner[0]} /> </div> </div> </div> <div className="px-[25px] bg-ice-HC-dark"> <div> {/* recommendations */} </div> - <CollectionItems collection={collection} /> + <CollectionItems collection={collection.collection} resources={collection?.resources.resources || []}/> </div> </> )} diff --git a/src/app/components/About.js b/src/app/components/About.js index cd8d63e9a1b891e6de4418a2133de15164a076fb..4b43b4add13b724907630258227ccb0d96de87dd 100644 --- a/src/app/components/About.js +++ b/src/app/components/About.js @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { useEffect, useState, useRef } from "react"; import mecredApi from "@/axiosConfig"; import Title from "./Title"; import Image from "next/image"; @@ -18,6 +18,7 @@ import AccountCircleRoundedIcon from '@mui/icons-material/AccountCircleRounded'; export default function AboutComponent() { const [statistics, setStatistics] = useState({}); + useEffect(() => { mecredApi .get("/statistics") @@ -35,7 +36,7 @@ export default function AboutComponent() { > <Image className={`rounded-lg w-14 h-14 invertIcon-HC-black`} - style={{ }} + style={{}} alt={name} src={icon} width={10} @@ -52,32 +53,35 @@ export default function AboutComponent() { const Statistics = () => { return ( - <div className="flex max-sm:flex-col mb-10"> + <div className="flex max-sm:flex-col mb-10 gap-x-[60px]"> <StatisticInfo - name={<p>Recursos <br /> Disponíveis</p>} + name={<p>Recursos Disponíveis</p>} data={statistics["count"]} - color={{ text: "text-orange-HC-white", bg: "bg-orange-HC-white" }} + color={{ text: "text-darkGray-HC-white", bg: "bg-orange-HC-white" }} icon="/redigitais.svg" /> <StatisticInfo - name={<p>Recursos <br /> Visualizados <br /> por mês</p>} + name={<p>Recursos Acessados <br /> por mês</p>} data={statistics["month_downloads"]} - color={{ text: "text-violet-HC-white", bg: "bg-violet-HC-white" }} + color={{ text: "text-darkGray-HC-white", bg: "bg-violet-HC-white" }} icon="/download.svg" /> <StatisticInfo - name={<p>Usuários <br /> Cadastrados </p>} - data="31207" - color={{ text: "text-pink-HC-white", bg: "bg-pink-HC-white" }} + name={<p>Usuários Cadastrados </p>} + data={statistics["unique_users"]} + color={{ text: "text-darkGray-HC-white", bg: "bg-pink-HC-white" }} icon="/seguir.svg" /> </div> ); }; + + + const ActorInfo = ({ name, description, nameImage }) => { return ( - <div className={`flex flex-col justify-start w-full items-center rounded-md`}> + <div className={`flex flex-col justify-start max-xl:w-full w-[500px] items-center rounded-md`}> <Image className="rounded-lg" alt={name} @@ -85,24 +89,47 @@ export default function AboutComponent() { width={500} height={10} /> - <span className="text-light text-darkGray-HC-white mt-4 text-base text-left"> + <span className="text-light text-darkGray-HC-white mt-10 mb-12 text-base text-start"> {description} </span> </div> ); }; + const MecredStats = () => { + + return ( + <div> + <div className="mx-8 my-10"> + <h1 className="flex justify-center font-bold text-2xl text-darkGray-HC-white mx-10"> + A MEC RED é uma rede para você se conectar com pessoas interessadas em Educação! + </h1> + </div> + <div> + <h1 className="flex text-xl justify-center text-darkGray-HC-white text-wrap max-md:mx-10 mx-[100px] my-7"> + Construa conosco a sua rede de conhecimentos, interagindo com pessoas envolvidas com experiência educacionais que ocorrem em todo o Brasil! + </h1> + </div> + <div> + <div className="flex flex-row justify-center"> + < Statistics /> + </div> + </div> + </div> + + ); + } + const Actors = () => { return ( <> - <h1 className="text-2xl text-darkGray-HC-white font-bold mb-3 mt-10"> + <h1 className="text-2xl text-darkGray-HC-white font-bold mt-10"> A quem se destina? </h1> - <h1 className="flex text-xl text-balance text-darkGray-HC-white xl:w-[80%] mb-10"> - A plataforma é aberta e destina-se a todos e todas que se interessam - pela relação entre a escola e a Cultura Digital: + <h1 className="text-xl text-center text-darkGray-HC-white lg:w-2/5 my-10 max-sm:hidden"> + A MEC RED é aberta e destina-se a todos e todas que se interessam pela relação entre a escola e a cultura digital </h1> - <div className="w-full grid grid-rows-2 max-sm:grid-rows-4 grid-flow-col gap-10 justify-center mb-10 "> + <div className="w-full grid grid-rows-2 max-sm:grid-rows-4 px-10 grid-flow-col gap-10 justify-center mb-10 "> <ActorInfo name="Professores" description="Encontre recursos digitais que atendem aos objetivos das suas aulas! Aproveite para seguir outros professores, acessar coleções e conhecer novas experiências de uso!" @@ -136,7 +163,7 @@ export default function AboutComponent() { className={`flex h-24 w-24 my-2 mx-10 rounded-full items-center justify-center ${color}`} > <Image - className={` invertIcon-HC-black rounded-lg w-12 h-12 bg-${color} ${title === "Publicar o seu Recurso" && `rotate-180` }`} + className={` invertIcon-HC-black rounded-lg w-12 h-12 bg-${color} ${title === "Publicar o seu Recurso" && `rotate-180`}`} alt={title} src={icon} width={10} @@ -235,11 +262,11 @@ export default function AboutComponent() { const Differences = () => { return ( <> - <h1 className="text-xl tracking-tight text-darkGray-HC-white font-bold mb-2 mt-10 max-sm:py-2"> + <h1 className="text-xl tracking-tight text-darkGray-HC-white font-bold mb-6 mt-10 max-sm:py-2"> O que nos faz diferentes? </h1> <div> - <div className="flex w-full align-middle px-16 max-sm:px-0 mt-4 mb-10 justify-center max-xl:flex-col max-xl:items-center space-x-2"> + <div className="flex w-full align-middle xl:px-60 lg:px-28 max-sm:px-0 mt-4 mb-10 justify-center max-xl:flex-col max-xl:items-center space-x-2"> <div className="w-64 grid grid-cols-1 place-content-center xl:mr-4"> <Image className={` -mt-4 rounded-lg`} @@ -292,7 +319,7 @@ export default function AboutComponent() { <h1 className="flex text-xl text-balance text-darkGray-HC-white xl:w-[80%] mb-10 max-md:px-4"> A MEC RED é construída de forma colaborativa por uma comunidade, seguindo os princípios do software livre, com atualizações frequentes e licenciada sob GNU AGP. </h1> - <div className="grid grid-cols-2 mx-24 gap-x-16 gap-y-8 mb-16 mt-4 max-md:grid-cols-1 max-md:ml-10 max-md:mr-4 max-md:mt-0"> + <div className="grid grid-cols-2 xl:mx-36 md:mx-20 gap-x-16 gap-y-8 mb-16 mt-4 max-md:grid-cols-1 max-md:ml-10 max-md:mr-4 max-md:mt-0"> <DevelopmentInfo title="Software Livre" description="A MEC RED é um software livre, permitindo acesso, modificação e distribuição do código. Isso promove transparência, colaboração e inovação aberta. Com essa abordagem, a plataforma cresce de forma coletiva e acessível." @@ -318,27 +345,92 @@ export default function AboutComponent() { link="/equipe" /> </div> - <DevelopmentInfo - title="Estatísticas" - description="Veja as estatísticas de uso da plataforma." - access="Clique aqui para ver as estatísticas." - link="/estatisticas" - /> </> ) } + + const SlideInfo = ({ name, description, nameImage, link }) => { + return ( + <a href={link} className="block"> + <div className="flex mt-2 flex-row items-center w-full"> + <div className="relative border border-white 2xl:w-[calc(20vw+8px)] max-xl:w-[248px] xl:w-[calc(18vw+23px)] h-[32vw] max-xl:h-[420px] max-md:h-[332px] overflow-hidden rounded-lg "> + <Image + className="object-cover object-[60%_75%]" + alt={name} + src={nameImage} + fill + /> + <div className="absolute bottom-0 left-0 w-full h-1/3 bg-gradient-to-t from-black to-transparent"> + <span className="absolute bottom-0 left-0 w-full bg-transparent bg-opacity-60 font-bold text-white text-xl max-xl:text-base pl-4 pb-8 max-md:pb-6"> + {description} + </span> + </div> + </div> + </div> + </a> + ); + }; + + const Slides = () => { + const slidesRef = useRef(null); + + useEffect(() => { + const handleWheel = (e) => { + if (e.deltaY !== 0) { + slidesRef.current.scrollLeft += e.deltaY*2; // Usa o scroll para horizontal + e.preventDefault(); // Impede o comportamento padrão + } + }; + const slidesContainer = slidesRef.current; + slidesContainer.addEventListener("wheel", handleWheel); // O evento wheel dispara quando o usuário gira o scroll do mouse + + // Limpeza do evento + return () => slidesContainer.removeEventListener("wheel", handleWheel); + }, []); + + return ( + <> + <div className="w-full px-1 xl:grid xl:grid-rows-1 xl:grid-flow-col gap-4 justify-between mb-10 pb-2 flex flex-nowrap overflow-x-auto scrollbar-none max-xl:animate-scrollHint scroll-smooth" + ref={slidesRef} + > + <SlideInfo + name="Professores" + description="Como publicar um recurso?" + nameImage="/images/slide-1.png" + link="/topicosAjuda?section=0&pos=1" + /> + <SlideInfo + name="Alunos" + description="Como fazer uma busca?" + nameImage="/images/slide-2.png" + link="/topicosAjuda?section=1&pos=0" + /> + <SlideInfo + name="troca" + description="Por que se cadastrar?" + nameImage="/images/slide-3.png" + link="/topicosAjuda?section=3&pos=0" + /> + <SlideInfo + name="Comunidade Acadêmica" + description="Como fazer meu cadastro?" + nameImage="/images/slide-4.png" + link="/topicosAjuda?section=3&pos=1" + /> + </div> + </> + ); + }; + return ( <> <div className="overflow-y-auto scrollbar-none"> - <div className="flex max-lg:col-span-3 col-span-2"> + <div className="flex col-span-2"> <div className="flex flex-col px-3 w-full"> - <Carousel /> - <div className="flex flex-col text-center items-center rounded-lg bg-white-HC-dark outline outline-1 outline-ice-HC-white "> - <div> - <Title /> - </div> - <Statistics /> + <Slides /> + <div className="flex flex-col text-center items-center rounded-lg bg-white-HC-dark outline outline-1 outline-ice-HC-white "> + <MecredStats /> </div> <div className="flex flex-col text-center items-center mt-12 rounded-lg bg-white-HC-dark max-sm:hidden outline outline-1 outline-ice-HC-white"> <Actors /> @@ -369,23 +461,6 @@ export default function AboutComponent() { </div> </div> </div> - <div className="max-xl:hidden col-span-1 my-3 "> - <div className="flex flex-col items-center gap-6 bg-white-HC-dark text-darkGray-HC-white rounded-xl px-10 py-7 mx-20 outline outline-1 outline-ice-HC-white"> - <p className="font-bold text-3xl w-full text-center">Tudo certo?</p> - <p className="text-base text-darkGray-HC-white tracking-tight text-justify"> - Ao terminar de ler sobre a Plataforma MEC RED você pode clicar no - botão abaixo para continuar navegando e explorar as ferramentas - disponíveis. - </p> - - <Button - href="/busca?page=LearningObject" - className="bg-turquoise-HC-white mt-2 text-xl text-white-HC-dark-underline py-4 w-full text-center rounded-lg hover:bg-darkTurquoise-HC-dark hover:text-white font-bold normal-case outline outline-1 outline-white" - > - Continuar - </Button> - </div> - </div> </> ); } diff --git a/src/app/components/AcessibilityBar.js b/src/app/components/AcessibilityBar.js index 6c6ffd337a3e355d643021226d07ca0914899bd9..28a87386606a0660e6aad42d144066b5bbf986cf 100644 --- a/src/app/components/AcessibilityBar.js +++ b/src/app/components/AcessibilityBar.js @@ -147,7 +147,7 @@ export default function AcessibilityBar() { <ContrastTwoToneIcon className="text-3xl pb-1" /> </button> - <h1 className="mt-1 text-start" id="MECRED"> + <h1 className="mt-1 font-light text-start" id="MECRED"> MEC RED - A Rede Social da Educação </h1> </div> @@ -162,29 +162,29 @@ export default function AcessibilityBar() { <div className="flex justify-between w-full max-sm:hidden"> - <h1 className="mt-1 text-start" id="MECRED"> + <h1 className="mt-1 font-light text-start" id="MECRED"> MEC RED - A Rede Social da Educação </h1> - <button id="acessibilidade1" onClick={() => handleAccessibility(1)}> + <button className='font-light' id="acessibilidade1" onClick={() => handleAccessibility(1)}> 1- Ir para o conteúdo. </button> - <button onClick={() => handleAccessibility(2)}> + <button className='font-light' onClick={() => handleAccessibility(2)}> 2- Ir para o menu. </button> - <button onClick={() => handleAccessibility(3)}> + <button className='font-light' onClick={() => handleAccessibility(3)}> 3- Ir para a busca. </button> {!loggedIn && - <button onClick={() => router.push("/entrar")}> + <button className='font-light' onClick={() => router.push("/entrar")}> 4- Ir para login. </button> } - <div className="flex py-1"> + <div className="font-light flex py-1"> <button>Tamanho do texto: </button> <button onClick={() => changeFont("decrease")}>A-</button> @@ -193,12 +193,12 @@ export default function AcessibilityBar() { <button onClick={() => changeFont("increase")}>A+</button> </div> - <button onClick={() => toggleContrast()}> + <button className='font-light' onClick={() => toggleContrast()}> Alto Contraste <ContrastTwoToneIcon - className="text-m pb-1" /> + className="text-m font-light pb-1" /> </button> - <button onClick={() => router.push("/acessibilidade")}> + <button className='font-light' onClick={() => router.push("/acessibilidade")}> Acessibilidade </button> @@ -215,35 +215,35 @@ export default function AcessibilityBar() { <div className="fixed top-0 flex justify-between w-screen bg-white-HC-dark z-20 text-[14px] py-1 px-3 text-darkGray-HC-white whitespace-nowrap border-b border-ice-HC-white"> <div className="flex justify-between w-full leading-tight"> - <h1 className="mt-1 text-start" id="MECRED"> + <h1 className="mt-1 font-light text-start" id="MECRED"> MEC RED - A Rede Social da Educação </h1> - <button id="acessibilidade1" onClick={() => handleAccessibility(1)}> + <button className='font-light' id="acessibilidade1" onClick={() => handleAccessibility(1)}> 1- Ir para o conteúdo. </button> {!loggedIn && - <button onClick={() => router.push("/entrar")}> + <button className='font-light' onClick={() => router.push("/entrar")}> 2- Ir para login. </button> } - <div className="flex items-center space-x-10"> + <div className="flex font-light items-center space-x-10"> <div className="flex"> <button>Tamanho do texto: </button> - <button onClick={() => changeFont("decrease")}>A-</button> + <button className='font-light' onClick={() => changeFont("decrease")}>A-</button> - <button onClick={() => changeFont("default")}>A</button> + <button className='font-light' onClick={() => changeFont("default")}>A</button> - <button onClick={() => changeFont("increase")}>A+</button> + <button className='font-light' onClick={() => changeFont("increase")}>A+</button> </div> - <button onClick={() => toggleContrast()}> + <button className='font-light' onClick={() => toggleContrast()}> Alto Contraste <ContrastTwoToneIcon className="text-m pb-1" /> </button> - <button onClick={() => router.push("/acessibilidade")}> + <button className='font-light' onClick={() => router.push("/acessibilidade")}> Acessibilidade </button> diff --git a/src/app/components/Cards.js b/src/app/components/Cards.js index 6b57b12e3d27fd5f82dea23021be7d4db5fcdb0c..8f4ac7e72a60ae143a3318149953933bc0c00e80 100644 --- a/src/app/components/Cards.js +++ b/src/app/components/Cards.js @@ -63,6 +63,7 @@ export default function Cards(props) { return thumbnail_url; }; + /** * * @param {String} updated_time @@ -90,19 +91,15 @@ export default function Cards(props) { function getRandomBg(id) { const colors = [ - "bg-turquoise", - "bg-orange", - "bg-turquoise-hover", - "bg-darkOrange-HC-gray ", - "bg-violet", - "bg-pink", - "bg-red", - "bg-darkGray-HC-white", - "bg-darkGray-HC-white-click", - "bg-ice-HC-dark ", + "bg-turquoise-HC-white", + "bg-orange-HC-white", + "bg-darkTurquoise-HC-white", + "bg-darkOrange-HC-white ", + "bg-violet-HC-white", + "bg-pink-HC-white", + "bg-red-HC-white", "bg-darkGray-HC-white", - "bg-darkGray-HC-white", - "bg-turquoise-HC-dark", + "bg-ice-HC-white", ] return colors[id % colors.length]; @@ -122,7 +119,6 @@ export default function Cards(props) { component={Link} href={`/recurso/${props["id"]}` + (props.collectionSource ? `?collectionId=${props.collectionSource}` : "")} > - <CardMedia id="conteudo" tabIndex="0" @@ -133,9 +129,9 @@ export default function Cards(props) { }} component="img" image={ - props["image"] === null - ? getDefaultThumbnail(props["type"]) - : mecredURL + props["image"] + props.image === null + ? getDefaultThumbnail(props.type) + : props.image } alt="imagem" title={props.title} @@ -166,7 +162,7 @@ export default function Cards(props) { {props?.noAvatar || !props["avatar"] ? <div className={`flex items-center shrink-0 justify-center text-xl font-bold ml-1 text-ice-HC-dark rounded-full h-[33px] w-[33px] ${getRandomBg(props["id"])}`} >{props["author"][0]}</div> : <img - src={mecredURL + props["avatar"]} + src="https://s3.c3sl.ufpr.br/mecredteste/avatar/1" alt={props["author"]} className="w-[33px] h-[33px] object-cover rounded-full" diff --git a/src/app/components/DownloadButton.js b/src/app/components/DownloadButton.js index c2f4403e239599abc43d48c20e7e8bd56374681d..03d3406f8e7aa9501aed7ad0accf72f0ed8e7fa7 100644 --- a/src/app/components/DownloadButton.js +++ b/src/app/components/DownloadButton.js @@ -1,6 +1,6 @@ import * as React from 'react'; import DownloadOutlinedIcon from '@mui/icons-material/Download'; -import { mecredURL, mecredURLv1 } from '@/axiosConfig'; +import mecredApi, { mecredURL, mecredURLv1 } from '@/axiosConfig'; /** * Responsável pelo Download dos recursos de uma coleção @@ -10,25 +10,34 @@ import { mecredURL, mecredURLv1 } from '@/axiosConfig'; */ export default function DownloadButton({ id, objects }) { - const handleDownloadCollection = (e) => { - e.preventDefault(); - let zip = false; - - alert("Caso esta coleção contenha links externos, eles serão abertos em novas abas.\n Talvez seja preciso permitir a abertura de várias abas nas opções do seu navegador!"); - objects.forEach(async (object) => { - if (object.collectionable.link !== null) { - let url = mecredURLv1 + `/learning_objects/${object.collectionable.id}/download`; - window.open(url, '_blank'); - } else { - zip = true; - } - }); - - if (zip) { - window.location = mecredURL + `zipper/${id}`; + const handleDownloadCollection = async (e) => { + e.preventDefault(); + + try { + const response = await mecredApi.get( + `/public/collections/${id}/download`, + { responseType: "blob" } // importante para baixar arquivos + ); + + const url = window.URL.createObjectURL(response.data); + const a = document.createElement("a"); + a.href = url; + a.download = `collection-${id}.zip`; // ou outro nome apropriado + a.click(); + window.URL.revokeObjectURL(url); + + } catch (error) { + if (error.response?.data?.message) { + alert(error.response.data.message); // substitua por toast/modal se preferir + } else { + alert("Erro ao baixar a coleção."); + } + console.error(error); } - }; + }; + + return ( <button diff --git a/src/app/components/FiltersModal.js b/src/app/components/FiltersModal.js index c9d23a3fd0968b491743be5c3241cead619b6eb8..deb92008225133e335b816cb1a61d3563fc134c3 100644 --- a/src/app/components/FiltersModal.js +++ b/src/app/components/FiltersModal.js @@ -49,7 +49,7 @@ export default function FiltersModal({ <p className=' text-2xl font-bold text-darkGray-HC-white '> Filtros de Pesquisa </p> - <CloseIcon onClick={handleClose} sx={{ color: "#6c8080", fontSize: "35px" }} /> + <CloseIcon className="cursor-pointer" onClick={handleClose} sx={{ color: "#6c8080", fontSize: "35px" }} /> </div> </div> <div className='p-6'> @@ -80,4 +80,4 @@ export default function FiltersModal({ </div> </div> ); -} \ No newline at end of file +} diff --git a/src/app/components/FormFilters.js b/src/app/components/FormFilters.js index b6cead337494e3bc28db1bfb86476bdbe1e692db..616ecb66fbb3d73a1d7ae9549e671af380c43bd9 100644 --- a/src/app/components/FormFilters.js +++ b/src/app/components/FormFilters.js @@ -162,9 +162,10 @@ export default function FormFilters({ return ( <> <form className="mt-12" onSubmit={handleSubmit} onKeyDown={(e) => { if (e.key === "Enter") e.preventDefault() }}> - <Divider /> - <ButtonsPages searchPage={filterStateDraft.searchClass} handlePageChange={handlePageChange} /> - <Divider /> + {/* Deixar isso comentado enquanto não podemos filtrar por coleções e usuários */} + {/* <Divider /> */} + {/* <ButtonsPages searchPage={filterStateDraft.searchClass} handlePageChange={handlePageChange} /> */} + {/* <Divider /> */} <p className="font-bold text-darkGray-HC-white text-xl py-2"> Tipo de recurso @@ -262,11 +263,11 @@ export default function FormFilters({ <div className="fixed bottom-[10%] z-20 bg-white-HC-dark p-4 w-[56%] flex justify-end"> <div className="flex"> <Button onClick={handleResetFilters} className="text-darkGray-HC-white-underline normal-case font-semibold text-base hover:bg-ice-HC-dark cursor-pointer mx-2 outline outline-1 outline-ice-HC-white">Remover filtros</Button> - <Button type="submit" className="bg-turquoise-HC-white hover:bg-darkTurquoise-HC-dark text-white-HC-dark-underline hover:text-white normal-case font-semibold text-base hover:bg-turquoise-hover cursor-pointer outline outline-1 outline-ice-HC-white">Mostrar resultados</Button> + <Button type="submit" className="bg-turquoise-HC-white hover:bg-darkTurquoise-HC-dark text-white-HC-dark-underline hover:text-white normal-case font-semibold text-base cursor-pointer outline outline-1 outline-ice-HC-white">Mostrar resultados</Button> </div> </div> </form> </> ) -} \ No newline at end of file +} diff --git a/src/app/components/GroupCardsCollections.js b/src/app/components/GroupCardsCollections.js index a76a601604486ec21f9d1a141c2ef999bd53c017..da03df706ccc22ed44bce5bbac78f4ab0608f208 100644 --- a/src/app/components/GroupCardsCollections.js +++ b/src/app/components/GroupCardsCollections.js @@ -2,6 +2,8 @@ import { useEffect, useState } from "react"; import Cards from "./Cards"; import { useRouter } from "next/navigation" +import mecredApi from "@/axiosConfig"; +import { authHeaders } from "../handlers/loginHandler"; /** * Retorna na tela uma coleção * @param {Array.<Object>} data - recursos da coleção @@ -10,9 +12,10 @@ import { useRouter } from "next/navigation" export default function GroupCardsCollections({ data, cardsPerRow, collectionId }) { const [expanded, setExpanded] = useState(false); const [showButton, setShowButton] = useState(false); + const [resources, setResources] = useState(null) const router = useRouter() - - console.log(data) + const [totalCount, setTotalCount] = useState(0) + const [got, setGot] = useState(false) const handleResize = (data) => { setShowButton(data?.length > cardsPerRow); @@ -26,24 +29,56 @@ export default function GroupCardsCollections({ data, cardsPerRow, collectionId handleResize(data); }), [cardsPerRow]; + useEffect(() => { + const fetchResources = async () => { + // if (idLogin === id) { + + await mecredApi + .get(`public/collection-resources/${collectionId}/resources`, { + headers: authHeaders(), + }) + /** + * Além de setar as coleções, indica o número total de coleções + * Isso facilita na verificação + */ + .then(({ data, headers }) => { + setTotalCount(headers["x-total-count"]) + setResources(data) + + setGot(true) + }); + // } else { + // await mecredApi + // .get(`public/collections/${id}/collections`) + // .then(({ data, headers }) => { + // setTotalCount(headers["x-total-count"]) + // setCollections(data) + // console.log(data) + // setGot(true) + // }); + // } + }; + fetchResources(collectionId); + }, []); + return ( <div className="flex flex-col"> <div className="mx-1 flex flex-col"> <div id="contentSize" className={`flex content flex-wrap max-sm:justify-center mb-4 max-sm:ml-0 md:ml-0 ${expanded ? "" : "overflow-y-hidden h-[270px]"}`}> - {data?.length !== 0 ? data?.sort((a,b) => a.position - b.position).map((item, index) => { + {resources?.length !== 0 ? resources?.sort((a,b) => a.position - b.position).map((item, index) => { return ( <Cards collectionSource={collectionId} key={index} - id={item['collectionable']['id']} - title={item["collectionable"]["name"]} - author={item["collectionable"]["publisher"]["name"]} - authorId={item["collectionable"]["publisher"]["id"]} - avatar={item["collectionable"]["publisher"]["avatar"]} - image={item["collectionable"]["thumbnail"]} - updated_at={item["collectionable"]["updated_at"]} + id={item.resources.id} + title={item.resources.name} + author={item.resources.author} + authorId={item.resources.user_id} + avatar={`https://s3.c3sl.ufpr.br/mecredteste/avatar/${item.resources.user_id}`} + image={`https://s3.c3sl.ufpr.br/mecredteste/thumbnail/resource/${item.resources.id}`} + updated_at={item.resources.updated_at} /> ); }) diff --git a/src/app/components/Header.js b/src/app/components/Header.js index 7ae1eaf4445ff27a41c6c3017139531c9dc3009f..6d736958ef563f68da2119dcb52bf87f2badc925 100644 --- a/src/app/components/Header.js +++ b/src/app/components/Header.js @@ -98,17 +98,17 @@ function DefaultContent({ <> <Notifications /> - <p className="max-md:hidden"><AccountMenu /></p> + <div className="max-md:hidden"><AccountMenu /></div> </> - ) : ( + ) : ( <button type="button" - className="group bg-orange-HC-white hover:bg-darkOrange-HC-dark px-4 h-10 mr-14 max-sm:ml-2 rounded text-white-HC-dark-underline flex items-center font-bold flex-shrink-0 hover:text-white-HC-underline outline outline-1 outline-ice-HC-white" + className="group bg-orange-HC-white hover:bg-darkOrange-HC-dark px-4 h-10 mr-8 max-sm:ml-2 rounded text-white-HC-dark-underline flex items-center font-bold flex-shrink-0 hover:text-white-HC-underline outline outline-1 outline-ice-HC-white" onClick={loginBarrier} > Entrar </button> - )} + )} </div> </div> diff --git a/src/app/components/ImageCropper.js b/src/app/components/ImageCropper.js index 2dbe5447dcb352e1ee888f46dfb958cc01d41e33..5c0efe75c80292fe98f91b85109f4742c7cadb22 100644 --- a/src/app/components/ImageCropper.js +++ b/src/app/components/ImageCropper.js @@ -4,182 +4,236 @@ import "react-image-crop/dist/ReactCrop.css"; import { canvasPreview } from "./canvasPreview"; import { getStoredValue, saveToLocalStorage } from "@/app/handlers/localStorageHandler"; import mecredApi from "@/axiosConfig"; +import { Modal } from "@mui/material"; +import { authHeaders } from "../handlers/loginHandler"; +import { useRouter } from "next/navigation" -export default function ImageCropper({ payloadHeader, type, userId, setChangePhoto }) { - // Estados para gerenciar a foto original, URL da foto, configuração do corte, corte completo e imagem cortada - const [photo, setPhoto] = useState(null); - const [photoURL, setPhotoURL] = useState(null); - const [crop, setCrop] = useState(null); - const [completedCrop, setCompletedCrop] = useState(false); - const [croppedImage, setCroppedImage] = useState(null); +export default function ImageCropper({ userId, setChangePhoto }) { + // Estados para gerenciar a foto original, URL da foto, configuração do corte, corte completo e imagem cortada + const [photo, setPhoto] = useState(null); + const [photoURL, setPhotoURL] = useState(null); + const [crop, setCrop] = useState(null); + const [completedCrop, setCompletedCrop] = useState(false); + const [croppedImage, setCroppedImage] = useState(null); + const [sucessOpen, setSucessOpen] = useState(false) + const [notSucessOpen, setNotSucessOpen] = useState(false) + const router = useRouter() - // Referências para a imagem e o canvas de pré-visualização - const imgRef = useRef(null); - const previewCanvasRef = useRef(null); + // Referências para a imagem e o canvas de pré-visualização + const imgRef = useRef(null); + const previewCanvasRef = useRef(null); + // Hook personalizado para aplicar debounce em efeitos + function useDebounceEffect(fn, waitTime, deps = []) { + useEffect(() => { + const t = setTimeout(() => { + fn.apply(undefined, deps); + }, waitTime); - // Recupera tokens de autenticação do armazenamento local - const token = getStoredValue("access_token"); - const client = getStoredValue("client"); - const uid = getStoredValue("uid"); + return () => { + clearTimeout(t); + }; + }, deps); + } - // Hook personalizado para aplicar debounce em efeitos - function useDebounceEffect(fn, waitTime, deps = []) { - useEffect(() => { - const t = setTimeout(() => { - fn.apply(undefined, deps); - }, waitTime); - - return () => { - clearTimeout(t); - }; - }, deps); - } + // Função para fazer upload da foto cortada + const uploadPhoto = async () => { + try { + let payload = new FormData(); + payload.set('file', croppedImage); + payload.set('id_user', String(userId)); + payload.set('content_type', croppedImage.type); // tipo MIME do arquivo (image/png, image/jpeg etc) - // Função para fazer upload da foto cortada - const uploadPhoto = async () => { - let payload = new FormData(); - payload.set(payloadHeader, croppedImage); - - await mecredApi.put(`/${type}/${userId}`, payload, { - headers: { - 'access-token': token, - 'token-type': 'Bearer', - 'client': client, - 'uid': uid, - 'Expires': 0 - } - }) - .catch(error => { - setChangePhoto(false); - if (error?.response.status === 500) // TODO: alterar isso quando tivermos um novo backend, pois não deveria retornar 500 toda vez. - console.error(error); // Talvez o backend tenha falhado, mas provavelmente a foto do perfil foi alterada. - }); - - await mecredApi.get(`/users/${userId}`, { - headers: { - 'access-token': token, - 'token-type': 'Bearer', - 'client': client, - 'uid': uid, - 'Expires': 0 - } - }) - .then(res => { - let userData = JSON.parse(getStoredValue("user_data")); - userData["avatar_file_name"] = res.data.avatar; - saveToLocalStorage("user_data", JSON.stringify(userData)); - }); - }; - - // Manipulador para quando o usuário seleciona uma foto - const handlePhoto = (e) => { - e.preventDefault(); - const file = e.target.files[0]; - if (file) { - setPhoto(file); - setPhotoURL(URL.createObjectURL(file)); - } - }; + const response = await mecredApi.post(`api/s3/upload/avatar`, payload, { + headers: authHeaders() + }); - // Função para centralizar o corte com uma proporção específica - function centerAspectCrop(mediaWidth, mediaHeight, aspect) { - return centerCrop( - makeAspectCrop( - { unit: "%", width: 50 }, - aspect, - mediaWidth, - mediaHeight - ), - mediaWidth, - mediaHeight - ); - } + console.log("Foto enviada com sucesso:", response.data); + setSucessOpen(true) - // Função chamada quando a imagem é carregada - function onImageLoad(e) { - const { width, height } = e.currentTarget; - const newCrop = centerAspectCrop(width, height, 1); - setCrop(newCrop); - setCompletedCrop(convertToPixelCrop(newCrop, width, height)); + } catch (error) { + setNotSucessOpen(true) + console.error("Erro ao enviar foto:", error); + } + }; + // Manipulador para quando o usuário seleciona uma foto + const handlePhoto = (e) => { + e.preventDefault(); + const file = e.target.files[0]; + if (file) { + setPhoto(file); + setPhotoURL(URL.createObjectURL(file)); } + }; - // Efeito com debounce para gerar a pré-visualização da imagem cortada - useDebounceEffect( - () => { - if ( - completedCrop?.width && - completedCrop?.height && - imgRef.current && - previewCanvasRef.current - ) { - // Gera a pré-visualização no canvas - canvasPreview( - imgRef.current, - previewCanvasRef.current, - completedCrop, - 1, - 0 - ); - // Converte o conteúdo do canvas em um blob e atualiza o estado - previewCanvasRef.current.toBlob((blob) => { - console.log("meu blob: ", blob); - setCroppedImage(blob); - }); - } - }, - 100, - [completedCrop] + // Função para centralizar o corte com uma proporção específica + function centerAspectCrop(mediaWidth, mediaHeight, aspect) { + return centerCrop( + makeAspectCrop( + { unit: "%", width: 50 }, + aspect, + mediaWidth, + mediaHeight + ), + mediaWidth, + mediaHeight ); + } + + // Função chamada quando a imagem é carregada + function onImageLoad(e) { + const { width, height } = e.currentTarget; + const newCrop = centerAspectCrop(width, height, 1); + setCrop(newCrop); + setCompletedCrop(convertToPixelCrop(newCrop, width, height)); + } + + // Efeito com debounce para gerar a pré-visualização da imagem cortada + useDebounceEffect( + () => { + if ( + completedCrop?.width && + completedCrop?.height && + imgRef.current && + previewCanvasRef.current + ) { + // Gera a pré-visualização no canvas + canvasPreview( + imgRef.current, + previewCanvasRef.current, + completedCrop, + 1, + 0 + ); + // Converte o conteúdo do canvas em um blob e atualiza o estado + previewCanvasRef.current.toBlob((blob) => { + console.log("meu blob: ", blob); + setCroppedImage(blob); + }); + } + }, + 100, + [completedCrop] + ); + const ModalSucess = ({ open, onClose }) => { return ( - <div className="flex flex-col items-center"> - <div className="flex space-x-4 mt-2 mb-5"> - <label className="bg-turquoise text-white-HC-dark-underline rounded-lg p-2 cursor-pointer"> - <input type="file" onChange={handlePhoto} className="hidden" /> - Selecionar Nova Foto - </label> - {completedCrop && ( - <button - className="text-sm p-2 text-white-HC-dark-underline border-main rounded-lg font-bold bg-turquoise hover:bg-turquoise-hover" - onClick={uploadPhoto} - > - Enviar - </button> - )} + <Modal open={open} onClose={onClose} className="grid place-items-center" slotProps={{ + backdrop: { + sx: { + backgroundColor: "rgba(0, 0, 0, 0.3)", // Ajuste a opacidade conforme necessário + }, + }, + }}> + <div className="flex flex-col justify-center bg-ice-HC-dark p-5 rounded"> + <p className="text-xl justify-center flex text-darkGray-HC-white-underline mb-2">Foto editada com sucesso!</p> + <div className="flex flex-row mt-2"> + + <button + className=" text-sm p-2 mr-1 text-white-HC-dark-underline border-main rounded-lg normal-case h-9 font-bold bg-turquoise hover:bg-turquoise-hover" + onClick={() => { + setChangePhoto(false); + router.push(`/perfil/${userId}`); + }} + > + Voltar para perfil + </button> + <button + className=" text-sm p-2 ml-1 text-darkGray-HC-white-underline border-main rounded-lg normal-case h-9 font-bold bg-ice-HC-dark hover:bg-ice-HC-dark-hover" + onClick={() => {onClose(); setChangePhoto(false)}} + > + Continuar editando + </button> + </div> + </div> + </Modal> + ) + } + + const ModalNotSucess = ({ open, onClose }) => { + return ( + <Modal open={open} onClose={onClose} className="grid place-items-center" slotProps={{ + backdrop: { + sx: { + backgroundColor: "rgba(0, 0, 0, 0.3)", // Ajuste a opacidade conforme necessário + }, + }, + }}> + <div className="flex flex-col justify-center bg-ice-HC-dark p-5 rounded"> + <p className="text-xl justify-center flex text-darkGray-HC-white-underline mb-2">Não foi possível alterar a foto</p> + <div className="flex flex-row mt-2"> + + <button + className=" text-sm p-2 mr-1 text-white-HC-dark-underline border-main rounded-lg normal-case h-9 font-bold bg-turquoise hover:bg-turquoise-hover" + onClick={() => { + setChangePhoto(false); + router.push(`/perfil/${userId}`); + }} + > + Voltar para perfil + </button> + <button + className=" text-sm p-2 ml-1 text-darkGray-HC-white-underline border-main rounded-lg normal-case h-9 font-bold bg-ice-HC-dark hover:bg-ice-HC-dark-hover" + onClick={() => {onClose(); setChangePhoto(false)}} + > + Continuar editando + </button> + </div> + </div> + </Modal> + ) + } + + return ( + <div className="flex flex-col items-center"> + <ModalNotSucess open={notSucessOpen} onClose={() => { setNotSucessOpen(false) }} /> + <ModalSucess open={sucessOpen} onClose={() => { setSucessOpen(false) }} /> + <div className="flex space-x-4 mt-2 mb-5"> + <label className="bg-turquoise text-white-HC-dark-underline rounded-lg p-2 cursor-pointer"> + <input type="file" onChange={handlePhoto} className="hidden" /> + Selecionar Nova Foto + </label> + {completedCrop && ( + <button + className="text-sm p-2 text-white-HC-dark-underline border-main rounded-lg font-bold bg-turquoise hover:bg-turquoise-hover" + onClick={uploadPhoto} + > + Enviar + </button> + )} + </div> + {photoURL && ( + <div className="flex space-x-4"> + <ReactCrop + crop={crop} + onChange={(_, percentCrop) => setCrop(percentCrop)} + onComplete={(c) => setCompletedCrop(c)} + aspect={1} + circularCrop={true} + > + <img + ref={imgRef} + alt="Imagem de Perfil" + src={photoURL} + onLoad={onImageLoad} + style={{ maxWidth: '400px', maxHeight: '400px' }} + /> + </ReactCrop> + {completedCrop && ( + <div className="flex justify-center items-center"> + <canvas + ref={previewCanvasRef} + style={{ + borderRadius: "50%", + border: "2px solid black", + objectFit: "contain", + width: Math.min(completedCrop.width, 200), + height: Math.min(completedCrop.height, 200), + }} + /> </div> - {photoURL && ( - <div className="flex space-x-4"> - <ReactCrop - crop={crop} - onChange={(_, percentCrop) => setCrop(percentCrop)} - onComplete={(c) => setCompletedCrop(c)} - aspect={1} - circularCrop={true} - > - <img - ref={imgRef} - alt="Imagem de Perfil" - src={photoURL} - onLoad={onImageLoad} - style={{ maxWidth: '400px', maxHeight: '400px' }} - /> - </ReactCrop> - {completedCrop && ( - <div className="flex justify-center items-center"> - <canvas - ref={previewCanvasRef} - style={{ - borderRadius: "50%", - border: "2px solid black", - objectFit: "contain", - width: Math.min(completedCrop.width, 200), - height: Math.min(completedCrop.height, 200), - }} - /> - </div> - )} - </div> - )} + )} </div> - ); + )} + </div> + ); } diff --git a/src/app/components/ItemNotification.js b/src/app/components/ItemNotification.js index e865af544e216fcf382f37865d57ef31ef6df988..d2c669ae88b605b9962608738b441f4074470d3f 100644 --- a/src/app/components/ItemNotification.js +++ b/src/app/components/ItemNotification.js @@ -1,7 +1,8 @@ -import { mecredURL } from "@/axiosConfig"; +import mecredApi, { mecredURL } from "@/axiosConfig"; import Image from "next/image"; import { useRouter } from "next/navigation"; - +import { useEffect, useState } from "react"; +import { authHeaders } from "../handlers/loginHandler"; const timeFunction = (updated_time) => { let data = new Date(updated_time) @@ -23,19 +24,15 @@ const timeFunction = (updated_time) => { function getRandomBg(id) { const colors = [ - "bg-turquoise", - "bg-orange", - "bg-turquoise-hover", - "bg-darkOrange-HC-gray ", - "bg-violet", - "bg-pink", - "bg-red", - "bg-darkGray-HC-white", - "bg-darkGray-HC-white-click", - "bg-ice-HC-dark ", + "bg-turquoise-HC-white", + "bg-orange-HC-white", + "bg-darkTurquoise-HC-white", + "bg-darkOrange-HC-white", + "bg-violet-HC-white", + "bg-pink-HC-white", + "bg-red-HC-white", "bg-darkGray-HC-white", - "bg-darkGray-HC-white", - "bg-turquoise-HC-dark", + "bg-ice-HC-white", ] return colors[id % colors.length]; @@ -44,17 +41,15 @@ function getRandomBg(id) { function tradutor(nome) { switch (nome) { case "like.create": - return "curtiu" - case "like.destroy": - return "descurtiu" + return "curtiu " case "download.create": - return "baixou" + return "baixou " case "review.create": - return "avaliou" + return "avaliou " case "curator_assignment.create": return "você foi atribuido para avaliar " case "submission.rejected": - return "sua submissão foi rejeitada pela equipe de avaliadores." + return "sua submissão foi rejeitada pela equipe de avaliadores. " case "submission.accepted": return "sua submissão foi aceita pela equipe de avaliadores: " @@ -77,18 +72,34 @@ export default function ItemNotification({ notification, postViewNotification }) postViewNotification(payload) - router.push(`recurso/${notification.recipient?.id}`) + router.push(`/recurso/${notification.recipient?.id}`) } + const [imageExists, setImageExists] = useState(false); + const imageUrl = `https://s3.c3sl.ufpr.br/mecredteste/avatar/${notification.owner_id}`; + + useEffect(() => { + const checkImage = async () => { + await mecredApi.get(`public/s3/get/avatar/${notification.owner_id}`, { + headers: authHeaders() + }) + .then(({ headers }) => setImageExists(true)) + .catch((error) => { + setImageExists(false) + }) + }; + + checkImage(); + }, [notification.owner_id]); return ( <div className="flex flex-row px-3 py-4 mt-1 ml-2 hover:bg-ice-HC-dark hover:rounded-lg" onClick={viewOneNotification} > <div className="pr-3 pl-1 shrink-0 flex items-center"> - {!notification.owner?.avatar ? <div className={`flex items-center justify-center text-xl font-bold text-ice-HC-dark rounded-full h-[43px] w-[43px] ${getRandomBg(notification.owner.id)}`} >{notification.owner.name[0]}</div> + {!imageExists ? <div className={`flex items-center justify-center text-xl font-bold text-ice-HC-dark rounded-full h-[43px] w-[43px] ${getRandomBg(notification.owner_id)}`} >{notification.owner_name[0]}</div> : <Image - src={mecredURL + notification.owner.avatar} - alt={notification.owner.name} + src={imageUrl} + alt={notification.owner_name} width={43} height={43} className="w-[43px] h-[43px] object-cover rounded-full" @@ -98,16 +109,16 @@ export default function ItemNotification({ notification, postViewNotification }) <div> <p className="text-sm font-bold text-darkGray-HC-white line-clamp-1"> - {notification.owner.name} + {notification.actor_name} </p> <p className="text-sm font-normal text-darkGray-HC-white line-clamp-2 "> - {tradutor(notification.activity)} - <a className="text-turquoise-HC-underline -hover" href={`recurso/${notification.recipient?.id}`} > + {tradutor(notification.action_name)} + <a className="text-turquoise-HC-underline -hover" href={`/recurso/${notification.recipient?.id}`} > {notification.recipient?.name} </a> </p> <p className="text-sm font-light text-darkGray-HC-white "> - {timeFunction(notification.created_at)} + {timeFunction(notification.createdAt)} </p> </div> </div> diff --git a/src/app/components/MenuProfile.js b/src/app/components/MenuProfile.js index 423b6068e5dfb1a4d575c8c651cef34863591ef7..ecf44986c27ac926ea946a8691fa5bb933320fe8 100644 --- a/src/app/components/MenuProfile.js +++ b/src/app/components/MenuProfile.js @@ -56,19 +56,15 @@ const items = [ function getRandomBg(id) { const colors = [ - "bg-turquoise", - "bg-orange", - "bg-turquoise-hover", - "bg-darkOrange-HC-gray ", - "bg-violet", - "bg-pink", - "bg-red", + "bg-turquoise-HC-white", + "bg-orange-HC-white", + "bg-darkTurquoise-HC-white", + "bg-darkOrange-HC-white ", + "bg-violet-HC-white", + "bg-pink-HC-white", + "bg-red-HC-white", "bg-darkGray-HC-white", - "bg-darkGray-HC-white-click", - "bg-ice-HC-dark ", - "bg-darkGray-HC-white", - "bg-darkGray-HC-white", - "bg-turquoise-HC-dark", + "bg-ice-HC-white", ] return colors[id % colors.length]; diff --git a/src/app/components/ModalNotifications.js b/src/app/components/ModalNotifications.js index 84c12fb7be09256ce0d8881c0d30ab118f9b80f1..3040b9d0ff5a835435f25de94a30db119747605b 100644 --- a/src/app/components/ModalNotifications.js +++ b/src/app/components/ModalNotifications.js @@ -8,10 +8,6 @@ import Image from 'next/image'; import Loading from './Loading'; import ItemNotification from './ItemNotification'; - - - - export default function ModalNotifications({ countNotifications, notifications, postViewNotification }) { const [anchorEl, setAnchorEl] = useState(null); @@ -25,12 +21,15 @@ export default function ModalNotifications({ countNotifications, notifications, const setViewdAllNotification = () => { const payload = { - "activities": { - "ids": [] + activities: { + ids: notifications.map((noti) => noti.id), + viewed: true // <-- necessário pro Zod validar! } - } + }; notifications.forEach((noti) => payload.activities.ids.push(noti.id)); + + console.log(payload) postViewNotification(payload) } @@ -81,7 +80,7 @@ export default function ModalNotifications({ countNotifications, notifications, <div className='flex pr-2' > <div className='text-lg py-3 font-bold text-darkGray-HC-white pl-6 pr-16'> Notificações </div> <button className='text-darkGray-HC-white-underline text-sm bg-mediumGray-HC-dark rounded-xl px-2 h-10 mt-1 mr-1 hover:bg-mediumGray-HC-white hover:text-darkGray-HC-dark-underline outline outline-1 outline-ice-HC-white' onClick={setViewdAllNotification}> Marcar como lidas </button> - </div>t + </div> <div className='px-4'> <hr className='border-mediumGray-HC-white' /> </div> diff --git a/src/app/components/NavigationBar.js b/src/app/components/NavigationBar.js index 47b0a79420fb99942ff5e708b558846cb7545be9..5572ab9e7e41b660b796813d457a79aed2924589 100644 --- a/src/app/components/NavigationBar.js +++ b/src/app/components/NavigationBar.js @@ -1,7 +1,17 @@ -import * as React from 'react'; -import { useState, useEffect } from 'react'; -import NeedLoginModal from './needLoginModal'; +"use client"; + +import Link from "next/link"; +import { useEffect, useState } from "react"; +import { usePathname, useSearchParams } from "next/navigation"; + +import NeedLoginModal from "./needLoginModal"; import { isLoggedIn } from "../handlers/loginHandler"; +import { + getStoredValue, + removeFromLocalStorage, +} from "../handlers/localStorageHandler"; + +// Ícones import FileUploadIcon from '@mui/icons-material/FileUpload'; import CollectionsBookmarkIcon from "@mui/icons-material/CollectionsBookmark"; import SubjectIcon from "@mui/icons-material/Subject"; @@ -11,108 +21,136 @@ import HelpIcon from "@mui/icons-material/Help"; import VerifiedIcon from "@mui/icons-material/Verified"; import { Person } from "@mui/icons-material"; import SearchIcon from '@mui/icons-material/Search'; -import { usePathname, useRouter, useSearchParams } from "next/navigation"; -import { - getStoredValue, - removeFromLocalStorage, - } from "../handlers/localStorageHandler"; - - -export default function NavigationBar({ mobileSearch}) { - - const [needLoginOpen, setNeedLoginOpen] = useState(false); - const pathname = usePathname(); - let searchParams = useSearchParams(); - const page = searchParams.get('page'); - const [id, setId] = useState(null); - - useEffect(() => { - if (isLoggedIn()) { - let data = JSON.parse(getStoredValue("user_data")); - setId(data["id"]); - } - }, []); - - const handleOpenLoggin = (e) => { - - if (!isLoggedIn()) { - e.preventDefault(); - setNeedLoginOpen(true); - } - }; - - const handleLogout = () => { - removeFromLocalStorage("access_token"); - removeFromLocalStorage("user_data"); - removeFromLocalStorage("uid"); - removeFromLocalStorage("expiry"); - removeFromLocalStorage("token-type"); - removeFromLocalStorage("client"); - window.location.reload(); - }; +/** + * @param {Object} props + * @param {Function} props.mobileSearch + */ +const navItems = [ + { label: "Pesquisar", href: "#", icon: SearchIcon }, + { label: "perfil", href: "/perfil", icon: Person }, + { label: "Coleções", href: "Collection", icon: CollectionsBookmarkIcon }, + { label: "Recursos", href: "LearningObject", icon: SubjectIcon }, + { label: "Sobre", href: "/sobre", icon: HelpIcon }, + { label: "MEC", href: "MEC", icon: VerifiedIcon }, + { label: "Publicar", href: "/publicar", icon: FileUploadIcon }, + { label: "Contato", href: "/contato", icon: EmailRoundedIcon }, + { label: "Sair", href: "/logout", icon: LogoutRounded }, +]; + +export default function NavigationBar({ mobileSearch }) { + const [id, setId] = useState(null); + const [needLoginOpen, setNeedLoginOpen] = useState(false); + const [loggedIn, setLoggedIn] = useState(false); + + const pathname = usePathname(); + const searchParams = useSearchParams(); + const page = searchParams.get('page'); + + useEffect(() => { + if (isLoggedIn()) { + const userData = getStoredValue("user_data"); + setLoggedIn(true); + if (userData) { + const data = JSON.parse(userData); + setId(data["id"]); + } + } + }, []); + + const handleLogout = () => { + removeFromLocalStorage("access_token"); + removeFromLocalStorage("user_data"); + removeFromLocalStorage("uid"); + removeFromLocalStorage("expiry"); + removeFromLocalStorage("token-type"); + removeFromLocalStorage("client"); + window.location.reload(); + }; + + const handleOpenLogin = () => { + if (!isLoggedIn()) { + setNeedLoginOpen(true); + } + }; + + const handleToggleMobileSearch = () => { + mobileSearch.setSearchIsClicked((prev) => !prev); + }; + + const getHref = (href) => { + if (href === "/publicar" || href === "/sobre" || href === "/contato") return href; + if (href === "/perfil") return `/perfil/${id}`; + if (href === "#") return "#"; + return `/busca?page=${href}`; + }; const navItems = [ { label: "Pesquisar", href: "#", icon: SearchIcon }, - { label: "Recursos", href: "/busca?page=LearningObject", icon: SubjectIcon }, - { label: "Coleções", href: "/busca?page=Collection", icon: CollectionsBookmarkIcon }, - { label: "Publicar", href: "/publicar", icon: FileUploadIcon }, - { label: "MEC", href: "/busca?page=MEC", icon: VerifiedIcon }, { label: "Perfil", href: "/perfil", icon: Person }, + { label: "Coleções", href: "/busca?page=Collection", icon: CollectionsBookmarkIcon }, + { label: "Recursos", href: "/busca?page=LearningObject", icon: SubjectIcon }, { label: "Sobre", href: "/sobre", icon: HelpIcon }, + { label: "MEC", href: "/busca?page=MEC", icon: VerifiedIcon }, + { label: "Publicar", href: "/publicar", icon: FileUploadIcon }, { label: "Contato", href: "/contato", icon: EmailRoundedIcon }, { label: "Sair", href: "", icon: LogoutRounded}, ] - const handleToggleMobileSearch = (e) => { - e.preventDefault(); - mobileSearch.setSearchIsClicked((prevState) => !prevState); // Alterna a exibição da pesquisa - }; - - return ( - <> - <NeedLoginModal open={needLoginOpen} setOpen={setNeedLoginOpen} /> - - <nav className="bg-lightGray h-50 outline outline-1 outline-ice-HC-white text-darkGray-HC-white font-light fixed bottom-0 left-0 w-full z-10"> - <ul className="flex justify-between overflow-x-auto no-scrollbar animate-scrollHint"> - {navItems.map((item, index) => { - const isPublishRoute = item.href === "/publicar"; - const isPerfilRoute = item.href === "/perfil"; - const isSearchButton = item.label === "Pesquisar"; - const isLogout = item.label === "Sair"; - - const isActive = - (page === item.href.split("page=")[1]) || - (pathname === item.href) || - (mobileSearch.searchIsClicked && item.label === "Pesquisar"); - - return ( - <li key={index} className="flex w-20 flex-col items-center justify-center p-3"> - <a - href={isLogout ? "#" : ( - isPublishRoute ? (isLoggedIn() ? "/publicar" : "") : - isPerfilRoute ? (isLoggedIn() ? `/perfil/${id}` : "") : - item.href - )} - onClick={ - isLogout ? (e) => { e.preventDefault(); handleLogout(); } : - isPublishRoute || isPerfilRoute ? (e) => handleOpenLoggin(e) : - isSearchButton ? (e) => handleToggleMobileSearch(e) : - undefined - } - className={`text-center rounded-md transition-all ${ - isActive ? "font-bold text-black" : "" - }`} - > - <item.icon className={`cursor-pointer text-3xl ${isActive ? "text-black font-bold" : ""}`} /> - <span className={`cursor-pointer text-xs ${isActive ? "text-black font-bold" : ""}`}> - {item.label} - </span> - </a> - </li> - ); - })} - </ul> - </nav> - </> - ) -} \ No newline at end of file + return ( + <> + <NeedLoginModal open={needLoginOpen} setOpen={setNeedLoginOpen} /> + + <nav className="bg-lightGray-HC-dark h-50 outline outline-1 outline-ice-HC-white text-darkGray-HC-white-underline font-light fixed bottom-0 left-0 w-full z-10"> + <ul className="flex justify-between overflow-x-auto no-scrollbar animate-scrollHint"> + {navItems.map((item, index) => { + const isActive = + page === item.href || + pathname === item.href || + pathname.startsWith(item.href) || + (mobileSearch.searchIsClicked && item.label === "Pesquisar"); + + const isProtected = item.href === "/publicar" || item.href === "/perfil"; + + const handleClick = (e) => { + if (item.label === "Sair") { + e.preventDefault(); + handleLogout(); + } else if (item.label === "Pesquisar") { + e.preventDefault(); + handleToggleMobileSearch(); + } else if (isProtected && !isLoggedIn()) { + e.preventDefault(); + handleOpenLogin(); + } + }; + + return ( + <li key={index} className="flex w-20 flex-col items-center justify-center p-3"> + <Link + href={ + item.label === "Publicar" && !loggedIn + ? "#" + : item.label === "perfil" && loggedIn + ? `/perfil/${id}` + : getHref(item.href) + } + onClick={handleClick} + className={`text-center rounded-md transition-all ${ + isActive ? "text-lightGray-HC-dark-underline font-bold" : "" + }`} + > + <item.icon + className={`cursor-pointer text-3xl ${isActive ? "text-darkGray-HC-white-underline" : ""}`} + /> + <span className={`cursor-pointer text-xs ${isActive ? "text-darkGray-HC-white-underline font-bold" : ""}`}> + {item.label} + </span> + </Link> + </li> + ); + })} + </ul> + </nav> + </> + ); +} diff --git a/src/app/components/Notifications.js b/src/app/components/Notifications.js index 080fb428bf9c1114869a57b9909d2f21daaf7189..00cf4c1051b1c7826640ea6b12833aea3a928aee 100644 --- a/src/app/components/Notifications.js +++ b/src/app/components/Notifications.js @@ -1,37 +1,25 @@ import mecredApi from "@/axiosConfig"; -import { useLoginBarrier } from "@/app/handlers/loginHandler"; +import { authHeaders, useLoggedIn, useLoginBarrier } from "@/app/handlers/loginHandler"; import { getStoredValue } from "@/app/handlers/localStorageHandler"; import { useEffect, useState } from 'react' import ModalNotifications from "./ModalNotifications"; -export default function Notifications() { +export default function Notifications({id}) { const [notifications, setNotifications] = useState([]); const [countNotifications, setCountNotifications] = useState(null); const loginBarrier = useLoginBarrier() - - const token = getStoredValue("access_token") - const client = getStoredValue("client") - const uid = getStoredValue("uid") - + const loggedIn = useLoggedIn() useEffect(() => { - if (!loginBarrier()) + if (!loggedIn) return - const url = `/feed?offset=0&limit=30` - - const getNotifications = async (url) => { + const getNotifications = async () => { await mecredApi - .get(url, { - headers: { - 'access-token': token, - 'token-type': 'Bearer', - 'client': client, - 'uid': uid, - 'Expires': 0 - } + .get(`api/notifications`, { + headers: authHeaders() }) .then(({ data }) => { - + console.log(data) // temp pq o set fica um passo atras ai nao eh possivel usar o set do countNotifications let temp = data.filter((noti) => {return((noti.viewed === false))}) setNotifications(temp) @@ -39,23 +27,21 @@ export default function Notifications() { }) .catch((error) => console.error(error)) } + // const getOwnerNotification = async () => { + // await mecredApi + // .get(`/api/user/${notifications}`) + // } //chama funcao - getNotifications(url) + getNotifications() - }, [loginBarrier, uid, client, token]) + }, []) const postViewNotification = async (payload) => { - + console.log("oiii", payload) await mecredApi - .post("/activities/view", payload, { - headers: { - 'access-token': token, - 'token-type': 'Bearer', - 'client': client, - 'uid': uid, - 'Expires': 0 - } + .post("api/notifications/updateMany", payload, { + headers: authHeaders() }) .then(() => { let temp = notifications.filter((noti) => (!payload.activities.ids.includes(noti.id))) diff --git a/src/app/components/Overlay.js b/src/app/components/Overlay.js index 610bb3dc71f2ea039635f9e9ce33e1fb17dbc8db..4561355f603d9b50ebfa9f84e9d905607e23a0b5 100644 --- a/src/app/components/Overlay.js +++ b/src/app/components/Overlay.js @@ -76,20 +76,20 @@ export default function Overlay({ // Passar o parâmetro type={twoColumns} para páginas que possuem duas colunas (ex: InfiniteScroll, Perfil) type === "twoColumns" ? <div className="flex w-full"> - <div className="fixed pt-[160px] w-[150px] overflow-y-auto h-screen"> + <div className="fixed pt-[160px] w-[150px] overflow-y-auto h-screen scrollbar-none"> <SideBar setFilterState={setFilterState} filterState={filterState} /> </div> - <div className=" flex-grow pt-[150px] min-w-0 h-full ml-[120px]"> + <div className=" flex-grow pt-[150px] min-w-0 h-full ml-[150px] mr-14"> {children} </div> </div> : // Páginas com três colunas e que não precisam de h-full <div - className="grid w-full h-dvh pt-[160px] text-base 2xl:grid-cols-[150px_minmax(0,1fr)_500px] xl:grid-cols-[150px_minmax(0,1fr)_400px] grid-cols-[150px_minmax(0,1fr)]" + className="grid w-full pt-[160px] h-dvh text-base 2xl:grid-cols-[150px_minmax(0,1fr)_500px] xl:grid-cols-[150px_minmax(0,1fr)_400px] grid-cols-[150px_minmax(0,1fr)]" > - <div className="min-h-0"> + <div className="min-h-0 overflow-y-auto scrollbar-none"> <SideBar setFilterState={setFilterState} filterState={filterState} /> </div> {children} diff --git a/src/app/components/RecommendedCards.js b/src/app/components/RecommendedCards.js index 3848c1b81db0a1a36a784011d16077318d36eb62..532cc68882e0c737d14229fa194221be3ba4c60b 100644 --- a/src/app/components/RecommendedCards.js +++ b/src/app/components/RecommendedCards.js @@ -91,19 +91,15 @@ export default function RecommendedCards(props) { function getRandomBg(id) { const colors = [ - "bg-turquoise", - "bg-orange", - "bg-turquoise-hover", - "bg-darkOrange-HC-gray ", - "bg-violet", - "bg-pink", - "bg-red", + "bg-turquoise-HC-white", + "bg-orange-HC-white", + "bg-darkTurquoise-HC-white", + "bg-darkOrange-HC-white ", + "bg-violet-HC-white", + "bg-pink-HC-white", + "bg-red-HC-white", "bg-darkGray-HC-white", - "bg-darkGray-HC-white-click", - "bg-ice-HC-dark ", - "bg-darkGray-HC-white", - "bg-darkGray-HC-white", - "bg-turquoise-HC-dark", + "bg-ice-HC-white", ] return colors[id % colors.length]; diff --git a/src/app/components/SearchComponent.js b/src/app/components/SearchComponent.js index 05350ceea7b988a114244b4a97d9c63606c3513f..90d22296751495b0b58eb1903f62877a1921f4f7 100644 --- a/src/app/components/SearchComponent.js +++ b/src/app/components/SearchComponent.js @@ -155,7 +155,10 @@ export default function SearchComponent({ setFilterState, filterState, sizeWindo id="buscar" type="text" placeholder="Digite aqui o que você deseja pesquisar" - className="p-2 px-5 rounded-lg outline outline-1 font-light text-2xl placeholder:text-lightGray-HC-dark outline-ice-HC-white align-middle h-full w-full" + className="p-2 px-5 rounded-lg outline outline-1 font-light text-2xl + text-darkGray-HC-dark + placeholder:text-darkGray-HC-dark + outline-ice-HC-white align-middle h-full w-full" onFocus={handleFocus} onBlur={handleBlur} onChange={(e) => { diff --git a/src/app/components/ShareButton.js b/src/app/components/ShareButton.js index f90436b35e60b5329d69034d9bd5b1058a5b2ff4..9bd1272da5f240f33ef5e2464d9980f4be2edc88 100644 --- a/src/app/components/ShareButton.js +++ b/src/app/components/ShareButton.js @@ -11,19 +11,24 @@ import { usePathname } from 'next/navigation'; */ export default function ShareButton({ type, id }) { const [shareOpen, setShareOpen] = useState(false); - + const baseUrl = typeof window !== 'undefined' ? window.location.origin : ''; - const link = `${baseUrl}/${type}/${id}`; // Gera o link dinâmico baseado no tipo e ID - + const link = `${baseUrl}/${type}/${id}`; // Gera o link dinâmico baseado no tipo e ID + return ( <> <button - className="p-2 text-sm rounded-xl max-md:my-3 bg-ice-HC-dark hover:bg-lightGray-HC-white hover:text-darkGray-HC-dark outline outline-1 outline-ice-HC-white text-darkGray-HC-white-underline font-bold normal-case flex justify-center items-center gap-2" + className="p-2 text-sm rounded-[10px] max-md:w-44 w-48 h-11 hover:bg-darkGray-HC-white hover:text-darkGray-HC-dark outline outline-1 outline-lightGray-HC-white text-darkGray-HC-white-underline hover:text-white-HC-dark-underline font-bold normal-case flex justify-center items-center gap-2" onClick={() => setShareOpen(true)} aria-label="Compartilhar" > <ShareOutlinedIcon fontSize="small" /> - <span className="hidden md:inline">Compartilhar</span> + {type === "perfil" ? + <span className="hidden md:inline">Compartilhar Perfil</span> + : + <span className="hidden md:inline">Compartilhar</span> + } + </button> <ShareModal open={shareOpen} diff --git a/src/app/components/ShareModal.js b/src/app/components/ShareModal.js index bdc8d59d18383cf083f2b901bea3f3e40a8143da..dcaae4f8415a22837d9ee0a4ad7fd71f6a992ad5 100644 --- a/src/app/components/ShareModal.js +++ b/src/app/components/ShareModal.js @@ -51,7 +51,7 @@ export default function ShareModal({ open, onClose, title, link }) { <Button disableElevation variant="outlined" - className="border-darkGray-HC-white text-darkGray-HC-white-underline border text-lg normal-case flex gap-2 " + className="border border-lightGray-HC-white text-darkGray-HC-white-underline hover:bg-darkGray-HC-white hover:text-white-HC-dark-underline text-lg normal-case flex gap-2 " sx={{ justifyContent: "start" }} onClick={() => { navigator.clipboard.writeText(link); diff --git a/src/app/components/SideBar.js b/src/app/components/SideBar.js index 56834a2bb8f80dcf59191d3fd0c176514f791f66..46c95be9bccae09a7823dd291e65df5d6ce95415 100644 --- a/src/app/components/SideBar.js +++ b/src/app/components/SideBar.js @@ -12,8 +12,10 @@ import { Person } from "@mui/icons-material"; import FileUploadIcon from '@mui/icons-material/FileUpload'; import { isLoggedIn, useLoggedIn, userData } from "../handlers/loginHandler"; import NeedLoginModal from "./needLoginModal"; +import LogoutRounded from '@mui/icons-material/LogoutRounded'; import { getStoredValue, + removeFromLocalStorage, } from "../handlers/localStorageHandler"; /** @@ -24,18 +26,11 @@ import { const acessoRapido = [ { - title: "Publicar", - icon: FileUploadIcon, - href: "/publicar", - id: "Publicar Recurso", - }, - { - title: "MEC", - icon: VerifiedIcon, - href: "MEC", - id: "MEC", + title: "Meu perfil", + icon: Person, + href: "/perfil", + id: "Perfil", }, - { title: "Coleções", icon: CollectionsBookmarkIcon, @@ -48,23 +43,35 @@ const acessoRapido = [ href: "LearningObject", id: "Recursos", }, - { - title: "Perfil", - icon: Person, - href: "/perfil", - id: "Perfil", - }, { title: "Sobre", icon: HelpIcon, href: "/sobre", id: "Sobre", }, + { + title: "MEC", + icon: VerifiedIcon, + href: "MEC", + id: "MEC", + }, + { + title: "Publicar", + icon: FileUploadIcon, + href: "/publicar", + id: "Publicar Recurso", + }, { title: "Contato", icon: EmailRoundedIcon, href: "/contato", id: "Contato", + }, + { + title: "Sair", + icon: LogoutRounded, + href: "/sobre", + id: "sobre", } ]; @@ -93,6 +100,15 @@ export default function SideBar({ setFilterState, filterState }) { const page = searchParams.get('page') const pathname = usePathname(); const loggedIn = useLoggedIn(); + const [id, setId] = useState(null); + + useEffect(() => { + if (loggedIn) { + let data = userData(); + console.log(data, "ALKSDJLAKSJD"); + setId(data?.user["id"]); + } + }, [loggedIn]); const getHref = (href) => { switch (href) { @@ -109,7 +125,17 @@ export default function SideBar({ setFilterState, filterState }) { } }; - const [needLoginOpen, setNeedLoginOpen] = useState(false); + const [needLoginOpen, setNeedLoginOpen] = useState(false); + + const handleLogout = () => { + removeFromLocalStorage("access_token"); + removeFromLocalStorage("user_data"); + removeFromLocalStorage("uid"); + removeFromLocalStorage("expiry"); + removeFromLocalStorage("token-type"); + removeFromLocalStorage("client"); + window.location.reload(); + } const handleOpenLogin = () => { @@ -118,23 +144,15 @@ export default function SideBar({ setFilterState, filterState }) { } }; - const [id, setId] = useState(null); - - useEffect(() => { - if (loggedIn) { - let data = userData(); - console.log(data, "ALKSDJLAKSJD"); - setId(data?.["id"]); - } - }, [loggedIn]); - return ( <> <NeedLoginModal open={needLoginOpen} setOpen={setNeedLoginOpen} /> <div className="max-md:hidden min-h-0 overflow-y-auto flex flex-col text-darkGray-HC-white-underline font-light"> - <div className="flex flex-col justify-start items-center gap-3 w-full "> - {acessoRapido.map((item, index) => { + <div className="flex flex-col justify-start items-center gap-2 w-full mb-5"> + {acessoRapido + .filter(item => loggedIn || (item.title !== "Sair" && item.href !== "/perfil")) + .map((item, index) => { return ( <Link onClick={item.href === "/publicar" ? handleOpenLogin : () => { }} @@ -142,12 +160,13 @@ export default function SideBar({ setFilterState, filterState }) { key={index} alt={item.title} title={item.title} - className={`aspect-square cursor-pointer hover:bg-lightGray-HC-white hover:text-darkGray-HC-dark-underline focus:bg-lightGray-HC-white text-center rounded-lg pt-2 w-[80px] + className={`aspect-square cursor-pointer hover:bg-lightGray-HC-white hover:text-darkGray-HC-dark-underline focus:bg-lightGray-HC-white text-center rounded-lg pt-2 w-[88px] ${(page === item.href) || (pathname.startsWith(item.href)) ? "bg-lightGray-HC-white text-darkGray-HC-dark-underline font-bold" : ""} `} > - <item.icon - className={`text-3xl rounded-xl cursor-pointer ${page === item.href ? "text-darkGray-HC-dark-underline font-bold" : ""}`} + <item.icon + className={`rounded-xl cursor-pointer ${page === item.href ? "text-darkGray-HC-dark-underline font-bold" : ""}`} + sx={{ fontSize: '1.6em' }} /> <div className={`py-1 text-base ${page === item.href ? "text-darkGray-HC-dark-underline font-bold" : ""}`}> {item.title} @@ -159,4 +178,4 @@ export default function SideBar({ setFilterState, filterState }) { </div> </> ); -} \ No newline at end of file +} diff --git a/src/app/components/Title.js b/src/app/components/Title.js index fa511547c01e614c22166a36389fcf1b4bce9aaa..cf1b33599c4fab798b522c07d7ab6d31eefd7198 100644 --- a/src/app/components/Title.js +++ b/src/app/components/Title.js @@ -1,11 +1,11 @@ export default function Title() { return ( - <div className="my-10 mx-8"> + <div className="my-10 mx-8 justify-center "> <h1 className="text-3xl max-lg:text-xl font-bold text-darkGray-HC-white my-10 text-center"> MEC RED - A Rede Social da Educação </h1> - <h1 className="text-xl max-lg:text-base text-darkGray-HC-white text-balance mb-5 text-center"> - Aqui você pode se conectar com pessoas interessadas na área da educação, + <h1 className="text-xl max-lg:text-base text-darkGray-HC-white mb-5 justify-center text-center max-w-4xl mx-auto"> + Aqui você pode se conectar com pessoas interessadas na área da educação,<br/> acessar e compartilhar recursos Educacionais Digitais (REDs)! </h1> </div> diff --git a/src/app/components/UsersPageCard.js b/src/app/components/UsersPageCard.js index 82a854c8e076fad361eafab53c83744d039c36d3..5595d9853e099a65e6f19a2ffcc62e8f840e1fb4 100644 --- a/src/app/components/UsersPageCard.js +++ b/src/app/components/UsersPageCard.js @@ -1,7 +1,10 @@ +'use client' import { mecredURL } from "@/axiosConfig"; import { CollectionsBookmark, Person, Subject } from "@mui/icons-material" +import { useEffect, useState } from 'react'; import { Avatar, Divider } from "@mui/material" import Link from "next/link" +import mecredApi from "@/axiosConfig"; /** * @@ -10,21 +13,31 @@ import Link from "next/link" * @returns */ export default function UsersPageCard({ item }) { + const [achievements, setAchievements] = useState(null); + + const fetchAchievements = async (id) => { + await mecredApi + .get(`/unlocked_achievements/user/${id}?limit=1000`) + .then(({ data }) => { + setAchievements(data); + }) + .catch(() => setError(true)) + } + + fetchAchievements(item.id); + + function getRandomBg(id) { const colors = [ - "bg-turquoise", - "bg-orange", - "bg-turquoise-hover", - "bg-darkOrange-HC-gray ", - "bg-violet", - "bg-pink", - "bg-red", + "bg-turquoise-HC-white", + "bg-orange-HC-white", + "bg-darkTurquoise-HC-white", + "bg-darkOrange-HC-white ", + "bg-violet-HC-white", + "bg-pink-HC-white", + "bg-red-HC-white", "bg-darkGray-HC-white", - "bg-darkGray-HC-white-click", - "bg-ice-HC-dark ", - "bg-darkGray-HC-white", - "bg-darkGray-HC-white", - "bg-turquoise-HC-dark", + "bg-ice-HC-white", ] return colors[id % colors.length]; @@ -34,7 +47,7 @@ export default function UsersPageCard({ item }) { return ( item && <Link tabIndex="-1" href={`/perfil/${item["id"]}`}> - <div id="conteudo" tabIndex="0" className="flex flex-col w-[300px] min-h-[270px] bg-white-HC-dark outline outline-1 outline-ice-HC-white m-4 rounded-lg hover:bg-ice-HC-dark-hover focus:bg-ice-HC-dark-hover"> + <div id="conteudo" tabIndex="0" className="flex flex-col w-[300px] min-h-[270px] bg-ice-HC-dark outline outline-1 outline-lightGray-HC-white m-4 rounded-lg hover:bg-ice-HC-dark-hover focus:bg-ice-HC-dark-hover"> <div className="grid justify-items-center h-[200px] pt-2"> {item["avatar"] ? <Avatar src={mecredURL + item["avatar"]} sx={{ position: "inherit" }} className=" min-h-[120px] min-w-[120px] m-2" /> @@ -46,21 +59,35 @@ export default function UsersPageCard({ item }) { <p className=" font-bold text-darkGray-HC-white-underline text-center">{item["name"]}</p> </div> - <Divider className="mx-4" /> + <hr className="border-lightGray-HC-white h-1 mx-4 "/> <div className="flex items-center flex-col gap-1 py-3 "> - <div className="flex flex-col justify-start gap-1"> - <div className="flex"> - <Person fontSize="small" className="text-darkGray-HC-white-underline mt-2" /> + <div className="grid grid-cols-2 justify-start gap-1"> + <div className="flex items-center mb-2"> + <img className="flex h-[20px] px-1 text-mediumGray-HC-white invertLogo-HC-white" + src="/nivel.svg" + alt="Icon nivel" + /> + <p className="mt-2 text-sm text-darkGray-HC-white-underline px-1">Nível: {item["level"]}</p> + </div> + <div className="flex items-center mb-2"> + <Person fontSize="small" className="text-darkGray-HC-white mt-2" /> <p className="mt-2 text-sm text-darkGray-HC-white-underline px-1">Seguidores: {item["follows_count"]}</p> </div> {/* <div className="flex"> <CollectionsBookmark fontSize="small" className="text-darkGray-HC-white-underline" /> <p className="text-sm text-darkGray-HC-white-underline inline px-1">Coleções: {item["collections_count"]} </p> </div> */} - <div className="flex"> - <Subject fontSize="small" className="text-darkGray-HC-white-underline" /> + <div className="flex items-center mb-2"> + <Subject fontSize="small" className="text-darkGray-HC-white" /> <p className="text-sm text-darkGray-HC-white-underline inline px-1">Recursos: {item["learning_objects_count"]}</p> </div> + <div className="flex items-center mb-2"> + <img className="flex h-[20px] px-1 invertLogo-HC-white" + src="/conquistas.svg" + alt="Icon conquista" + /> + <p className="mt-2 text-sm text-darkGray-HC-white-underline px-1">Conquistas: {achievements?.length}</p> + </div> </div> </div> </div> diff --git a/src/app/components/collectionPreview.js b/src/app/components/collectionPreview.js index 96554dc57a8996b37ed65f3c29f89287d479cd97..138819c7c1ad48a0e8700a1f11af34f6eb4757b0 100644 --- a/src/app/components/collectionPreview.js +++ b/src/app/components/collectionPreview.js @@ -50,7 +50,7 @@ const getDefaultThumbnail = (type) => { return thumbnail_url; }; -export default function CollectionPreview({ collection }) { +export default function CollectionPreview({ collection, resources }) { if (!collection?.id) return <></>; const uri = mecredURL + "inline/" + collection.id; @@ -70,7 +70,7 @@ export default function CollectionPreview({ collection }) { </div> ); - if (collection.items_thumbnails.length > 0) { + if (resources > 0) { content = ( <div className="relative aspect-video w-full h-full"> <Image @@ -81,7 +81,7 @@ export default function CollectionPreview({ collection }) { width: '100%', objectFit: 'cover' }} - src={mecredURL + collection.items_thumbnails[0]} + src={`https://s3.c3sl.ufpr.br/mecredteste/thumbnail/resource/${resource.id}`} alt={collection.name} /> </div> diff --git a/src/app/components/needLoginModal.js b/src/app/components/needLoginModal.js index adf5c7e5bd18722afc73feca981054940d29b2d2..cf8b0859facde32cd53273caf9426d80ae325824 100644 --- a/src/app/components/needLoginModal.js +++ b/src/app/components/needLoginModal.js @@ -7,7 +7,7 @@ export default function NeedLoginModal({ open, setOpen }) { return ( <> <Modal - open={open && isLoggedIn} + open={open} className="grid h-screen place-items-center m-5" onClose={() => setOpen(false)} slotProps={{ @@ -19,23 +19,23 @@ export default function NeedLoginModal({ open, setOpen }) { }} > <div> - <div className="flex flex-col rounded-lg bg-white-HC-dark p-3"> - <div className="text-xl text-darkGray-HC-white-underline font-bold ">Entrar</div> + <div className="flex flex-col rounded-lg bg-white-HC-dark p-3 outline outline-1 outline-ice-HC-white"> + <div className="text-xl text-darkGray-HC-white font-bold ">Entrar</div> <div className="p-3"> - <div className="text-base text-darkGray-HC-white-underline"> + <div className="text-base text-darkGray-HC-white"> Você precisa entrar ou se cadastrar para executar essa ação. </div> <div className="flex flex-wrap justify-center gap-1 items-stretch"> <Button variant="contained" - className="bg-turquoise hover:bg-[#1d1d1d1c] disabled:bg-red mt-3 text-white-HC-dark-underline hover:text-turquoise-HC-underline shadow-none rounded normal-case text-base font-bold flex-shrink-0 flex-grow" + className="bg-turquoise-HC-white hover:bg-darkTurquoise-HC-dark disabled:bg-red-HC-white mt-3 text-white-HC-dark-underline hover:text-white-HC-underline shadow-none rounded normal-case text-base font-bold flex-shrink-0 flex-grow outline outline-1 outline-ice-HC-white" onClick={loginBarrier} > Ir para página de Login </Button> <Button variant="contained" - className="bg-white-HC-dark hover:bg-[#1d1d1d1c] disabled:bg-red mt-3 text-turquoise-HC-underline hover:text-turquoise-HC-underline shadow-none rounded normal-case text-base font-bold flex-shrink-0 flex-grow" + className="bg-white-HC-dark disabled:bg-red mt-3 text-turquoise-HC-white-underline hover:text-turquoise-HC-white shadow-none rounded normal-case text-base font-bold flex-shrink-0 flex-grow" onClick={() => setOpen(false)} > Cancelar diff --git a/src/app/components/publisherInfo.js b/src/app/components/publisherInfo.js index b86a45be1af7e739c2e84ab040b7b2be65dfde9a..273e31b34ddc65689defef25df3c2ff64970ba2f 100644 --- a/src/app/components/publisherInfo.js +++ b/src/app/components/publisherInfo.js @@ -35,19 +35,15 @@ export default function PublisherInfo({ publisher, disabledButton = false }) { function getRandomBg(id) { const colors = [ - "bg-turquoise", - "bg-orange", - "bg-turquoise-hover", - "bg-darkOrange-HC-gray ", - "bg-violet", - "bg-pink", - "bg-red", + "bg-turquoise-HC-white", + "bg-orange-HC-white", + "bg-darkTurquoise-HC-white", + "bg-darkOrange-HC-white ", + "bg-violet-HC-white", + "bg-pink-HC-white", + "bg-red-HC-white", "bg-darkGray-HC-white", - "bg-darkGray-HC-white-click", - "bg-ice-HC-dark ", - "bg-darkGray-HC-white", - "bg-darkGray-HC-white", - "bg-turquoise-HC-dark", + "bg-ice-HC-white", ] return colors[id % colors.length]; diff --git a/src/app/contato/page.js b/src/app/contato/page.js index bb6b42a83494968c70fc4036e947331b23e0b036..39c1939972dc0479c66ecad805c864a2b771ab0a 100644 --- a/src/app/contato/page.js +++ b/src/app/contato/page.js @@ -31,7 +31,7 @@ export default function Contact() { } await mecredApi - .post("/contacts", { + .post("public/contact", { name: formData.get("name"), email: formData.get("email"), message: formData.get("contents"), diff --git a/src/app/editar/[id]/components/EditForm.js b/src/app/editar/[id]/components/EditForm.js index 8a0011ade7631e4ce8b13253cf38f362da492150..625f0f835741032d784cefe000327d7ea0925f1c 100644 --- a/src/app/editar/[id]/components/EditForm.js +++ b/src/app/editar/[id]/components/EditForm.js @@ -4,7 +4,7 @@ import UpdateInfo from "./UpdateInfo"; export default function EditForm({ user }) { return ( - <div className="w-full bg-white-HC-dark rounded-lg shadow-lg"> + <div className="w-full bg-white-HC-dark rounded-lg shadow-lg outline outline-1 outline-ice-HC-white overflow-y-auto scrollbar-none"> <UpdateInfo user={user}/> <Divider className="mt-5 mx-4"/> <UpdatePassword user={user} /> diff --git a/src/app/editar/[id]/components/UpdateInfo.js b/src/app/editar/[id]/components/UpdateInfo.js index 3f1678a9f0566fe2b9cc510b993173a14d8e272e..6544ef5b6a27cd661f99f794ac0aa51d6349f963 100644 --- a/src/app/editar/[id]/components/UpdateInfo.js +++ b/src/app/editar/[id]/components/UpdateInfo.js @@ -1,272 +1,267 @@ +"use client" import { Avatar, Button, Modal, TextField } from "@mui/material" import FieldLabel from "@/app/components/FieldLabel" -import { useState, useMemo } from "react" +import { useState, useMemo, useEffect } from "react" import mecredApi, { mecredURL } from "@/axiosConfig" import { getStoredValue, saveToLocalStorage } from "@/app/handlers/localStorageHandler" import { useRouter } from "next/navigation" import ImageCropper from "@/app/components/ImageCropper" +import { authHeaders } from "@/app/handlers/loginHandler" export default function UpdateInfo({ user }) { - const [name, setName] = useState(user["name"]) - const [description, setDescription] = useState(user["description"] ? user["description"] : "") - const [sucessOpen, setSucessOpen] = useState(false) - const [notSucessOpen, setNotSucessOpen] = useState(false) - const [email, setEmail] = useState(user["email"] ?? "") - const [changePhoto, setChangePhoto] = useState(false) + const [name, setName] = useState(user["name"]) + const [description, setDescription] = useState(user["description"] ? user["description"] : "") + const [sucessOpen, setSucessOpen] = useState(false) + const [notSucessOpen, setNotSucessOpen] = useState(false) + const [email, setEmail] = useState(user["email"] ?? "") + const [changePhoto, setChangePhoto] = useState(false) + const reEmail = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ - const token = getStoredValue("access_token") - const client = getStoredValue("client") - const uid = getStoredValue("uid") - const router = useRouter() - const reEmail = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ + function getRandomBg(id) { + const colors = [ + "bg-turquoise", + "bg-orange", + "bg-turquoise-hover", + "bg-darkOrange-HC-gray ", + "bg-violet", + "bg-pink", + "bg-red", + "bg-darkGray-HC-white", + "bg-darkGray-HC-white-click", + "bg-ice-HC-dark ", + "bg-darkGray-HC-white", + "bg-darkGray-HC-white", + "bg-turquoise-HC-dark", + ] - function getRandomBg(id) { - const colors = [ - "bg-turquoise", - "bg-orange", - "bg-turquoise-hover", - "bg-darkOrange-HC-gray ", - "bg-violet", - "bg-pink", - "bg-red", - "bg-darkGray-HC-white", - "bg-darkGray-HC-white-click", - "bg-ice-HC-dark ", - "bg-darkGray-HC-white", - "bg-darkGray-HC-white", - "bg-turquoise-HC-dark", - ] - - return colors[id % colors.length]; + return colors[id % colors.length]; + } + + const handleSubmit = async (e) => { + e.preventDefault() + + if (name === "" || email === "") { + setNotSucessOpen(true) + return } + const payload = { + id: user.id, + name, + email, + description + }; + await mecredApi.post(`api/user/update`, payload, { + headers: authHeaders() + }) + .then(res => { + setSucessOpen(true); + }) + .catch(() => setNotSucessOpen(true)) + } - const handleSubmit = async (e) => { - e.preventDefault() + /** + * Handlers de texto + **/ + const handleNameChange = (e) => { + setName(e.target.value); + } - if (name === "" || email === "") { - setNotSucessOpen(true) - return - } + const handleDescriptionChange = (e) => { + setDescription(e.target.value); + } - const payload = { - user: { - name: name, - description: description, - email: email - } - } + const handleEmailChange = (e) => { + setEmail(e.target.value); + } - const url = `/users/${user["id"]}` + const router = useRouter() + + /* + * Modals + **/ + const ModalSucess = ({ open, onClose }) => { + return ( + <Modal open={open} onClose={onClose} className="grid place-items-center" slotProps={{ + backdrop: { + sx: { + backgroundColor: "rgba(0, 0, 0, 0.3)", // Ajuste a opacidade conforme necessário + }, + }, + }}> + <div className="flex flex-col justify-center bg-ice-HC-dark p-5 rounded"> + <p className="text-xl justify-center flex text-darkGray-HC-white-underline mb-2">Perfil editado com sucesso!</p> + <div className="flex flex-row mt-2"> - await mecredApi.put(url, payload, { - headers: { - 'access-token': token, - 'token-type': 'Bearer', - 'client': client, - 'uid': uid, - 'Expires': 0 - } - }) - .then(res => { - setSucessOpen(true); - }) - .catch(() => setNotSucessOpen(true)) + <button + className=" text-sm p-2 mr-1 text-white-HC-dark-underline border-main rounded-lg normal-case h-9 font-bold bg-turquoise hover:bg-turquoise-hover" + onClick={() => router.push(`/perfil/${user["id"]}`)} + > + Voltar para perfil + </button> + <button + className=" text-sm p-2 ml-1 text-darkGray-HC-white-underline border-main rounded-lg normal-case h-9 font-bold bg-ice-HC-dark hover:bg-ice-HC-dark-hover" + onClick={() => onClose()} + > + Continuar editando + </button> + </div> + </div> + </Modal> + ) + } - } + const ModalNotSucess = ({ open, onClose }) => { + return ( + <Modal open={open} onClose={onClose} className="grid place-items-center" slotProps={{ + backdrop: { + sx: { + backgroundColor: "rgba(0, 0, 0, 0.3)", // Ajuste a opacidade conforme necessário + }, + }, + }}> + <div className="flex flex-col justify-center bg-ice-HC-dark p-5 rounded"> + <p className="text-xl justify-center flex text-darkGray-HC-white-underline mb-2">Não foi possível fazer as alterações</p> + <div className="flex flex-row mt-2"> - /** - * Handlers de texto - **/ - const handleNameChange = (e) => { - setName(e.target.value); - } + <button + className=" text-sm p-2 mr-1 text-white-HC-dark-underline border-main rounded-lg normal-case h-9 font-bold bg-turquoise hover:bg-turquoise-hover" + onClick={() => router.push(`/perfil/${user.id}`)} + > + Voltar para perfil + </button> + <button + className=" text-sm p-2 ml-1 text-darkGray-HC-white-underline border-main rounded-lg normal-case h-9 font-bold bg-ice-HC-dark hover:bg-ice-HC-dark-hover" + onClick={() => onClose()} + > + Continuar editando + </button> + </div> + </div> + </Modal> + ) + } - const handleDescriptionChange = (e) => { - setDescription(e.target.value); - } + const ModalImageCropper = ({ open, onClose }) => { + return ( + <Modal + open={open} + onClose={onClose} + className="grid place-items-center" + slotProps={{ + backdrop: { + sx: { + backgroundColor: "rgba(0, 0, 0, 0.3)", // Ajuste a opacidade conforme necessário + }, + }, + }} + > + <div + className="flex flex-col bg-ice-HC-dark p-6 rounded-lg outline outline-1 outline-ice-HC-white overflow-auto" + style={{ + width: '90%', + maxWidth: '600px', + height: '70vh', + maxHeight: '90vh', + }} + > + <p className="text-xl text-darkGray-HC-white-underline text-center mb-4">Editar Foto de Perfil</p> - const handleEmailChange = (e) => { - setEmail(e.target.value); - } + <div className="flex-grow"> + <ImageCropper userId={user.id} setChangePhoto={setChangePhoto} /> + </div> - /* - * Modals - **/ - const ModalSucess = ({ open, onClose }) => { - return ( - <Modal open={open} onClose={onClose} className="grid place-items-center" slotProps={{ - backdrop: { - sx: { - backgroundColor: "rgba(0, 0, 0, 0.3)", // Ajuste a opacidade conforme necessário - }, - }, - }}> - <div className="flex flex-col justify-center bg-ice-HC-dark p-5 rounded"> - <p className="text-xl justify-center flex text-darkGray-HC-white-underline mb-2">Perfil editado com sucesso!</p> - <div className="flex flex-row mt-2"> + <button + className="text-sm p-2 text-darkGray-HC-white-underline border-main rounded-lg h-9 font-bold bg-ice-HC-dark hover:bg-ice-HC-dark-hover mt-4" + onClick={onClose} + > + Cancelar + </button> + </div> + </Modal> + ) + } - <button - className=" text-sm p-2 mr-1 text-white-HC-dark-underline border-main rounded-lg normal-case h-9 font-bold bg-turquoise hover:bg-turquoise-hover" - onClick={() => router.push(`/perfil/${user["id"]}`)} - > - Voltar para perfil - </button> - <button - className=" text-sm p-2 ml-1 text-darkGray-HC-white-underline border-main rounded-lg normal-case h-9 font-bold bg-ice-HC-dark hover:bg-ice-HC-dark-hover" - onClick={() => onClose()} - > - Continuar editando - </button> - </div> - </div> - </Modal> - ) - } + const [imageExists, setImageExists] = useState(false); + const imageUrl = `https://s3.c3sl.ufpr.br/mecredteste/avatar/${user.id}?nocache=${Date.now()}`; - const ModalNotSucess = ({ open, onClose }) => { - return ( - <Modal open={open} onClose={onClose} className="grid place-items-center" slotProps={{ - backdrop: { - sx: { - backgroundColor: "rgba(0, 0, 0, 0.3)", // Ajuste a opacidade conforme necessário - }, - }, - }}> - <div className="flex flex-col justify-center bg-ice-HC-dark p-5 rounded"> - <p className="text-xl justify-center flex text-darkGray-HC-white-underline mb-2">Não foi possível fazer as alterações</p> - <div className="flex flex-row mt-2"> + useEffect(() => { + const checkImage = async () => { + await mecredApi.get(`public/s3/get/avatar/${user.id}`, { + headers: authHeaders() + }) + .then(({ headers }) => setImageExists(true)) + .catch((error) => { + setImageExists(false) + }) + }; - <button - className=" text-sm p-2 mr-1 text-white-HC-dark-underline border-main rounded-lg normal-case h-9 font-bold bg-turquoise hover:bg-turquoise-hover" - onClick={() => router.push(`/perfil/${user["id"]}`)} - > - Voltar para perfil - </button> - <button - className=" text-sm p-2 ml-1 text-darkGray-HC-white-underline border-main rounded-lg normal-case h-9 font-bold bg-ice-HC-dark hover:bg-ice-HC-dark-hover" - onClick={() => onClose()} - > - Continuar editando - </button> - </div> - </div> - </Modal> - ) - } + checkImage(); + }, [user.id]); - const ModalImageCropper = ({ open, onClose }) => { - return ( - <Modal - open={open} - onClose={onClose} - className="grid place-items-center" - slotProps={{ - backdrop: { - sx: { - backgroundColor: "rgba(0, 0, 0, 0.3)", // Ajuste a opacidade conforme necessário - }, - }, - }} - > - <div - className="flex flex-col bg-ice-HC-dark p-6 rounded-lg outline outline-1 outline-ice-HC-white overflow-auto" - style={{ - width: '90%', - maxWidth: '600px', - height: '70vh', - maxHeight: '90vh', - }} - > - <p className="text-xl text-darkGray-HC-white-underline text-center mb-4">Editar Foto de Perfil</p> - - <div className="flex-grow"> - <ImageCropper payloadHeader={"user[avatar]"} type={"users"} userId={user.id} setChangePhoto={setChangePhoto} /> - </div> - - <button - className="text-sm p-2 text-darkGray-HC-white-underline border-main rounded-lg h-9 font-bold bg-ice-HC-dark hover:bg-ice-HC-dark-hover mt-4" - onClick={onClose} - > - Cancelar - </button> - </div> - </Modal> - ) - } - - return ( - <div> - <ModalNotSucess open={notSucessOpen} onClose={() => { setNotSucessOpen(false) }} /> - <ModalSucess open={sucessOpen} onClose={() => { setSucessOpen(false) }} /> - <form onSubmit={handleSubmit}> - <label className="text-3xl text-darkGray-HC-white-underline font-bold mt-3 flex justify-center">Editar Perfil</label> - <div className="flex flex-col mt-4 items-center"> - <label className="text-xl text-darkGray-HC-white font-bold mx-6">Foto de perfil</label> - <div className="flex flex-col items-center my-2"> - {user["avatar"] ? ( - <img - src={mecredURL + user["avatar"]} - className="w-[150px] h-[150px] object-cover rounded-full" - alt="Editar perfil" - /> - ) : ( - <div - className={`flex items-center justify-center text-xl font-bold text-ice-HC-dark rounded-full h-[150px] w-[150px] ${getRandomBg(user["id"])}`} - > - {user["name"][0]} - </div> - )} - - <button - type="button" - className="bg-turquoise text-white-HC-dark-underline rounded-lg mt-2 px-4 py-2" - onClick={() => setChangePhoto(true)} - > - Editar Foto - </button> + return ( + <div> + <ModalNotSucess open={notSucessOpen} onClose={() => { setNotSucessOpen(false) }} /> + <ModalSucess open={sucessOpen} onClose={() => { setSucessOpen(false) }} /> + <form onSubmit={handleSubmit}> + <label className="text-3xl text-darkGray-HC-white-underline font-bold mt-3 flex justify-center">Editar Perfil</label> + <div className="flex flex-col mt-4 items-center"> + <label className="text-xl text-darkGray-HC-white font-bold mx-6">Foto de perfil</label> + <div className="flex flex-col items-center my-2"> + {imageExists ? + <Avatar src={imageUrl} sx={{ position: "inherit" }} alt="Foto de perfil" className=" h-[276px] w-[276px] " /> + : + <div className={`flex items-center justify-center text-8xl font-bold text-ice-HC-dark rounded-full h-[276px] w-[276px] bg-turquoise-HC-white ${getRandomBg(user.id)}`} >{user.name[0]}</div> + } + <button + type="button" + className="bg-turquoise text-white-HC-dark-underline rounded-lg mt-2 px-4 py-2" + onClick={() => setChangePhoto(true)} + > + Editar Foto + </button> - <ModalImageCropper open={changePhoto} onClose={() => setChangePhoto(false)} /> - </div> - </div> + <ModalImageCropper open={changePhoto} onClose={() => setChangePhoto(false)} /> + </div> + </div> - <div className="mx-4 mt-4"> - <label className=" text-xl text-darkGray-HC-white-underline font-bold ">Nome Completo *</label> - <TextField - onChange={handleNameChange} - className="w-[100%] mt-2" - defaultValue={user["name"]} - /> - </div> - <div className="mx-4"> - <FieldLabel name="Sobre mim" description="Visível no seu perfil público" /> - <TextField - multiline - rows={3} - onChange={handleDescriptionChange} - helperText={`${description.length}/160`} - error={description.length > 160} - className="w-[100%]" - defaultValue={user["description"]} - /> - </div> - <div className="mx-4 mt-8"> - <label className=" text-xl text-darkGray-HC-white-underline font-bold ">Email *</label> - <TextField - onChange={handleEmailChange} - className="w-[100%] mt-2" - defaultValue={user["email"]} - /> - </div> + <div className="mx-4 mt-4"> + <label className=" text-xl text-darkGray-HC-white-underline font-bold ">Nome Completo *</label> + <TextField + onChange={handleNameChange} + className="w-[100%] mt-2" + defaultValue={user["name"]} + /> + </div> + <div className="mx-4"> + <FieldLabel name="Sobre mim" description="Visível no seu perfil público" /> + <TextField + multiline + rows={3} + onChange={handleDescriptionChange} + helperText={`${description.length}/160`} + error={description.length > 160} + className="w-[100%]" + defaultValue={user["description"]} + /> + </div> + <div className="mx-4 mt-8"> + <label className=" text-xl text-darkGray-HC-white-underline font-bold ">Email *</label> + <TextField + onChange={handleEmailChange} + className="w-[100%] mt-2" + defaultValue={user["email"]} + /> + </div> - <div className="flex justify-end mt-5 mr-4"> + <div className="flex justify-end mt-5 mr-4"> - <button type="button" onClick={() => router.push(`/perfil/${user["id"]}`)} className="bg-white-HC-dark text-darkGray-HC-white-underline p-2 rounded-lg hover:bg-ice-HC-dark-hover mr-1 ">Voltar para perfil</button> - <button type="submit" className="bg-turquoise text-white-HC-dark-underline p-2 rounded-lg hover:bg-turquoise-hover ml-1 ">Salvar alterações</button> - </div> - </form> + <button type="button" onClick={() => router.push(`/perfil/${user["id"]}`)} className="bg-white-HC-dark text-darkGray-HC-white-underline p-2 rounded-lg hover:bg-ice-HC-dark-hover mr-1 ">Voltar para perfil</button> + <button type="submit" className="bg-turquoise text-white-HC-dark-underline p-2 rounded-lg hover:bg-turquoise-hover ml-1 ">Salvar alterações</button> </div> - ) + </form> + </div> + ) } diff --git a/src/app/editar/[id]/components/UpdatePassword.js b/src/app/editar/[id]/components/UpdatePassword.js index 366525f38f1000b06b61d1eae037ce2616857532..eabca4b7dd47d9798eeec442650f4c752a111100 100644 --- a/src/app/editar/[id]/components/UpdatePassword.js +++ b/src/app/editar/[id]/components/UpdatePassword.js @@ -3,6 +3,7 @@ import { Modal, TextField } from "@mui/material" import { useState } from "react" import { getStoredValue } from "@/app/handlers/localStorageHandler" import { useRouter } from "next/navigation" +import { authHeaders } from "@/app/handlers/loginHandler" export default function UpdatePassword({ user }) { const [currentPassword, setCurrentPassword] = useState("") @@ -11,21 +12,6 @@ export default function UpdatePassword({ user }) { const [equal, setEqual] = useState(true) const [notSucessOpen, setNotSucessOpen] = useState(false) const [sucessOpen, setSucessOpen] = useState(false) - const token = getStoredValue("access_token") - const client = getStoredValue("client") - const uid = getStoredValue("uid") - const authHeaders = { - headers: { - 'access-token': token, - 'token-type': 'Bearer', - 'client': client, - 'uid': uid, - 'Expires': 0 - } - } - const router = useRouter() - - const handleCurr = (e) => { setCurrentPassword(e.target.value) @@ -59,14 +45,15 @@ export default function UpdatePassword({ user }) { return } - await mecredApi.put(url, payload, authHeaders) + await mecredApi.put(url, payload, { + headers: authHeaders() + }) .then(() => setSucessOpen(true)) .catch(() => setNotSucessOpen(true)) - - } + const ModalNotSucess = ({ open, onClose }) => { return ( <Modal open={open} onClose={onClose} className="grid place-items-center" slotProps={{ diff --git a/src/app/editar/[id]/page.js b/src/app/editar/[id]/page.js index a9a984d529cf7d2b2f60bf56cc981e798bf709da..3fc8c66946a04631043d2ae86aa00329d5ac5bab 100644 --- a/src/app/editar/[id]/page.js +++ b/src/app/editar/[id]/page.js @@ -4,30 +4,21 @@ import EditForm from "./components/EditForm"; import { useEffect, useState } from "react"; import mecredApi from "@/axiosConfig"; import { getStoredValue } from "@/app/handlers/localStorageHandler"; -import { useLoginBarrier } from "@/app/handlers/loginHandler"; +import { authHeaders, useLoginBarrier } from "@/app/handlers/loginHandler"; import Loading from "../../components/Loading"; export default function Edit({ params }) { const [userData, setUserData] = useState() - const token = getStoredValue("access_token") - const client = getStoredValue("client") - const uid = getStoredValue("uid") const loginBarrier = useLoginBarrier() const [got, setGot] = useState(false) useEffect(() => { - if (!loginBarrier()) - return + // if (!loginBarrier()) + // return const fetchUser = async (id) => { await mecredApi - .get(`/users/${id}`, { - headers: { - 'access-token': token, - 'token-type': 'Bearer', - 'client': client, - 'uid': uid, - 'Expires': 0 - } + .get(`api/user/${id}`, { + headers: authHeaders() }) .then(({data}) => { setUserData(data); @@ -37,7 +28,7 @@ export default function Edit({ params }) { } fetchUser(params.id) - }, [params.id, token, client, uid, loginBarrier]) + }, [params.id]) const ErrorEdit = () => { return ( diff --git a/src/app/entrar/components/LoginForm.js b/src/app/entrar/components/LoginForm.js index b44cbd3ec4ffca5ead49e395e230012159865255..8d0a53dafc1f314561cf12fb2a17054641032325 100644 --- a/src/app/entrar/components/LoginForm.js +++ b/src/app/entrar/components/LoginForm.js @@ -67,7 +67,7 @@ export default function LoginForm({ {/* Campo de E-mail */} <div className="w-full mb-6"> - <label htmlFor="email" className="block text-sm font-medium text-darkGray-HC-white mb-1"> + <label htmlFor="email" className="block text-sm font-light text-darkGray-HC-white mb-1"> Insira seu e-mail </label> <input @@ -81,7 +81,7 @@ export default function LoginForm({ {/* Campo de Senha */} <div className="w-full mb-6"> - <label htmlFor="password" className="block text-sm font-medium text-darkGray-HC-white mb-1"> + <label htmlFor="password" className="block text-sm font-light text-darkGray-HC-white mb-1"> Insira sua senha </label> <div className="relative"> diff --git a/src/app/entrar/components/PasswordModal.js b/src/app/entrar/components/PasswordModal.js index 34cbc949f354a4983eebd7023764016dd924f4d0..d8bfe123ec49ae5852c2149893d7bda7b65f836e 100644 --- a/src/app/entrar/components/PasswordModal.js +++ b/src/app/entrar/components/PasswordModal.js @@ -73,7 +73,7 @@ export default function PasswordModal({ open, handleClose }) { <Box className="bg-white-HC-dark outline outline-1 outline-ice-HC-white p-5 flex flex-col items-center border-none rounded-xl"> <div className="flex flex-row justify-between mb-2"> <h1 className="text-turquoise-HC-white text-2xl font-bold m-2 mb-5 mr-4">Vamos encontrar sua conta</h1> - <CloseIcon onClick={handleClose} sx={{ color: "var(--darkGray-HC-white)", fontSize: "30px", marginTop:"5px" }} /> + <CloseIcon onClick={handleClose} sx={{ color: "var(--darkGray-HC-white)", fontSize: "30px", marginTop: "5px" }} /> </div> <div> {feedbackMessage ? ( @@ -82,7 +82,7 @@ export default function PasswordModal({ open, handleClose }) { </Alert> ) : null} <div className="w-full mb-3"> - <label htmlFor="email" className="block text-sm font-medium text-darkGray-HC-white mb-1"> + <label htmlFor="email" className="block text-sm font-light text-darkGray-HC-white mb-1"> E-mail * </label> <input diff --git a/src/app/entrar/components/SignupModal.js b/src/app/entrar/components/SignupModal.js index c9a7e052248eddc25921a8f87edeb65a8d8885d9..b6322d63582debb9083b031f269cc748207f9056 100644 --- a/src/app/entrar/components/SignupModal.js +++ b/src/app/entrar/components/SignupModal.js @@ -85,7 +85,7 @@ export default function SignupModal({ open, handleClose }) { <Box className="bg-white-HC-dark outline outline-1 outline-ice-HC-white sm:w-1/2 xl:w-1/4 p-5 flex flex-col items-center border-none rounded-xl"> <div className="flex w-full"> <h1 className="text-turquoise-HC-white text-center w-full flex-1 text-2xl font-bold m-5">Cadastre-se</h1> - <CloseIcon onClick={handleClose} sx={{ color: "var(--darkGray-HC-white)", fontSize: "30px", marginTop: "5px" }} className="" /> + <CloseIcon onClick={handleClose} sx={{ color: "var(--darkGray-HC-white)", fontSize: "30px", marginTop: "5px" }} className="" /> </div> <form onSubmit={handleSubmit} className="flex flex-col w-full"> @@ -95,7 +95,7 @@ export default function SignupModal({ open, handleClose }) { </Alert> ) : null} <div className="w-full mb-3"> - <label htmlFor="nome" className="block text-sm font-medium text-darkGray-HC-white mb-1"> + <label htmlFor="nome" className="block text-sm font-light text-darkGray-HC-white mb-1"> Nome Completo * </label> <input @@ -108,7 +108,7 @@ export default function SignupModal({ open, handleClose }) { /> </div> <div className="w-full mb-3"> - <label htmlFor="email" className="block text-sm font-medium text-darkGray-HC-white mb-1"> + <label htmlFor="email" className="block text-sm font-light text-darkGray-HC-white mb-1"> E-mail * </label> <input @@ -121,7 +121,7 @@ export default function SignupModal({ open, handleClose }) { /> </div> <div className="w-full mb-3"> - <label htmlFor="password" className="block text-sm font-medium text-darkGray-HC-white mb-1"> + <label htmlFor="password" className="block text-sm font-light text-darkGray-HC-white mb-1"> Senha * </label> <div className="relative"> @@ -154,7 +154,7 @@ export default function SignupModal({ open, handleClose }) { <p className="text-darkGray-HC-white text-sm">A senha deve ter no mínimo 8 caracteres.</p> </div> <div className="w-full mb-4"> - <label htmlFor="passwordConfirmation" className="block text-sm font-medium text-darkGray-HC-white mb-1"> + <label htmlFor="passwordConfirmation" className="block text-sm font-light text-darkGray-HC-white mb-1"> Confirmar senha * </label> <div className="relative"> diff --git a/src/app/equipe/components/teamCard.js b/src/app/equipe/components/teamCard.js index 013f53b080b7145c73cdda79ae91c10038670920..08a2205ecb07fb6fc8faec1f6c6ea2bb9afd4045 100644 --- a/src/app/equipe/components/teamCard.js +++ b/src/app/equipe/components/teamCard.js @@ -207,6 +207,21 @@ const team = [ filter: "UFPR", active: true, }, + { + name: "Nicolas Rizzardi", + image: "https://mecred.c3sl.ufpr.br/team-photos/Nicolas_Rizzardi.png", + info: "Desenvolvimento", + links: { + MecRed: "https://mecred.mec.gov.br/perfil/42599", + Lattes: "http://lattes.cnpq.br/6435898346121114", + Linkedin: "https://www.linkedin.com/in/nicolas-rizzardi-9140971a4", + Outro: "https://github.com/NARizzardi", + }, + details: `Nicolas Rizzardi é graduando em Ciência da Computação pela Universidade Federal do Paraná (UFPR). Foi bolsista do C3SL atuando como + desenvolvedor na plataforma MECRED.`, + filter: "UFPR", + active: false, + }, ] diff --git a/src/app/estatisticas/page.js b/src/app/estatisticas/page.js index 1b912d6ebf59c4c8b2cc20fd13d743ae58358441..7afa5637c29953fd8fc55e5df4a89dbafc50ead6 100644 --- a/src/app/estatisticas/page.js +++ b/src/app/estatisticas/page.js @@ -1,9 +1,17 @@ "use client" import Overlay from "../components/Overlay" +import { useEffect } from 'react'; +import { useRouter } from 'next/navigation'; + export default function About() { + const router = useRouter(); + + useEffect(() => { + router.push(`/sobre`); + }); - return ( + /*return ( <Overlay type="twoColumns"> <div className="m-3 sm:ml-24 "> <iframe @@ -15,5 +23,5 @@ export default function About() { </iframe> </div> </Overlay> - ) + )*/ } diff --git a/src/app/globals.css b/src/app/globals.css index 8e751398eec0ad33112bd183ae227f233c315e69..ef4ead286723e464e56f0860687ac6678ac5b59a 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -73,6 +73,8 @@ --lightGray: #d8e6e6; --lightGray-HC-dark: #d8e6e6; --lightGray-HC-white: #d8e6e6; + --lightGray-HC-white-underline:#d8e6e6; + --lightGray-HC-dark-underline:#d8e6e6; --red-HC-white: #dc2626; --mediumGray-HC-white: #b9cccc; --mediumGray-HC-dark: #b9cccc; diff --git a/src/app/handlers/loginHandler.js b/src/app/handlers/loginHandler.js index 7cb30394e532b70fd479a0e36679f3f88cc079e0..72f45758f169f35703810fd5c4c2dc80752aafff 100644 --- a/src/app/handlers/loginHandler.js +++ b/src/app/handlers/loginHandler.js @@ -14,9 +14,9 @@ export function useLoginBarrier() { const pathname = usePathname(); const searchParams = useSearchParams(); const router = useRouter(); - + return useCallback(() => { - if (!localStorage.getItem('token')) return true; + if (localStorage.getItem('token')) return true; const params = new URLSearchParams(); params.set("redirect", pathname); @@ -68,7 +68,6 @@ export function logOut() { export function userData() { const dataString = localStorage.getItem('user_data'); - if (!dataString) return undefined; diff --git a/src/app/not-found.js b/src/app/not-found.js index 8e982b2e335df47a9e0abb69dcc90eee339f02bc..95291a7c5be22de47f15b708d2b811e3a8f22d7b 100644 --- a/src/app/not-found.js +++ b/src/app/not-found.js @@ -6,11 +6,10 @@ export default function Error(){ const router = useRouter() return ( <Overlay> - <div className="flex justify-center items-center mt-72 flex-col"> - <p className="text-8xl text-darkGray-HC-white font-bold">404</p> + <p className="text-8xl text-darkGray-HC-white font-bold mb-10">404</p> <p className="text-darkGray-HC-white text-xl font-semibold">Página não encontrada</p> - <button onClick={() => router.push("/")} className="mt-4 bg-turquoise text-lg text-white-HC-dark-underline p-2 px-4 rounded-lg hover:bg-turquoise-hover">Voltar para página inicial</button> + <button onClick={() => router.push("/")} className="mt-4 bg-turquoise-HC-white text-lg text-white-HC-dark-underline p-2 px-4 rounded-lg hover:bg-darkTurquoise-HC-dark hover:text-white outline outline-1">Voltar para página inicial</button> </div> </Overlay> ) diff --git a/src/app/novaSenha/page.js b/src/app/novaSenha/page.js index e4ffa7aaa63e96e2ea2b6cab684a5c1b0ddb9546..85a8019aef2bd868c2ed1dd4dc48654d96ced7fc 100644 --- a/src/app/novaSenha/page.js +++ b/src/app/novaSenha/page.js @@ -127,33 +127,33 @@ export default function ResetPassword() { </div> {/* Campo de Nova Senha */} <div className="w-full mb-6"> - <label htmlFor="senha" className="block text-sm font-medium text-gray-700 mb-1"> - Nova Senha * - </label> + <label htmlFor="senha" className="block text-sm font-light text-gray-700 mb-1"> + Nova Senha * + </label> <div className="relative"> <input - id="senha" - type={showPassword ? 'text' : 'password'} - className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-secondary" - onChange={(e) => setPassword(e.target.value)} - value={password} - alt="Nova Senha" + id="senha" + type={showPassword ? 'text' : 'password'} + className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-secondary" + onChange={(e) => setPassword(e.target.value)} + value={password} + alt="Nova Senha" /> <button - type="button" - onClick={handleClickShowPassword} - className="absolute inset-y-0 right-0 pr-3 flex items-center text-sm leading-5" + type="button" + onClick={handleClickShowPassword} + className="absolute inset-y-0 right-0 pr-3 flex items-center text-sm leading-5" > - {showPassword ? <img src="ocultar-senha.svg" alt="Ocultar senha" /> : <img src="ver-senha.svg" alt="Ver senha" />} + {showPassword ? <img src="ocultar-senha.svg" alt="Ocultar senha" /> : <img src="ver-senha.svg" alt="Ver senha" />} </button> </div> </div> {/* Campo de Confirmação de Nova Senha */} <div className="w-full mb-6"> - <label htmlFor="confirma-senha" className="block text-sm font-medium text-gray-700 mb-1"> - Confirme Nova Senha * - </label> + <label htmlFor="confirma-senha" className="block text-sm font-light text-gray-700 mb-1"> + Confirme Nova Senha * + </label> <div className="relative"> <input id="confirma-senha" @@ -167,7 +167,7 @@ export default function ResetPassword() { type="button" onClick={handleClickShowPasswordConfirmation} className="absolute inset-y-0 right-0 pr-3 flex items-center text-sm leading-5" - > + > {showPasswordConfirmation ? ( <img src="ocultar-senha.svg" alt="Ocultar senha" /> ) : ( diff --git a/src/app/perfil/[id]/components/CardsComplaints.js b/src/app/perfil/[id]/components/CardsComplaints.js index 78e1cf17d10b5edf31ccb70250f50126bd7094f7..ce0832416831138173503d28c982e4e5c703a7c2 100644 --- a/src/app/perfil/[id]/components/CardsComplaints.js +++ b/src/app/perfil/[id]/components/CardsComplaints.js @@ -32,14 +32,14 @@ export default function CardsComplaints({ item, key}) { }} component="img" image="/images/preview-recurso-denunciado.png" - title={item[0]?.name} + title={item?.name} alt="img" /> <CardHeader className="self-start flex-shrink h-[100px]" title={ <Typography variant="body2" color="" className="line-clamp-2 text-darkGray-HC-white-underline font-bold"> - {item[0]?.name} + {item?.name} </Typography> } subheader={ @@ -49,7 +49,7 @@ export default function CardsComplaints({ item, key}) { color="text.secondary" className="line-clamp-1 text-darkGray-HC-white font-light" > - {item[0]?.name} + {item?.name} </Typography> </> } @@ -57,7 +57,7 @@ export default function CardsComplaints({ item, key}) { <div className="hover:bg-ice-HC-dark-hover flex items-end rounded-lg"> <Button className="text-darkGray-HC-white-underline font-light" alt='Avaliar' - onClick={() => window.open(location.protocol + `//` + location.host + `/recurso/${item[0]?.learning_object_id}`)} + onClick={() => window.open(location.protocol + `//` + location.host + `/recurso/${item?.id}`)} > Avaliar </Button> diff --git a/src/app/perfil/[id]/components/CardsHomologation.js b/src/app/perfil/[id]/components/CardsHomologation.js index b95ca213a40908fa6c6569ddb93f81587a93a02d..f713f650eebdd82f756a169aa5ba162b942a4554 100644 --- a/src/app/perfil/[id]/components/CardsHomologation.js +++ b/src/app/perfil/[id]/components/CardsHomologation.js @@ -5,6 +5,7 @@ import Avatar from "@mui/material/Avatar"; import Typography from "@mui/material/Typography"; import Link from "next/link"; import { mecredURL } from "@/axiosConfig"; +import { useEffect, useState } from "react"; const getDefaultThumbnail = (type) => { let thumbnail_url; @@ -52,6 +53,34 @@ const getDefaultThumbnail = (type) => { */ export default function CardsHomologation({ item, key, tag }) { + const [imageMap, setImageMap] = useState({}); + + const verifyImage = async (id) => { + try { + await mecredApi.get(`public/s3/get/thumbnail/resource/${id}`, { + headers: authHeaders() + }); + return true; // Existe + } catch (error) { + if (error.response && error.response.status === 404) { + return false; // Não existe + } + return false; + } + }; + + useEffect(() => { + const checkImage = async () => { + const exists = await verifyImage(item.id); + setImageMap({ [item.id]: exists }); + }; + + if (item) { + checkImage(); + } + }, [item]); + + return ( <Card className="transition bg-white-HC-dark outline outline-1 outline-ice-HC-white items-center mt-5 mx-2 min-h-[320px]" @@ -78,22 +107,21 @@ export default function CardsHomologation({ item, key, tag }) { }} component="img" image={ - tag ? null : - item["learning_object"]["thumbnail"] === null - ? getDefaultThumbnail(item["learning_object"]["object_type"]) - : mecredURL + item["learning_object"]["thumbnail"] - } - title={ tag ? item[0]?.name : item["learning_object"]["thumbnail"]} + imageMap[item.id] + ? `https://s3.c3sl.ufpr.br/mecredteste/thumbnail/resource/${item.id}` + : getDefaultThumbnail(item.objectTypeName) + } + title={item[0]?.name} alt="img" /> <CardHeader className="self-start flex-shrink h-[100px]" - avatar={tag ? null : item["submitter"]["avatar"] === null ? null : + avatar={ <Link href="/perfil"> <Avatar - src={mecredURL + item["submitter"]["avatar"]} - alt={item["submitter"]["name"]} - title={item["submitter"]["name"]} + src={`https://s3.c3sl.ufpr.br/mecredteste/avatar/${item.user_id}`} + alt={item.author} + title={item.author} // className="-mt-9" sx={{ width: 28, @@ -106,7 +134,7 @@ export default function CardsHomologation({ item, key, tag }) { } title={ <Typography variant="body2" color="" className="line-clamp-2 text-darkGray-HC-white-underline font-bold"> - { tag ? item[0]?.name : item["learning_object"]["name"]} + { tag ? item[0]?.name : item.name} </Typography> } subheader={ @@ -116,7 +144,7 @@ export default function CardsHomologation({ item, key, tag }) { color="text.secondary" className="line-clamp-1 text-darkGray-HC-white-underline font-light" > - {tag ? item[0]?.name : item["submitter"]["name"]} + {tag ? item[0]?.name : item.author} </Typography> </> } diff --git a/src/app/perfil/[id]/components/CreateCollectionModal.js b/src/app/perfil/[id]/components/CreateCollectionModal.js index b10a63a74af440ab1b2736c79aae561c8703a481..22ae4f30a3b67a8d680c8cb5cfda5defd0250c9c 100644 --- a/src/app/perfil/[id]/components/CreateCollectionModal.js +++ b/src/app/perfil/[id]/components/CreateCollectionModal.js @@ -2,6 +2,7 @@ import { FormLabel, Modal, TextField, RadioGroup, FormControlLabel, Radio } from import { useState } from "react"; import { getStoredValue } from "@/app/handlers/localStorageHandler"; import mecredApi from "@/axiosConfig"; +import { authHeaders } from "@/app/handlers/loginHandler"; /** * @param {Object} props @@ -56,26 +57,19 @@ export default function CreateCollectionModal({ open, onClose, idLogin }) { * Informações necessárias para o backend para criar uma nova coleção */ const payload = { - "collection": { - "name": name, - "owner_id": idLogin, - "owner_type": "User", - "privacy": e.target["privacy-radio-group"].value - } + "user_id": idLogin, + "name": name, + "privacy": e.target["privacy-radio-group"].value }; /** * Requisição para criação da coleção */ + console.log(typeof idLogin); // deve mostrar "number" se estiver certinho + try { // Requisição para criação da coleção - const response = await mecredApi.post("/collections", payload, { - headers: { - "access-token": token, - "token-type": "Bearer", - client: client, - uid: uid, - Expires: 0, - }, + const response = await mecredApi.post("api/collections/create", payload, { + headers: authHeaders(), }); setOpenSuccess(true); setName(""); @@ -114,12 +108,12 @@ export default function CreateCollectionModal({ open, onClose, idLogin }) { <FormLabel > <RadioGroup name="privacy-radio-group"> <FormControlLabel - value="public" + value="false" control={<Radio className="" />} label="Coleção Pública" /> <FormControlLabel - value="private" + value="true" control={<Radio />} label="Coleção Privada" /> diff --git a/src/app/perfil/[id]/components/EditCollectionModal.js b/src/app/perfil/[id]/components/EditCollectionModal.js index cf231bcf19637b82cd58e125bd50cf42c3a9463a..083c074883ed0b21d4b96861a64bbfe4ad160134 100644 --- a/src/app/perfil/[id]/components/EditCollectionModal.js +++ b/src/app/perfil/[id]/components/EditCollectionModal.js @@ -2,6 +2,7 @@ import { useState } from "react"; import { Modal, TextField, RadioGroup, FormControlLabel, Radio, FormLabel } from "@mui/material"; import { getStoredValue } from "@/app/handlers/localStorageHandler"; import mecredApi from "@/axiosConfig"; +import { authHeaders } from "@/app/handlers/loginHandler"; /** * @param {Object} props @@ -23,25 +24,16 @@ export default function EditCollectionModal({ open, onClose, collectionId, colle const handleSubmit = async (e) => { e.preventDefault(); - const payload = { - collection: { - name, - owner_id: collectionData.owner_id, - owner_type: collectionData.owner_type, - privacy, - }, + id: collectionId, + name, + owner_id: collectionData.owner_id, + owner_type: collectionData.owner_type, + privacy, }; - try { - const response = await mecredApi.put(`/collections/${collectionId}`, payload, { - headers: { - "access-token": token, - "token-type": "Bearer", - client, - uid, - Expires: 0, - }, + const response = await mecredApi.post(`api/collections/update`, payload, { + headers: authHeaders(), }); console.log(response.data) @@ -84,9 +76,9 @@ export default function EditCollectionModal({ open, onClose, collectionId, colle }, }, }}> - <div className="flex flex-col bg-ice-HC-dark p-5 rounded-lg w-[40%] max-sm:w-[85%]"> - <div className="text-2xl font-bold text-darkGray-HC-white-underline">Editar Coleção</div> - <p className="text-lg text-darkGray-HC-white-underline font-bold mb-1 mt-4">Nome da Coleção*</p> + <div className="flex flex-col bg-ice-HC-dark p-5 rounded-lg w-[40%] max-sm:w-[85%] outline outline-1 outline-ice-HC-white"> + <div className="text-2xl font-bold text-darkGray-HC-white">Editar Coleção</div> + <p className="text-lg text-darkGray-HC-white font-bold mb-1 mt-4">Nome da Coleção*</p> <form onSubmit={handleSubmit}> <TextField size="small" @@ -94,24 +86,68 @@ export default function EditCollectionModal({ open, onClose, collectionId, colle onChange={(e) => setName(e.target.value)} value={name} required + sx={{ + '& .MuiOutlinedInput-root': { + '& fieldset': { + borderColor: 'var(--mediumGray-HC-white)', // cor da borda + }, + '&:hover fieldset': { + borderColor: 'var(--turquoise-HC-white)', // ao passar o mouse + }, + '&.Mui-focused fieldset': { + borderColor: 'var(--turquoise-HC-white)', // quando estiver focado + }, + '& input': { + color: 'var(--darkGray-HC-white)', // cor do texto digitado + }, + }, + }} /> - <p className="text-lg text-darkGray-HC-white-underline font-bold mb-3 mt-4">Esta coleção é:</p> + <p className="text-lg text-darkGray-HC-white font-bold mb-3 mt-4">Esta coleção é:</p> <FormLabel> - <RadioGroup value={privacy} onChange={(e) => setPrivacy(e.target.value)}> - <FormControlLabel value="public" control={<Radio />} label="Coleção Pública" /> - <FormControlLabel value="private" control={<Radio />} label="Coleção Privada" /> + <RadioGroup + value={privacy} + sx={{ + '& .MuiRadio-root': { + color: 'var(--darkGray-HC-white)', // Default radio color + '&.Mui-checked': { + color: 'var(--turquoise-HC-white)', // Selected radio color + }, + }, + }} + onChange={(e) => setPrivacy(e.target.value)}> + <FormControlLabel + value="public" + control={<Radio />} + label="Coleção Pública" + sx={{ + '& .MuiFormControlLabel-label': { + color: 'var(--darkGray-HC-white)', + }, + }} + /> + <FormControlLabel + value="private" + control={<Radio />} + label="Coleção Privada" + sx={{ + '& .MuiFormControlLabel-label': { + color: 'var(--darkGray-HC-white)', + }, + }} + /> </RadioGroup> </FormLabel> <div className="flex flex-row-reverse justify-center space-x-2"> <button - className="border text-sm p-2 text-ice-HC-dark border-main rounded-lg normal-case h-9 font-bold bg-turquoise hover:bg-turquoise-hover" + className="border text-sm p-2 text-white-HC-dark-underline border-ice-HC-dark hover:border-ice-HC-white hover:text-white rounded-lg normal-case h-9 font-bold bg-turquoise-HC-white hover:bg-darkTurquoise-HC-dark" type="button" // Alterado para "button" onClick={handleSubmit} // Chama a função diretamente no onClick > Salvar Alterações </button> <button - className="border text-sm p-2 text-darkGray-HC-white-underline border-main rounded-lg normal-case h-9 font-bold bg-ice-HC-dark hover:bg-ice-HC-dark-hover" + className="border text-sm p-2 text-darkGray-HC-white-underline border-main rounded-lg normal-case h-9 font-bold bg-ice-HC-dark hover:bg-lightGray-HC-dark" onClick={onClose} > Cancelar diff --git a/src/app/perfil/[id]/components/FollowersCards.js b/src/app/perfil/[id]/components/FollowersCards.js index 33819806798ea855ccaa6f91da9be189cded4931..dba01ae8978f1865143c5b4e23f242e9753990e5 100644 --- a/src/app/perfil/[id]/components/FollowersCards.js +++ b/src/app/perfil/[id]/components/FollowersCards.js @@ -5,7 +5,7 @@ import UsersPageCard from "@/app/components/UsersPageCard"; import { Button } from "@mui/material"; import NotFound from "./NotFound"; import Loading from "@/app/components/Loading"; - +import { authHeaders } from "@/app/handlers/loginHandler"; /** * * @param {Object} props @@ -16,25 +16,15 @@ import Loading from "@/app/components/Loading"; export default function FollowersCards({ id, count }) { const [numberCards, setNumberCards] = useState(0); const [followers, setFollowers] = useState([]); - const token = getStoredValue("access_token"); - const client = getStoredValue("client"); - const uid = getStoredValue("uid"); - const expiry = getStoredValue("expiry"); const [got, setGot] = useState(false); useEffect(() => { const fetchData = async () => { try { - const { data } = await mecredApi.get(`/users/${id}/followers?offset=${numberCards}`, { - headers: { - 'access-token': token, - 'token-type': 'Bearer', - 'client': client, - 'uid': uid, - 'Expires': expiry - } + const { data } = await mecredApi.get(`public/user/followers/${id}?offset=${numberCards}`, { + headers: authHeaders() }); - setFollowers((prevFollowers) => [...prevFollowers, ...data]); + setFollowers((prevFollowers) => [...prevFollowers, ...(Array.isArray(data) ? data : [])]); setGot(true); } catch (error) { console.error(error); @@ -45,7 +35,7 @@ export default function FollowersCards({ id, count }) { // token changes after each request so if we put as dependecy it will keep changing and make more than one request. // to solve this we probably need useContext. // eslint-disable-next-line react-hooks/exhaustive-deps - }, [id, numberCards, client, uid, expiry]); + }, [id, numberCards]); const toggleContent = () => { setNumberCards((prevNumberCards) => prevNumberCards + 12); @@ -61,7 +51,7 @@ export default function FollowersCards({ id, count }) { <div className="p-3 my-5 rounded-md min-w-[200px] min-h-[180px]"> <div className="flex flex-wrap justify-center"> {followers.map((item, i) => ( - item && ( + item.follower && ( <Fragment key={i}> <UsersPageCard item={item.follower} /> </Fragment> diff --git a/src/app/perfil/[id]/components/FollowingCards.js b/src/app/perfil/[id]/components/FollowingCards.js index b04101d724275a7c75b1949c3e9e5cc41ce71250..cdfbe7a5f64ad7af37b086a100c9e6ede4366aa1 100644 --- a/src/app/perfil/[id]/components/FollowingCards.js +++ b/src/app/perfil/[id]/components/FollowingCards.js @@ -5,6 +5,7 @@ import UsersPageCard from "@/app/components/UsersPageCard"; import { Button } from "@mui/material"; import NotFound from "./NotFound"; import Loading from "@/app/components/Loading"; +import { authHeaders } from "@/app/handlers/loginHandler"; /** * @@ -21,19 +22,14 @@ export default function FollowingCards({ id, count }) { const uid = getStoredValue("uid"); const expiry = getStoredValue("expiry"); const [got, setGot] = useState(false); + useEffect(() => { const fetchData = async () => { try { - const { data } = await mecredApi.get(`/users/${id}/following/User?offset=${numberCards}`, { - headers: { - 'access-token': token, - 'token-type': 'Bearer', - 'client': client, - 'uid': uid, - 'Expires': expiry - } + const { data } = await mecredApi.get(`public/user/follows/${id}`, { + headers: authHeaders() }); - setFollowing((prevFollowing) => [...prevFollowing, ...data]); + setFollowing((prevFollowing) => [...prevFollowing, ...(Array.isArray(data) ? data : [])]); setGot(true); } catch (error) { console.error(error); diff --git a/src/app/perfil/[id]/components/GroupButton.js b/src/app/perfil/[id]/components/GroupButton.js index eb90d0c41f67f310ba6e86dcdd6a9ea59693b7b9..6b1014d1ad8097661b911f0f2596c1106e03a718 100644 --- a/src/app/perfil/[id]/components/GroupButton.js +++ b/src/app/perfil/[id]/components/GroupButton.js @@ -42,8 +42,8 @@ export default function GroupButton({ profileData, idLogin }) { * Fetch de seguir ou parar de seguir outro usuário */ const followHandler = () => { - if (!loginBarrier()) - return + // if (!loginBarrier()) + // return mecredApi.put( `users/${profileData["id"]}/follow/`, {}, @@ -60,21 +60,6 @@ export default function GroupButton({ profileData, idLogin }) { setFollow(!follow); } - - function shareLink(url) { - if (navigator.share) { - navigator.share({ - title: "Compartilhar perfil", - url: url, - }) - .then(() => console.log("Compartilhamento realizado com sucesso")) - .catch((error) => console.error("Erro ao compartilhar:", error)); - } else { - console.log("Compartilhamento nativo não suportado"); - } - } - - /** * Atualiza o perfil para marcar com seguindo */ @@ -85,13 +70,13 @@ export default function GroupButton({ profileData, idLogin }) { const ReportedModal = ({ open, onClose }) => { return ( - <Modal open={open} onClose={onClose} className="grid place-items-center" slotProps={{ - backdrop: { - sx: { - backgroundColor: "rgba(0, 0, 0, 0.3)", // Ajuste a opacidade conforme necessário - }, + <Modal open={open} onClose={onClose} className="grid place-items-center" slotProps={{ + backdrop: { + sx: { + backgroundColor: "rgba(0, 0, 0, 0.3)", // Ajuste a opacidade conforme necessário }, - }}> + }, + }}> <div className="flex flex-col justify-center bg-ice-HC-dark p-5 rounded outline outline-1 outline-ice-HC-white"> <p className="text-xl justify-center flex text-darkGray-HC-white mb-2">O usuário já foi denunciado!</p> <div className="flex flex-row justify-center mt-2"> @@ -111,10 +96,10 @@ export default function GroupButton({ profileData, idLogin }) { return ( <> <div className='pb-4 flex flex-row max-lg:flex-col justify-between max-lg:items-center max-lg:pt-8 max-lg:mr-0 mr-10'> - <div className='flex flex-row gap-4 max-sm:flex-col max-sm:items-center' > + <div className='flex flex-row gap-4 max-sm:flex-col max-sm:items-center' > {idLogin == profileData["id"] ? <button - className={`text-[16px] rounded-[10px] normal-case h-10 font-bold w-48 text-white-HC-dark-underline hover:text-white bg-turquoise-HC-white hover:bg-darkTurquoise-HC-dark outline outline-1 outline-ice-HC-white `} + className={`text-[16px] rounded-[10px] normal-case h-11 font-bold w-44 text-white-HC-dark-underline hover:text-white bg-turquoise-HC-white hover:bg-darkTurquoise-HC-dark outline outline-1 outline-ice-HC-white `} alt="Editar meu perfil" onClick={() => router.push(`/editar/${idLogin}`)} > diff --git a/src/app/perfil/[id]/components/MedalAchievements.js b/src/app/perfil/[id]/components/MedalAchievements.js index 0a6cdfadb0afd4caa635833dbb2ac340a3c01dca..406b17972a509df9c1d52bd515cb9bf0fe01707e 100644 --- a/src/app/perfil/[id]/components/MedalAchievements.js +++ b/src/app/perfil/[id]/components/MedalAchievements.js @@ -3,22 +3,31 @@ import mecredApi, { mecredURL } from '@/axiosConfig'; export default function MedalAchievements({ items }) { + return ( <div className="flex flex-row w-1/3 max-sm:w-full justify-end max-sm:justify-center xl:gap-x-6 max-sm:gap-x-2 md:gap-x-2 md:max-xl:ml-[80px] xl:mr-10 max-sm:mb-5"> - {items?.map((avatar, index) => - avatar.being_used && ( - <div key={index} className="flex shrink-0 flex-row relative"> - <img src="/medalha-exibicao-da-conquista.svg" alt="medal" className=" flex w-[69px] h-[92px] max-sm:w-[50px] invertLogo-HC-white" /> - <Avatar - className="w-[57px] h-[55px] max-sm:w-[40px] max-sm:h-[40px] max-sm:top-4 max-sm:right absolute top-1.5 right-1.5 " - key={avatar.item ? avatar.name : null} - alt={avatar.item ? avatar.item.name : avatar.name} - src={mecredURL + (avatar.item ? avatar.item.image : null)} - /> - </div> + {(items?.length ?? 0) > 0 ? ( + items.map((avatar, index) => + avatar.is_active && ( + <div key={index} className="flex shrink-0 flex-row relative"> + <img + src="/medalha-exibicao-da-conquista.svg" + alt="medal" + className="flex w-[69px] h-[92px] max-sm:w-[50px] invertLogo-HC-white" + /> + <Avatar + className="w-[57px] h-[55px] max-sm:w-[40px] max-sm:h-[40px] max-sm:top-4 max-sm:right absolute top-1.5 right-1.5" + key={avatar.item ? avatar.name : null} + alt={avatar.item ? avatar.item.name : avatar.name} + src={mecredURL + (avatar.item?.image ?? '')} + /> + </div> + ) ) + ) : ( + <div></div> )} </div> - ); + ) } diff --git a/src/app/perfil/[id]/components/ProfileCollections.js b/src/app/perfil/[id]/components/ProfileCollections.js index a598c246027db33c658bbc59f9e6347ce2ea6455..5ff3e82cb339f54e77bd876d18c91f5827ef86a4 100644 --- a/src/app/perfil/[id]/components/ProfileCollections.js +++ b/src/app/perfil/[id]/components/ProfileCollections.js @@ -13,6 +13,7 @@ import EditOutlinedIcon from '@mui/icons-material/EditOutlined'; import EditCollectionModal from "./EditCollectionModal"; import DeleteOutlinedIcon from '@mui/icons-material/DeleteOutlined'; import ShareButton from "@/app/components/ShareButton"; +import { authHeaders } from "@/app/handlers/loginHandler"; const ModalSucess = ({ open, onClose, modalOnClose }) => { return ( @@ -43,14 +44,11 @@ export default function ProfileCollections({ id, idLogin }) { const [editOpen, setEditOpen] = useState(false) const [collections, setCollections] = useState([]) const [totalCount, setTotalCount] = useState(0) - const [deleted, setDeleted] = useState(false) + const [deleted, setDeleted] = useState(false) const [modalOpen, setModalOpen] = useState(false) const [numberCards, setNumberCards] = useState(4) const [deleteOpen, setDeleteOpen] = useState(false) const [colToDelete, setColToDelete] = useState(0) - const token = getStoredValue("access_token"); - const client = getStoredValue("client"); - const uid = getStoredValue("uid"); const [got, setGot] = useState(false) const [cardsPerRow, setCardsPerRow] = useState(0); @@ -79,14 +77,8 @@ export default function ProfileCollections({ id, idLogin }) { if (idLogin === id) { await mecredApi - .get(`/users/${id}/collections?limit=${numberCards}`, { - headers: { - "access-token": token, - "token-type": "Bearer", - client: client, - uid: uid, - Expires: 0, - }, + .get(`api/collections/${id}/all-collections`, { + headers: authHeaders() }) /** * Além de setar as coleções, indica o número total de coleções @@ -94,21 +86,23 @@ export default function ProfileCollections({ id, idLogin }) { */ .then(({ data, headers }) => { setTotalCount(headers["x-total-count"]) - setCollections(data) + setCollections(data.fullCollections) + setGot(true) }); } else { await mecredApi - .get(`/users/${id}/collections?limit=${numberCards}`) + .get(`public/collections/${id}/collections`) .then(({ data, headers }) => { setTotalCount(headers["x-total-count"]) setCollections(data) + console.log(data) setGot(true) }); } }; fetchCollections(id); - }, [id, client, uid, token, numberCards, idLogin, deleted]); + }, [id, numberCards, idLogin, deleted]); /** * Inicialmente sempre vai aparecer 4 coleções para o usuário (se ele tiver mais que 4). @@ -122,13 +116,7 @@ export default function ProfileCollections({ id, idLogin }) { e.preventDefault(); const url = `/collections/${colToDelete}`; - const headers = { - "access-token": token, - "token-type": "Bearer", - client: client, - uid: uid, - Expires: 0, - }; + const headers = authHeaders(); try { await mecredApi.delete(url, { headers }); // Passando o objeto 'headers' corretamente @@ -187,16 +175,16 @@ export default function ProfileCollections({ id, idLogin }) { </button> )} </div> - + <ModalSucess open={modalOpen} onClose={() => setModalOpen(false)} modalOnClose={() => setDeleted(!deleted)} /> - - {collections.length === 0 ? ( + + {collections?.length === 0 ? ( <NotFound name="coleções" /> ) : ( <div className="justify-center mt-5"> - {collections.map((item, index) => ( + {collections?.map((item, index) => ( <div key={index} className="bg-white-HC-dark outline outline-1 outline-ice-HC-white mb-10 pt-6 px-4 rounded-2xl relative"> - + {/* Cabeçalho com título, autor e botões */} <div className="flex justify-between items-start"> {/* Título e autor */} @@ -205,7 +193,12 @@ export default function ProfileCollections({ id, idLogin }) { <Link href={`/colecao/${item.id}`}>{item.name}</Link> </p> <p className="ml-1 text-darkGray-HC-white-underline"> - por <Link className="hover:underline" href={`/perfil/${item.owner.id}`}>{item.owner.name}</Link> + por {item.owner?.id && ( + <Link className="hover:underline" href={`/perfil/${item.owner.id}`}> + {item.owner.name} + </Link> + )} + </p> </div> @@ -219,7 +212,7 @@ export default function ProfileCollections({ id, idLogin }) { <div className="flex gap-4"> {/* Adiciona um espaçamento entre os botões */} {/* Botão de Editar */} <button - className="px-3 py-2 text-sm rounded-xl outline outline-2 outline-ice-HC-white bg-ice-HC-dark hover:bg-ice-HC-dark-hover text-darkGray-HC-white font-bold normal-case max-md:my-3 flex justify-center items-center gap-2 md:px-3 md:py-2" + className="px-3 py-2 text-sm rounded-xl outline outline-1 outline-ice-HC-white bg-ice-HC-dark hover:bg-lightGray-HC-white text-darkGray-HC-white-underline hover:text-darkGray-HC-dark-underline font-bold normal-case max-md:my-3 flex justify-center items-center gap-2 md:px-3 md:py-2" onClick={() => setEditOpen(true)} aria-label="Editar" // Texto para leitores de tela > @@ -229,8 +222,8 @@ export default function ProfileCollections({ id, idLogin }) { {/* Botão de Excluir */} <button - className="p-2 max-md:my-3 text-sm rounded-xl text-black-HC-white font-bold normal-case flex justify-center items-center gap-2 hover:bg-red" - onClick={() => { setDeleteOpen(true); setColToDelete(item.id);} } + className="p-2 max-md:my-3 text-sm rounded-xl text-black-HC-white font-bold normal-case flex justify-center items-center gap-2 hover:bg-red-HC-white hover:text-white-HC-dark" + onClick={() => { setDeleteOpen(true); setColToDelete(item.id); }} aria-label="Excluir" // Texto para leitores de tela > <DeleteOutlinedIcon fontSize="small" /> {/* Ícone de lata de lixo */} @@ -242,13 +235,13 @@ export default function ProfileCollections({ id, idLogin }) { {/* Cartões de coleção abaixo */} <div className="mt-4"> - <GroupCardsCollections data={item.collection_items} cardsPerRow={cardsPerRow} /> + <GroupCardsCollections collectionId={item.id} cardsPerRow={cardsPerRow} /> </div> </div> ))} </div> )} - + {/* Botão "Ver mais" abaixo das coleções */} {numberCards < totalCount && ( <Button @@ -268,6 +261,6 @@ export default function ProfileCollections({ id, idLogin }) { )} </> ); - + } diff --git a/src/app/perfil/[id]/components/ProfileComplaints.js b/src/app/perfil/[id]/components/ProfileComplaints.js index df7bc0b3f458eb7029bf754c2228740b3fbcda40..9c60a40d7be3f34e71b739c2d9930783cae898e8 100644 --- a/src/app/perfil/[id]/components/ProfileComplaints.js +++ b/src/app/perfil/[id]/components/ProfileComplaints.js @@ -4,6 +4,7 @@ import mecredApi from "@/axiosConfig"; import { getStoredValue } from "@/app/handlers/localStorageHandler"; import Loading from "@/app/components/Loading"; import CardsComplaints from "./CardsComplaints"; +import { authHeaders } from "@/app/handlers/loginHandler"; /** * @returns Cards dos recursos para homologação (Só aparece para curadores) @@ -25,14 +26,8 @@ export default function ProfileComplaints({ id }) { useEffect(() => { const fetchComplaints = async (id) => { await mecredApi - .get(`/learning_objects_complaints?offset=0&limit=${numberCards}`, { - headers: { - 'access-token': token, - 'token-type': 'Bearer', - 'client': client, - 'uid': uid, - 'Expires': expiry - } + .get(`api/complaint/resources`, { + headers: authHeaders() }) .then(({ data, headers }) => { setComplaints(data); @@ -57,7 +52,7 @@ export default function ProfileComplaints({ id }) { {got ? ( <Card className='p-3 my-10 rounded-md min-w-[200px] min-h-[180px] bg-white-HC-dark shadow-none '> <div className="flex content flex-wrap justify-center"> - {complaints.map((item, i) => ( + {complaints?.map((item, i) => ( i % 2 === 0 && ( <div key={i} className="flex"> {complaints[i] && <CardsComplaints item={complaints[i]} tag={true} />} diff --git a/src/app/perfil/[id]/components/ProfileHomologation.js b/src/app/perfil/[id]/components/ProfileHomologation.js index 662eb58e7ad679b91a7230d6f4b79d4e7582d44c..d7a36422821b38c73e82cd0dfc1f497c23d776b1 100644 --- a/src/app/perfil/[id]/components/ProfileHomologation.js +++ b/src/app/perfil/[id]/components/ProfileHomologation.js @@ -4,6 +4,7 @@ import mecredApi from "@/axiosConfig"; import { getStoredValue } from "@/app/handlers/localStorageHandler"; import CardsHomologation from "./CardsHomologation"; import Loading from "@/app/components/Loading"; +import { authHeaders } from "@/app/handlers/loginHandler"; /** * @returns Cards dos recursos para homologação (Só aparece para curadores) @@ -22,16 +23,11 @@ export default function ProfileHomologation({ id }) { useEffect(() => { const fetchHomologation = async (id) => { await mecredApi - .get(`/submissions/all_users_submissions/${id}?offset=${numberCards}`, { - headers: { - 'access-token': token, - 'token-type': 'Bearer', - 'client': client, - 'uid': uid, - 'Expires': 0 - } + .get(`api/homologation/all`, { + headers: authHeaders() }) .then(({ data, headers }) => { + console.log(data) setHomologated(prevData => [...prevData, ...data]); setTotalCount(Number(headers["x-total-count"])) setGot(true) @@ -53,7 +49,7 @@ export default function ProfileHomologation({ id }) { {got ? ( <Card className='p-3 my-10 rounded-md min-w-[200px] min-h-[180px] bg-white-HC-dark shadow-none '> <div className="flex content flex-wrap justify-center"> - {homologated.map((item, i) => ( + {homologated?.map((item, i) => ( <CardsHomologation item={item} key={i} /> ))} </div> diff --git a/src/app/perfil/[id]/components/ProfileItens.js b/src/app/perfil/[id]/components/ProfileItens.js index d46d37faebb2683c2f6d9fccba2fced9d9521152..956b84fa6dbedacd07c35f30a23ce032a9b9a9b9 100644 --- a/src/app/perfil/[id]/components/ProfileItens.js +++ b/src/app/perfil/[id]/components/ProfileItens.js @@ -11,320 +11,346 @@ import Link from 'next/link'; import Image from 'next/image'; export default function ProfileItens({ profileData, setItems, items, store, type }) { - const [showDescription, setShowDescription] = useState(null); - const [equip, setEquip] = useState(null); - const [errorEquip, setErrorEquip] = useState(false); - const [fullEquiped, setFullEquiped] = useState(false); - const [buyItem, setBuyItem] = useState(null); - const [arrayAcquired, setArrayAcquired] = useState(new Array(store.length).fill(0)); - - const token = getStoredValue("access_token"); - const client = getStoredValue("client"); - const uid = getStoredValue("uid"); + const [showDescription, setShowDescription] = useState(null); + const [equip, setEquip] = useState(null); + const [errorEquip, setErrorEquip] = useState(false); + const [fullEquiped, setFullEquiped] = useState(false); + const [buyItem, setBuyItem] = useState(null); + const [arrayAcquired, setArrayAcquired] = useState(new Array(store.length).fill(0)); - useEffect(() => { - const handlePurchase = () => { - setArrayAcquired(prev => { - const newArray = [...prev]; - for (let i = 0; i < store.length; i++) - newArray[i] = items.some((obj) => obj.item?.id === store[i]?.id) ? 1 : 0; - return newArray; - }); - } - - handlePurchase(); - }, [items, store]); - - console.log(arrayAcquired); + const token = getStoredValue("access_token"); + const client = getStoredValue("client"); + const uid = getStoredValue("uid"); - const iconEggs = <Image - src="/gema.svg" - alt="gema icon" - width={15} - height={10} - className="inline mx-1 mb-1 invertLogo-HC-white" - /> + useEffect(() => { + const handlePurchase = () => { + setArrayAcquired(prev => { + const newArray = [...prev]; + for (let i = 0; i < store.length; i++) + newArray[i] = items.some((obj) => obj.item?.id === store[i]?.id) ? 1 : 0; + return newArray; + }); + } + handlePurchase(); + }, [items, store]); - const ModalBuyItem = ({ name, price, open, onClose, index, id }) => { - const restEggs = profileData["points"] - price; - - return ( - <Modal - open={open} - onClose={onClose} - className="grid place-items-center m-5" - slotProps={{ - backdrop: { - sx: { - backgroundColor: "rgba(0, 0, 0, 0.3)", - }, - }, - }} - > - <div className="bg-ice-HC-dark outline outline-1 outline-ice-HC-white p-5 rounded-lg"> - <div className='flex justify-end'> - <IconButton onClick={onClose} className='group hover:bg-ice-HC-white'> - <CloseIcon fontSize='large' className='text-darkGray-HC-white group-hover:text-darkGray-HC-dark' /> - </IconButton> - </div> - <div className="flex flex-col gap-5 justify-center "> - <p className="font-bold text-xl text-darkGray-HC-white">Deseja realmente comprar este item?</p> - <p className="font-bold text-darkGray-HC-white">Esta compra não envolve nenhum dinheiro real.</p> - <p className="inline text-darkGray-HC-white">O item que você deseja comprar, - <span className="font-bold"> {name}</span>, custa - <span className="font-bold text-turquoise-HC-white "> {iconEggs} {price}</span> gemas. Você possui - <span className="font-bold text-turquoise-HC-white "> {iconEggs} {profileData["points"]}</span> gemas. - </p> - {restEggs < 0 ? ( - <p className="font-bold text-darkGray-HC-white">Você não possui gemas o suficiente para comprar este item.</p> - ) : ( - <> - <p className="inline text-darkGray-HC-white">Comprar este item lhe deixará com - <span className="font-bold text-turquoise-HC-white "> {iconEggs} {restEggs} </span> - gemas. - </p> - </> - )} - </div> - <div className="flex justify-end mt-4"> - <button onClick={onClose} className="bg-ice-HC-dark p-2 rounded-lg hover:bg-ice-HC-dark-hover text-darkGray-HC-white-underline mr-1">Cancelar</button> - {restEggs >= 0 && ( - <button onClick={() => { - handlePostRequestStore(id, index); - onClose(); // Fecha o modal - }} className="bg-turquoise-HC-white text-white-HC-dark-underline hover:text-white-HC-underline p-2 rounded-lg hover:bg-darkTurquoise-HC-dark ml-4 outline outline-1 outline-ice-HC-white">Comprar</button> - )} - </div> - </div> - </Modal> - ); - } + console.log(arrayAcquired); - const ModalFullEquiped = ({ open, onClose }) => { - return ( - <Modal - open={open} - onClose={onClose} - className="grid place-items-center m-5" - slotProps={{ - backdrop: { - sx: { - backgroundColor: "rgba(0, 0, 0, 0.3)", - }, - }, - }} - > - <div className="bg-ice-HC-dark outline outline-1 outline-ice-HC-white p-5 rounded-lg"> - <div className='flex justify-end'> - <IconButton onClick={onClose} className='group hover:bg-ice-HC-white'> - <CloseIcon fontSize='large' className='text-darkGray-HC-white group-hover:text-darkGray-HC-dark' /> - </IconButton> - </div> - <div className="flex flex-col justify-center "> - <p className="pt-3 text-xl text-darkGray-HC-white">Você só pode equipar até 3 insígnias simultaneamente</p> - </div> - <div className="flex justify-end mt-4"> - <button onClick={onClose} className="bg-ice-HC-dark p-2 rounded-lg hover:bg-ice-HC-dark-hover text-darkGray-HC-white-underline mr-1">Fechar</button> - </div> - </div> - </Modal> - ) - } + const iconEggs = <Image + src="/gema.svg" + alt="gema icon" + width={15} + height={10} + className="inline mx-1 mb-1 invertLogo-HC-white" + /> - const ModalErrorEquip = ({ open, onClose }) => { - return ( - <Modal - open={open} - onClose={onClose} - className="grid place-items-center m-5" - slotProps={{ - backdrop: { - sx: { - backgroundColor: "rgba(0, 0, 0, 0.3)", - }, - }, - }} - > - <div className="outline outline-1 outline-ice-HC-white bg-ice-HC-dark p-5 rounded-lg"> - <div className="flex flex-col items-center justify-center "> - <p className="pt-3 text-xl text-darkGray-HC-white "> - Erro na comunicação com o servidor. - Por favor entre em contato com o suporte: - </p> - <a href="/contato" className="flex mt-4 w-24 bg-turquoise text-md text-white-HC-dark-underline p-2 px-6 justify-center rounded-lg hover:bg-turquoise-hover"> - Contato - </a> - </div> - <div className="flex justify-end mt-4"> - <button onClick={onClose} className="bg-ice-HC-dark p-2 rounded-lg hover:bg-ice-HC-dark-hover text-darkGray-HC-white-underline mr-1">Fechar</button> - </div> - </div> - </Modal> - ) - } - const handlePostRequestStore = async (id, index) => { - try{ - await mecredApi - .post(`/users/purchase_item`, - {"item_id": id}, - { - headers: { - 'access-token': token, - 'token-type': 'Bearer', - 'client': client, - 'uid': uid, - 'Expires': 0 - } - }) - - - setArrayAcquired(prev => { - const newArray = [...prev]; // Cria uma cópia do array - newArray[index] = 1; - return newArray; // Retorna o novo array atualizado - }) - - await mecredApi - .get(`/users/${profileData.id}/items/?item_type=badge&limit=1000`, { - headers: { - 'access-token': token, - 'token-type': 'Bearer', - 'client': client, - 'uid': uid, - 'Expires': 0 - } - }) - .then(({ data }) => { - setItems(data); - }) - .catch(() => setError(true)) + const ModalBuyItem = ({ name, price, open, onClose, index, id }) => { + const restEggs = profileData["points"] - price; + return ( + <Modal + open={open} + onClose={onClose} + className="grid place-items-center m-5" + slotProps={{ + backdrop: { + sx: { + backgroundColor: "rgba(0, 0, 0, 0.3)", + }, + }, + }} + > + <div className="bg-ice-HC-dark outline outline-1 outline-ice-HC-white p-5 rounded-lg"> + <div className='flex justify-end'> + <IconButton onClick={onClose} className='group hover:bg-ice-HC-white'> + <CloseIcon fontSize='large' className='text-darkGray-HC-white group-hover:text-darkGray-HC-dark' /> + </IconButton> + </div> + <div className="flex flex-col gap-5 justify-center "> + <p className="font-bold text-xl text-darkGray-HC-white">Deseja realmente comprar este item?</p> + <p className="font-bold text-darkGray-HC-white">Esta compra não envolve nenhum dinheiro real.</p> + <p className="inline text-darkGray-HC-white">O item que você deseja comprar, + <span className="font-bold"> {name}</span>, custa + <span className="font-bold text-turquoise-HC-white "> {iconEggs} {price}</span> gemas. Você possui + <span className="font-bold text-turquoise-HC-white "> {iconEggs} {profileData["points"]}</span> gemas. + </p> + {restEggs < 0 ? ( + <p className="font-bold text-darkGray-HC-white">Você não possui gemas o suficiente para comprar este item.</p> + ) : ( + <> + <p className="inline text-darkGray-HC-white">Comprar este item lhe deixará com + <span className="font-bold text-turquoise-HC-white "> {iconEggs} {restEggs} </span> + gemas. + </p> + </> + )} + </div> + <div className="flex justify-end mt-4"> + <button onClick={onClose} className="bg-ice-HC-dark p-2 rounded-lg hover:bg-ice-HC-dark-hover text-darkGray-HC-white-underline mr-1">Cancelar</button> + {restEggs >= 0 && ( + <button onClick={() => { + handlePostRequestStore(id, index); + onClose(); // Fecha o modal + }} className="bg-turquoise-HC-white text-white-HC-dark-underline hover:text-white-HC-underline p-2 rounded-lg hover:bg-darkTurquoise-HC-dark ml-4 outline outline-1 outline-ice-HC-white">Comprar</button> + )} + </div> + </div> + </Modal> + ); + } - } catch (error) { - setErrorEquip(true); - console.error("Erro ao fazer a requisição:", error); + const ModalFullEquiped = ({ open, onClose }) => { + return ( + <Modal + open={open} + onClose={onClose} + className="grid place-items-center m-5" + slotProps={{ + backdrop: { + sx: { + backgroundColor: "rgba(0, 0, 0, 0.3)", + }, + }, + }} + > + <div className="bg-ice-HC-dark outline outline-1 outline-ice-HC-white p-5 rounded-lg"> + <div className='flex justify-end'> + <IconButton onClick={onClose} className='group hover:bg-ice-HC-white'> + <CloseIcon fontSize='large' className='text-darkGray-HC-white group-hover:text-darkGray-HC-dark' /> + </IconButton> + </div> + <div className="flex flex-col justify-center "> + <p className="pt-3 text-xl text-darkGray-HC-white">Você só pode equipar até 3 insígnias simultaneamente</p> + </div> + <div className="flex justify-end mt-4"> + <button onClick={onClose} className="bg-ice-HC-dark p-2 rounded-lg hover:bg-ice-HC-dark-hover text-darkGray-HC-white-underline mr-1">Fechar</button> + </div> + </div> + </Modal> + ) + } + + const ModalErrorEquip = ({ open, onClose }) => { + return ( + <Modal + open={open} + onClose={onClose} + className="grid place-items-center m-5" + slotProps={{ + backdrop: { + sx: { + backgroundColor: "rgba(0, 0, 0, 0.3)", + }, + }, + }} + > + <div className="outline outline-1 outline-ice-HC-white bg-ice-HC-dark p-5 rounded-lg"> + <div className="flex flex-col items-center justify-center "> + <p className="pt-3 text-xl text-darkGray-HC-white "> + Erro na comunicação com o servidor. + Por favor entre em contato com o suporte: + </p> + <a href="/contato" className="flex mt-4 w-24 bg-turquoise text-md text-white-HC-dark-underline p-2 px-6 justify-center rounded-lg hover:bg-turquoise-hover"> + Contato + </a> + </div> + <div className="flex justify-end mt-4"> + <button onClick={onClose} className="bg-ice-HC-dark p-2 rounded-lg hover:bg-ice-HC-dark-hover text-darkGray-HC-white-underline mr-1">Fechar</button> + </div> + </div> + </Modal> + ) + } + + const handlePostRequestStore = async (id, index) => { + try { + await mecredApi + .post(`/users/purchase_item`, + { "item_id": id }, + { + headers: { + 'access-token': token, + 'token-type': 'Bearer', + 'client': client, + 'uid': uid, + 'Expires': 0 } + }) + + + setArrayAcquired(prev => { + const newArray = [...prev]; // Cria uma cópia do array + newArray[index] = 1; + return newArray; // Retorna o novo array atualizado + }) + + await mecredApi + .get(`/users/${profileData.id}/items/?item_type=badge&limit=1000`, { + headers: { + 'access-token': token, + 'token-type': 'Bearer', + 'client': client, + 'uid': uid, + 'Expires': 0 + } + }) + .then(({ data }) => { + setItems(data); + }) + .catch(() => setError(true)) + + + } catch (error) { + setErrorEquip(true); + console.error("Erro ao fazer a requisição:", error); } + } - {/* + {/* id: id do item a ser alterado url: É a variação se vai equipar ou desequipar tal item index: A posição do item na lista de itens do json */} - const handlePostRequestItem = async (id, url, index) => { + const handlePostRequestItem = async (id, url, index) => { - const result = items.filter((item) => item.being_used === true); + const result = items.filter((item) => item.being_used === true); - if (result.length === 3 && url === "equip_item" ) { - setFullEquiped(true); - return; - } - - items[index].being_used = !items[index].being_used; - setItems([...items]); - - console.log(profileData["user_items"]); + if (result.length === 3 && url === "equip_item") { + setFullEquiped(true); + return; + } + + items[index].being_used = !items[index].being_used; + setItems([...items]); - try{ - await mecredApi - .post(`/users/${url}`, - {"item_id": id}, - { - headers: { - 'access-token': token, - 'token-type': 'Bearer', - 'client': client, - 'uid': uid, - 'Expires': 0 - } - }) - } catch (error) { - setErrorEquip(true); - console.error("Erro ao fazer a requisição:", error); - } + console.log(profileData["user_items"]); + try { + await mecredApi + .post(`/users/${url}`, + { "item_id": id }, + { + headers: { + 'access-token': token, + 'token-type': 'Bearer', + 'client': client, + 'uid': uid, + 'Expires': 0 + } + }) + } catch (error) { + setErrorEquip(true); + console.error("Erro ao fazer a requisição:", error); } - - return ( - <> - <ModalErrorEquip open={errorEquip} onClose={() => setErrorEquip(false)} /> - <ModalFullEquiped open={fullEquiped} onClose={() => setFullEquiped(false)} /> - {/* Cards de itens do usuário*/} - {(type === "item" ? items : store)?.map((e, index) => { - - return ( - <div key={index} className="relative flex flex-c bg-ice-HC-dark w-[250px] h-[370px] justify-center outline outline-1 outline-ice-HC-white rounded-2xl m-2 text-center"> - {/* Parte de trás (detalhes) */} - {showDescription == index && ( - <div className="absolute inset-0 flex flex-col gap-5 text-[100%] text-darkGray-HC-white bg-ice-HC-dark bg-opacity-90 p-6 rounded-2xl pt-8 z-10 text-left"> - <div className="h-[270px] flex flex-col gap-6"> - <p className="font-bold">{e.item?.name || e.name}</p> - <p className="font-light overflow-y-auto scrollbar-none">{e.item?.description || e.description}</p> - </div> - - <button - className="absolute bottom-0 pb-8 text-turquoise-HC-white-underline hover:text-darkTurquoise-HC-white text-left" - onClick={() => setShowDescription(null)} - > - Voltar - </button> - </div> - )} + } - <div className="relative flex flex-col text-xs pt-8" > - <div className="flex justify-center items-center text-darkGray-HC-white-underline pb-4"> - <Avatar - alt={e.item?.name || e.name} - src={mecredURL + (e.item?.image || e.image)} - sx={{ width: 145, height: 145 }} - /> - </div> - <div className="flex flex-col justify-center text-base items-center"> - {(e.item === undefined) ? ( - <> - <h1 className="flex text-lg text-darkGray-HC-white text-[100%] font-bold px-6 items-center min-h-[40px]"> - {e.item?.name || e.name} - </h1> - <button className="text-turquoise-HC-white-underline hover:text-darkTurquoise-HC-white pb-2" onClick={() => setShowDescription(index)}>Ver mais</button> - <div className='flex flex-wrap gap-x-4'> - <h1 className='flex text-darkGray-HC-white font-bold gap-x-1'>{iconEggs}{e.price}</h1> - </div> - <ModalBuyItem - name={e.name} - price={e.price} - open={buyItem === e.id} - onClose={() => setBuyItem(null)} - index={index} - id={e.id} - /> - <button className="flex h-[43px] w-[158px] justify-center items-center bg-lightGray-HC-dark hover:bg-darkGray-HC-white rounded-[10px] outline outline-1 outline-ice-HC-white font-bold text-darkGray-HC-white-underline hover:text-white-HC-dark-underline mt-2" - onClick={() => !arrayAcquired[index] && setBuyItem(e.id)} - > - {arrayAcquired[index] ? "Adquirido" : "Comprar"} - </button> - </> - ) : ( - <> - <h1 className="flex text-lg text-darkGray-HC-white text-[100%] font-bold px-6 items-center min-h-[60px]"> - {e.item?.name || e.name} - </h1> - <button className="text-turquoise-HC-white-underline hover:text-darkTurquoise-HC-white" onClick={() => setShowDescription(index)}>Ver mais</button> - <button className="flex h-[43px] w-[158px] justify-center items-center bg-lightGray-HC-dark hover:bg-darkGray-HC-white rounded-[10px] outline outline-1 outline-ice-HC-white font-bold text-darkGray-HC-white hover:text-white-HC-dark-underline mt-4" - onClick={() => handlePostRequestItem(e.item?.id || null, e.being_used ? "unequip_item" : "equip_item", index)} - > - {e.being_used ? "Desequipar" : "Equipar"} - </button> - </> - )} - - </div> - </div> - </div> - ); - })} - </> - ); -} + return ( + <> + <ModalErrorEquip open={errorEquip} onClose={() => setErrorEquip(false)} /> + <ModalFullEquiped open={fullEquiped} onClose={() => setFullEquiped(false)} /> + {/* Cards de itens do usuário */} + {(type === "item" ? items : store)?.length > 0 ? ( + (type === "item" ? items : store).map((e, index) => { + return ( + <div + key={index} + className="relative flex flex-c bg-ice-HC-dark w-[250px] h-[370px] justify-center outline outline-1 outline-ice-HC-white rounded-2xl m-2 text-center" + > + {/* Parte de trás (detalhes) */} + {showDescription == index && ( + <div className="absolute inset-0 flex flex-col gap-5 text-[100%] text-darkGray-HC-white bg-ice-HC-dark bg-opacity-90 p-6 rounded-2xl pt-8 z-10 text-left"> + <div className="h-[270px] flex flex-col gap-6"> + <p className="font-bold">{e.item?.name || e.name}</p> + <p className="font-light overflow-y-auto scrollbar-none"> + {e.item?.description || e.description} + </p> + </div> + <button + className="absolute bottom-0 pb-8 text-turquoise-HC-white-underline hover:text-darkTurquoise-HC-white text-left" + onClick={() => setShowDescription(null)} + > + Voltar + </button> + </div> + )} + + <div className="relative flex flex-col text-xs pt-8"> + <div className="flex justify-center items-center text-darkGray-HC-white-underline pb-4"> + <Avatar + alt={e.item?.name || e.name} + src={mecredURL + (e.item?.image || e.image)} + sx={{ width: 145, height: 145 }} + /> + </div> + <div className="flex flex-col justify-center text-base items-center"> + {e.item === undefined ? ( + <> + <h1 className="flex text-lg text-darkGray-HC-white text-[100%] font-bold px-6 items-center min-h-[40px]"> + {e.item?.name || e.name} + </h1> + <button + className="text-turquoise-HC-white-underline hover:text-darkTurquoise-HC-white pb-2" + onClick={() => setShowDescription(index)} + > + Ver mais + </button> + <div className="flex flex-wrap gap-x-4"> + <h1 className="flex text-darkGray-HC-white font-bold gap-x-1"> + {iconEggs} + {e.price} + </h1> + </div> + <ModalBuyItem + name={e.name} + price={e.price} + open={buyItem === e.id} + onClose={() => setBuyItem(null)} + index={index} + id={e.id} + /> + <button + className="flex h-[43px] w-[158px] justify-center items-center bg-lightGray-HC-dark hover:bg-darkGray-HC-white rounded-[10px] outline outline-1 outline-ice-HC-white font-bold text-darkGray-HC-white-underline hover:text-white-HC-dark-underline mt-2" + onClick={() => + !arrayAcquired[index] && setBuyItem(e.id) + } + > + {arrayAcquired[index] ? "Adquirido" : "Comprar"} + </button> + </> + ) : ( + <> + <h1 className="flex text-lg text-darkGray-HC-white text-[100%] font-bold px-6 items-center min-h-[60px]"> + {e.item?.name || e.name} + </h1> + <button + className="text-turquoise-HC-white-underline hover:text-darkTurquoise-HC-white" + onClick={() => setShowDescription(index)} + > + Ver mais + </button> + <button + className="flex h-[43px] w-[158px] justify-center items-center bg-lightGray-HC-dark hover:bg-darkGray-HC-white rounded-[10px] outline outline-1 outline-ice-HC-white font-bold text-darkGray-HC-white hover:text-white-HC-dark-underline mt-4" + onClick={() => + handlePostRequestItem( + e.item?.id || null, + e.being_used ? "unequip_item" : "equip_item", + index + ) + } + > + {e.being_used ? "Desequipar" : "Equipar"} + </button> + </> + )} + </div> + </div> + </div> + ); + }) + ) : <div></div>} + </> + ); +} \ No newline at end of file diff --git a/src/app/perfil/[id]/components/ProfileResources.js b/src/app/perfil/[id]/components/ProfileResources.js index 5b4bcbd429e2e5c0478174b251b0174a3ee93d76..e5098627e4bf94182552edfbdde49e5d0c6e1e9d 100644 --- a/src/app/perfil/[id]/components/ProfileResources.js +++ b/src/app/perfil/[id]/components/ProfileResources.js @@ -6,6 +6,7 @@ import { getStoredValue } from "@/app/handlers/localStorageHandler"; import { Button, Card } from "@mui/material"; import NotFound from "./NotFound"; import Loading from "@/app/components/Loading"; +import { authHeaders } from "@/app/handlers/loginHandler"; /** * @returns Recursos do usuário @@ -15,12 +16,10 @@ import Loading from "@/app/components/Loading"; * */ export default function ProfileResources({ id, idLogin }) { + //Concateno tanto os arrays de recursos em homologação quanto aceitos + const [uniqueResources, setUniqueResources] = useState([]) const [resources, setResources] = useState([]) const [homologaResources, setHomologaResources] = useState([]) - const token = getStoredValue("access_token") - const client = getStoredValue("client") - const uid = getStoredValue("uid") - const expiry = getStoredValue("expiry") const [numberCards, setNumberCards] = useState(0) const [resourcesCount, setResourcesCount] = useState(0) const [homologaCount, setHomologaCount] = useState(0) @@ -30,14 +29,8 @@ export default function ProfileResources({ id, idLogin }) { useEffect(() => { const fetchLearningObjects = async (id) => { await mecredApi - .get(`/users/${id}/learning_objects?offset=${numberCards}`, { - headers: { - 'access-token': token, - 'token-type': 'Bearer', - 'client': client, - 'uid': uid, - 'Expires': expiry - } + .get(`public/resource/allResourceByUser/${id}?offset=${numberCards}`, { + headers: authHeaders() }) .then(({ data, headers }) => { setResourcesCount(Number(headers["x-total-count"])); @@ -48,22 +41,17 @@ export default function ProfileResources({ id, idLogin }) { .catch((error) => { console.error(error); }); + }; const fetchSubmissions = async (id) => { await mecredApi .get(`/submissions/user_submissions/${id}`, { - headers: { - 'access-token': token, - 'token-type': 'Bearer', - 'client': client, - 'uid': uid, - 'Expires': expiry - } + headers: authHeaders() }) .then(({ data }) => { setHomologaResources((prevHomologaResources) => [...prevHomologaResources, ...data]); - setHomologaCount(data.length); + setHomologaCount(data.length); }) .catch((error) => { console.error(error); @@ -73,9 +61,9 @@ export default function ProfileResources({ id, idLogin }) { fetchLearningObjects(id); //só aparece os recursos em homologação se o perfil acessado for o mesmo do logado - if (idLogin === id) fetchSubmissions(id); + if (idLogin === id) fetchSubmissions(id); - }, [id, numberCards, token, client, uid, expiry, idLogin]); + }, [id, numberCards, idLogin]); const toggleContent = () => { setNumberCards(numberCards + 12) @@ -85,7 +73,58 @@ export default function ProfileResources({ id, idLogin }) { setTotalCount(resourcesCount + homologaCount) }, [resourcesCount, homologaCount]) + useEffect(() => { + if (resources.length > 0 || homologaResources.length > 0) { + + const unified = [...resources, ...homologaResources]; + + // Remove recursos duplicados com base no id (Retorna a primeira ocorrência) + const remove_duplicates = unified.filter((item, index, array) => { + return array.findIndex(obj => obj.id === item.id) === index; + }); + + // Atualiza o estado com os únicos + setUniqueResources(remove_duplicates); + } + }, [resources, homologaResources]); + + const [imageMap, setImageMap] = useState({}); + + const verifyImage = async (id) => { + try { + await mecredApi.get(`public/s3/get/thumbnail/resource/${id}`, { + headers: authHeaders() + }); + return true; // Existe + } catch (error) { + if (error.response && error.response.status === 404) { + return false; // Não existe + } + return false; + } + }; + + useEffect(() => { + const checkImages = async () => { + const map = {}; + + await Promise.all( + resources.map(async (resource) => { + const exists = await verifyImage(resource.id); + map[resource.id] = exists; + }) + ); + + setImageMap(map); + }; + + if (resources.length) { + checkImages(); + } + }, [resources]); + + return ( <> {got ? ( @@ -113,14 +152,20 @@ export default function ProfileResources({ id, idLogin }) { ) : ( <div className="p-3 my-5 mb-24 mx-5 rounded-md min-w-[200px] min-h-[180px] bg-white-HC-dark "> <div className="flex flex-wrap justify-center"> - {resources.map((resource, index) => ( + {uniqueResources.map((resource, index) => ( <Cards - id={resource.id} + id={resource.learning_object?.id || resource?.id} key={index} title={resource.name} - author={resource.publisher.name} - avatar={resource.publisher.avatar} - image={resource.thumbnail} + author={resource.author} agora a api retorna + avatar={`https://s3.c3sl.ufpr.br/mecredteste/avatar/${id}`} + image={ + imageMap[resource.id] + ? `https://s3.c3sl.ufpr.br/mecredteste/thumbnail/resource/${resource.id}` + : null + } + + type={resource.objectTypeName} updated_at={resource.updated_at} /> ))} @@ -128,11 +173,16 @@ export default function ProfileResources({ id, idLogin }) { <Cards id={resource.id} key={index} - title={resource.learning_object.name} - author={resource.learning_object.author} - avatar={resource.submitter.avatar} - image={resource.learning_object.thumbnail} - updated_at={resource.learning_object.updated_at} + title={resource.name} + author={resource.author} + avatar={`https://s3.c3sl.ufpr.br/mecredteste/avatar/${id}`} + image={ + imageMap[resource.id] + ? `https://s3.c3sl.ufpr.br/mecredteste/thumbnail/resource/${resource.id}` + : null + } + type={resource.objectTypeName} + updated_at={resource.updated_at} homologa={resource.status} /> ))} diff --git a/src/app/perfil/[id]/components/SelectionButtons.js b/src/app/perfil/[id]/components/SelectionButtons.js index e4cfa8e841c9d29b0950bc6b1884c3232ef0759c..2254b1cb6a49a0df7b7a5a6f3c8f71d97ab14e12 100644 --- a/src/app/perfil/[id]/components/SelectionButtons.js +++ b/src/app/perfil/[id]/components/SelectionButtons.js @@ -7,11 +7,11 @@ import { useState } from "react"; * @return Botões de informações que o usuário pode acessar * @param {Object} props * @param {Function} props.setOptButton - * @param {Boolean} props.verifyCurator `true` se for curador, `false` se não. + * @param {Boolean} props.setUserVerified `true` se for curador, `false` se não. * @param {Number} props.idProfile * @param {Number} props.idLogin */ -export default function SelectionButtons({ setOptButton, verifyCurator, idProfile, idLogin, options }) { +export default function SelectionButtons({ setOptButton, userVerified, idProfile, idLogin, options }) { const [value, setValue] = useState(0) const handleChange = (e, newValue) => { @@ -27,7 +27,7 @@ export default function SelectionButtons({ setOptButton, verifyCurator, idProfil // o usuário só consegue ver seguidores e seguindos quando logado const buttons = options.map(obj => obj.name) - + return ( <div className="" > @@ -40,7 +40,7 @@ export default function SelectionButtons({ setOptButton, verifyCurator, idProfil TabIndicatorProps={{ style: { background: "var(--turquoise-HC-white)" } }} > {buttons.map((item, index) => { - + return ( <Tab className="text-[16px] py-5 normal-case text-darkGray-HC-white" key={index} value={index} label={<p className="text-darkGray-HC-white-underline">{item}</p>} /> ) @@ -59,16 +59,22 @@ export default function SelectionButtons({ setOptButton, verifyCurator, idProfil variant="scrollable" scrollButtons="auto" allowScrollButtonsMobile + TabIndicatorProps={{ style: { background: "var(--turquoise-HC-white)" } }} className="text-darkGray-HC-white" > {buttons.map((item, index) => { return ( - <Tab key={index} value={index} label={item} /> + <Tab + key={index} + value={index} + label={<p className="text-darkGray-HC-white-underline">{item}</p>} + /> ) })} </Tabs> + <hr style={{ borderTop: "1px solid var(--lightGray-HC-white)" }} /> </div> </div> diff --git a/src/app/perfil/[id]/components/Stats.js b/src/app/perfil/[id]/components/Stats.js index 3c30e1c4404fa1e7bc8fdb541fe8d679752c108e..3975f77ba6074840fa9ba268eb086de2f02b58f8 100644 --- a/src/app/perfil/[id]/components/Stats.js +++ b/src/app/perfil/[id]/components/Stats.js @@ -26,12 +26,12 @@ export default function ProfileStats({ profileData, achievements, progresses, it value: achievements?.length, src: "/conquistas.svg" }, - { - icon: <RotateRightTwoToneIcon fontSize="large"/>, - name: "Progresso:", - value: progresses?.length, - src: "/progressos.svg" - }, + // { + // icon: <RotateRightTwoToneIcon fontSize="large"/>, + // name: "Progresso:", + // value: progresses?.length, + // src: "/progressos.svg" + // }, { icon: <BusinessCenterTwoToneIcon fontSize="large"/>, name: "Itens:", @@ -51,13 +51,17 @@ export default function ProfileStats({ profileData, achievements, progresses, it <> <div className='flex flex-row justify-between px-1 max-xl:grid max-xl:grid-cols-3 max-xl:gap-5 max-md:flex max-md:flex-nowrap max-md:overflow-x-auto mt-[42px] max-md:scrollbar-none max-md:animate-scrollHint'> {statsArray.map((item, index) => ( - <div key={index} className='flex justify-center px-4 2xl:w-[210px] h-[60px] gap-0.5 items-center bg-white-HC-dark rounded-[10px] whitespace-nowrap text-[80%%] font-light text-darkGray-HC-white outline outline-1 outline-ice-HC-white'> + <div key={index} className='flex justify-center px-4 2xl:w-[210px] h-[60px] gap-0.5 items-center bg-white-HC-dark rounded-[10px] whitespace-nowrap text-[80%%] font-light text-darkGray-HC-white max-md:my-1 outline outline-1 outline-ice-HC-white'> <img className="flex h-[26px] px-1 invertLogo-HC-white" src={item.src} alt={item.name} /> - <h1 className="flex">{item.name} {item.value}</h1> + <h1 className="flex">{item.name} + {item.value? + item.value : 0 + } + </h1> </div> ))} </div> diff --git a/src/app/perfil/[id]/components/UserCard.js b/src/app/perfil/[id]/components/UserCard.js index a5251ea8311a5ab85632247003c877f3f7a1c91f..fd8b617e9836bfa16f98282996364e46366087cf 100644 --- a/src/app/perfil/[id]/components/UserCard.js +++ b/src/app/perfil/[id]/components/UserCard.js @@ -7,7 +7,7 @@ import { Avatar } from '@mui/material'; import { useEffect, useState } from 'react'; import { getStoredValue } from '@/app/handlers/localStorageHandler'; import mecredApi, { mecredURL } from '@/axiosConfig'; -import { isLoggedIn } from '@/app/handlers/loginHandler'; +import { authHeaders, isLoggedIn, useLoggedIn, userData } from '@/app/handlers/loginHandler'; import Stats from './Stats'; import MedalAchievements from './MedalAchievements'; import AboutCard from "./AboutCard"; @@ -18,7 +18,9 @@ import FollowingCards from "./FollowingCards"; import FollowersCards from "./FollowersCards"; import ProfileComplaints from "./ProfileComplaints"; import ProfileAchievementsMenu from "./ProfileAchievementsMenu"; +import { Person } from "@mui/icons-material"; +/* Não precisa mais com o Verificado const roles = [ { id: 1, @@ -71,24 +73,20 @@ const roles = [ translate: "" } -] +] */ function getRandomBg(id) { const colors = [ "bg-turquoise-HC-white", "bg-orange-HC-white", - "bg-turquoise-hover", - "bg-darkOrange-HC-gray ", + "bg-darkTurquoise-HC-white", + "bg-darkOrange-HC-white ", "bg-violet-HC-white", "bg-pink-HC-white", "bg-red-HC-white", "bg-darkGray-HC-white", - "bg-darkGray-HC-white-click", - "bg-ice-HC-dark ", - "bg-darkGray-HC-white", - "bg-darkGray-HC-white", - "bg-turquoise-HC-dark", + "bg-ice-HC-white", ] return colors[id % colors.length]; @@ -100,49 +98,37 @@ function getRandomBg(id) { * @param {Array.<Object>} props.profileData * @param {Number} props.idLogin */ -export default function UserCard({ profileData, idLogin, achievements, progresses, setItems, items, store}) { +export default function UserCard({ profileData, idLogin, achievements, progresses, setItems, items, store }) { const [followers, setFollowers] = useState(0) const [following, setFollowing] = useState(0) - const [translateItems, setTranslateItems] = useState("") + // const [translateItems, setTranslateItems] = useState("") Não precisa mais com o Verificado const [optButton, setOptButton] = useState(0) const [verifyCurator, setVerifyCurator] = useState(false) + const [userVerified, setUserVerified] = useState(false) + const [medalActive, setMedalActive] = useState(0) + const [profileInfo, setProfileInfo] = useState("") + const loggedIn = useLoggedIn() /** * faz fetch dos seguidores e seguindo, se não estiver logado não aparece essa informação */ useEffect(() => { - if (!isLoggedIn) + if (!loggedIn) return; + setProfileInfo(userData()["user"]) + console.log(profileData) const fetchFollowers = async () => { - const token = getStoredValue("access_token") - const client = getStoredValue("client") - const uid = getStoredValue("uid") - const expiry = getStoredValue("expiry") - - await mecredApi.get('/users/' + profileData["id"] + "/followers", { - headers: { - 'access-token': token, - 'token-type': 'Bearer', - 'client': client, - 'uid': uid, - 'Expires': expiry - } - + await mecredApi.get(`public/user/followers/${profileData.id}`, { + headers: authHeaders() }) .then(({ headers }) => setFollowers(Number(headers["x-total-count"]))) .catch((error) => { console.error(error) }) - await mecredApi.get('/users/' + profileData["id"] + "/following/User", { - headers: { - 'access-token': token, - 'token-type': 'Bearer', - 'client': client, - 'uid': uid, - 'Expires': expiry - } + await mecredApi.get(`public/user/follows/${profileData.id}`, { + headers: authHeaders() }) .then(({ headers }) => { @@ -153,90 +139,109 @@ export default function UserCard({ profileData, idLogin, achievements, progresse }) } - fetchFollowers() + //Conta quantas medalhas ativas o usuário possui + // const countMedalBeingUsed = items?.filter(item => item.being_used).length; + // setMedalActive(countMedalBeingUsed) - /** - * Função que faz a tradução conforme os cargos do usuário. - * Busca em `roles` qual respectiva tradução no array. - * A função trata cargos repetidos e, como "submitter" é um cargo de todos os usuários, é retirado da lista. - * Função serve também para verificar se o usuário (no caso, o usuário logado) é curador, para ter permissão de homologação - */ - const itemsRoles = async () => { - let items = [] - for (let i = 0; i < profileData["roles"].length; i++) { - let found = roles.find((element) => profileData["roles"][i]["name"] === element.role) - - if (!items.includes(found.translate) && found.role !== "submitter") items.push(found.translate) + fetchFollowers() + // Função que análisa se o usuário é considerado "verificado" conforme cargo + const verifier = async () => { + const all_roles = [ + "teacher", "admin", "curator", "moderator", + "supervisor", "editor", "partner", "publisher", "submitter" + ]; + + // Extrai todos os nomes dos cargos do usuário + const user_roles = profileData["roles"].map(role => role.name); + + // Verifica se algum cargo do usuário está na lista de roles permitidos + const verifier_user_roles = user_roles.find(role => all_roles.includes(role)); + + if (verifier_user_roles) { + setUserVerified(true); } + }; + verifier() - setVerifyCurator(items.includes("Curador")) - return items.join(' | '); - } - itemsRoles() - .then(roles => setTranslateItems(roles)) - }, [profileData]) + }, [items, profileData]) /* * Menu de seleção do usuário * Verifica se o usuário está logado para definir as opções */ - let options = [{ name: "Sobre", component: <AboutCard content={profileData["description"]} /> }] - - if (isLoggedIn() && profileData["id"] == idLogin) { + let options = [{ name: "Sobre", component: <AboutCard content={profileData.description} /> }] + if (profileData.id == profileInfo.id) { options.push({ name: "Conquistas", component: <ProfileAchievementsMenu profileData={profileData} achievements={achievements} progresses={progresses} setItems={setItems} items={items} store={store} /> }, - { name: "Meus Recursos", component: <ProfileResources id={profileData["id"]} idLogin={idLogin} /> }, - { name: "Minhas Coleções", component: <ProfileCollections id={profileData["id"]} idLogin={idLogin} /> }, - { name: "Seguidores", component: <FollowersCards id={profileData["id"]} count={followers} /> }, - { name: "Seguindo", component: <FollowingCards id={profileData["id"]} count={following} /> }, + { name: "Meus Recursos", component: <ProfileResources id={profileData.id} idLogin={idLogin} /> }, + { name: "Minhas Coleções", component: <ProfileCollections id={profileData.id} idLogin={idLogin} /> }, + { name: "Seguidores", component: <FollowersCards id={profileData.id} count={followers} /> }, + { name: "Seguindo", component: <FollowingCards id={profileData.id} count={following} /> }, ) - if (verifyCurator) { + if (userVerified) { options.push( - { name: "Homologação", component: <ProfileHomologation id={profileData["id"]} /> }, - { name: "Denúncias", component: <ProfileComplaints id={profileData["id"]} /> } + { name: "Homologação", component: <ProfileHomologation id={profileData.id} /> }, + { name: "Denúncias", component: <ProfileComplaints id={profileData.id} /> } ) } } - else if (profileData["id"] == 0) { + else if (profileData.id == 0) { options.push( - { name: "Recursos", component: <ProfileResources id={profileData["id"]} idLogin={idLogin} /> }, - { name: "Coleções", component: <ProfileCollections id={profileData["id"]} idLogin={idLogin} /> }, + { name: "Recursos", component: <ProfileResources id={profileData.id} idLogin={idLogin} /> }, + { name: "Coleções", component: <ProfileCollections id={profileData.id} idLogin={idLogin} /> }, ) } else { options.push( - { name: "Recursos", component: <ProfileResources id={profileData["id"]} idLogin={idLogin} /> }, - { name: "Coleções", component: <ProfileCollections id={profileData["id"]} idLogin={idLogin} /> }, - { name: "Seguidores", component: <FollowersCards id={profileData["id"]} count={followers} /> }, - { name: "Seguindo", component: <FollowingCards id={profileData["id"]} count={following} /> }, + { name: "Recursos", component: <ProfileResources id={profileData.id} idLogin={idLogin} /> }, + { name: "Coleções", component: <ProfileCollections id={profileData.id} idLogin={idLogin} /> }, + { name: "Seguidores", component: <FollowersCards id={profileData.id} count={followers} /> }, + { name: "Seguindo", component: <FollowingCards id={profileData.id} count={following} /> }, ) } + const [imageExists, setImageExists] = useState(false); + const imageUrl = `https://s3.c3sl.ufpr.br/mecredteste/avatar/${profileData.id}`; + useEffect(() => { + const checkImage = async () => { + await mecredApi.get(`public/s3/get/avatar/${profileData.id}`, { + headers: authHeaders() + }) + .then(({ headers }) => setImageExists(true)) + .catch((error) => { + setImageExists(false) + }) + }; + + checkImage(); + }, [profileData.id]); + return ( - <div className='overflow-y-auto min-h-dvh ml-[30px] mr-[80px] max-md:mx-[20px] max-md:mb-24 '> + <div className='overflow-y-auto min-h-dvh max-md:mx-[20px] max-md:mb-24 '> <div className='flex flex-col'> - <div className='flex max-lg:flex-col rounded-2xl gap-4 max-sm:gap-0 max-lg:items-center bg-white-HC-dark outline outline-1 outline-ice-HC-white' > + <div className='flex max-md:mx-1 mx-0.5 mt-2 max-lg:flex-col rounded-2xl gap-4 max-sm:gap-0 max-lg:items-center bg-white-HC-dark outline outline-1 outline-ice-HC-white' > <div className='p-10 max-sm:p-0 h-full items-center'> - {/*a imagem do usuário tem nomes diferentes no backend se for usuário público ou não */} - {profileData["avatar"] ? - <Avatar src={mecredURL + profileData["avatar"]} sx={{ position: "inherit" }} alt="Foto de perfil" className=" h-[276px] w-[276px] " /> + {imageExists ? + <Avatar src={imageUrl} sx={{ position: "inherit" }} alt="Foto de perfil" className=" h-[276px] w-[276px] " /> : - <div className={`flex items-center justify-center text-8xl font-bold text-ice-HC-dark rounded-full h-[276px] w-[276px] bg-turquoise-HC-white ${getRandomBg(profileData["id"])}`} >{profileData["name"][0]}</div> + <div className={`flex items-center justify-center text-8xl font-bold text-ice-HC-dark rounded-full h-[276px] w-[276px] bg-turquoise-HC-white ${getRandomBg(profileData["id"])}`} >{profileData.name[0]}</div> } + </div> <div className='flex flex-col pt-12 max-lg:pt-2 pb-6 justify-between w-full '> - <div className=' flex flex-col justify-start '> + <div className=' flex flex-col justify-start '> <div className='flex flex-row max-sm:flex-col-reverse'> - <div className='flex flex-row w-2/3 max-sm:w-full items-center text-darkGray-HC-white font-bold max-sm:text-3xl text-4xl max-sm:mr-5 max-sm:mb-6'> - <div className='bg-lightGray-HC-white shrink-0 rounded-full max-lg:w-[20px] max-lg:h-[20px] w-[28px] h-[28px] mx-4 aspect-square p-0 m-0' /> {profileData["name"]} + <div className={`flex flex-row w-2/3 max-sm:w-full items-center text-darkGray-HC-white font-bold max-sm:text-3xl text-4xl max-sm:mr-5 max-sm:mb-5 ${medalActive === 0 ? "mb-3" : ""}`}> + <img src="/usuario-perfil.svg" alt="perfil" className='flex aspect-square mr-4 max-lg:mx-4 w-[28px] h-[28px] rounded-full' /> + <div className='shrink-0 max-lg:w-[20px] max-lg:h-[20px] h-[28px] p-0 m-0' /> {profileData["name"]} </div> {/* Medalhas de conquistas do usuário*/} @@ -244,41 +249,48 @@ export default function UserCard({ profileData, idLogin, achievements, progresse </div> - {profileData["email"] && profileData["id"] !== 35342 && ( + {/* {profileData["email"] && profileData["id"] !== 35342 && ( <div className='mb-3 truncate flex flex-row items-center text-darkGray-HC-white max-sm:text-base text-2xl'> - <div className='bg-lightGray-HC-white shrink-0 rounded-full w-[28px] h-[28px] max-lg:w-[20px] max-lg:h-[20px] mx-4 aspect-square' /> + <img src="/ocupacao.svg" alt="ocupacao" className='flex aspect-square mr-4 max-lg:mx-4 w-[28px] h-[28px] rounded-full' /> + <div className='shrink-0 h-[28px] max-lg:w-[20px] max-lg:h-[20px]' /> {profileData["email"]} </div> - )} + )} */} <div className='mb-3'> - {translateItems && - <div className='flex flex-row items-center mt-1 text-darkGray-HC-white max-sm:text-base text-xl'> - <div className='bg-lightGray-HC-white shrink-0 rounded-full w-[28px] h-[28px] max-lg:w-[20px] max-lg:h-[20px] mx-4 aspect-square' /> - {translateItems}</div> + {userVerified && + <div className='flex flex-row items-center mt-3 text-darkGray-HC-white max-sm:text-base text-xl'> + <img + src="/usuario-verificado.svg" + alt="verificado" + className='flex aspect-square mr-4 max-lg:mx-4 w-[28px] h-[28px] rounded-full' + /> + <span>Usuário verificado</span> + </div> } </div> </div> {/*Botões de editar perfil e compartilhar */} - <GroupButton profileData={profileData} idLogin={idLogin} /> + <GroupButton profileData={profileData} idLogin={profileInfo.id} /> </div> </div> {/* Stats do usuário*/} + {/* Não há um funcionamento definido, portanto, colocar depois com as rotas estabelecidas */} <Stats profileData={profileData} achievements={achievements} progresses={progresses} items={items} /> {/* Botões de recursos, sobre, coleções e homologação, mostra quais botões para cada usuário */} - <div className='rounded-2xl min-w-[200px] mt-10 bg-white-HC-dark outline outline-1 outline-ice-HC-white'> - {<SelectionButtons options={options} setOptButton={setOptButton} verifyCurator={verifyCurator} idLogin={idLogin} idProfile={profileData["id"]} />} + <div className='max-md:mx-1 max-md:mb-1 rounded-2xl min-w-[200px] mt-10 bg-white-HC-dark outline outline-1 outline-ice-HC-white'> + {<SelectionButtons options={options} setOptButton={setOptButton} userVerified={userVerified} idLogin={idLogin} idProfile={profileData["id"]} />} {/* Faz a escolha correta de qual botão o usuário clicou */} <ProfileOptions options={options} content={profileData["description"]} optButton={optButton} id={profileData["id"]} - idLogin={idLogin} + idLogin={profileInfo.id} followersCount={followers} followingCount={following} achievements={achievements} diff --git a/src/app/perfil/[id]/page.js b/src/app/perfil/[id]/page.js index 431cb8d6a3e60ae5b2062f55ad00f986ecc779e0..95cd964f7a7b7f1e8d94e7f185488dd99f06ad7c 100644 --- a/src/app/perfil/[id]/page.js +++ b/src/app/perfil/[id]/page.js @@ -4,7 +4,7 @@ import { getStoredValue } from "../../handlers/localStorageHandler"; import { useEffect, useState } from "react"; import Overlay from "../../components/Overlay"; import mecredApi from "@/axiosConfig"; -import { isLoggedIn } from "@/app/handlers/loginHandler"; +import { authHeaders, isLoggedIn, userData } from "@/app/handlers/loginHandler"; import ErrorComponent from "@/app/components/ErrorComponent"; export default function Perfil({ params }) { @@ -15,9 +15,7 @@ export default function Perfil({ params }) { const [progresses, setProgresses] = useState(null); const [error, setError] = useState(false) const [idLogin, setIdLogin] = useState(0) - const token = getStoredValue("access_token") - const client = getStoredValue("client") - const uid = getStoredValue("uid") + const optTab = getStoredValue("tab"); @@ -33,7 +31,7 @@ export default function Perfil({ params }) { */ const fetchAchievements = async (id) => { await mecredApi - .get(`/unlocked_achievements/user/${id}?limit=1000`) + .get(`public/userAchievements/${id}/achievements`) .then(({ data }) => { setAchievements(data); }) @@ -42,20 +40,20 @@ export default function Perfil({ params }) { fetchAchievements(params.id); - const fetchProgresses = async (id) => { - await mecredApi - .get(`/user_progresses/${id}`) - .then(({ data }) => { - setProgresses(data); - }) - .catch(() => setError(true)) - } + // const fetchProgresses = async (id) => { + // await mecredApi + // .get(`/user_progresses/${id}`) + // .then(({ data }) => { + // setProgresses(data); + // }) + // .catch(() => setError(true)) + // } - fetchProgresses(params.id) + // fetchProgresses(params.id) const fetchItems = async (id) => { await mecredApi - .get(`/users/${id}/items/?item_type=badge&limit=1000`) + .get(`public/user-items/${id}/items?limit=1000`) .then(({ data }) => { setItems(data); }) @@ -65,44 +63,39 @@ export default function Perfil({ params }) { fetchItems(params.id) if (isLoggedIn()) { - let data = getStoredValue("user_data") - let dataJson = JSON.parse(data); + let data = userData() const fetchUser = async (id) => { await mecredApi - .get(`/users/${id}`, { - headers: { - 'access-token': token, - 'token-type': 'Bearer', - 'client': client, - 'uid': uid, - 'Expires': 0 - } + .get(`api/user/${id}`, { + headers: authHeaders() }) .then(({ data }) => { + console.log(data) setProfileData(data); }) .catch(() => setError(true)) } fetchUser(params.id) - setIdLogin(dataJson["id"]) + setIdLogin(data["user"]["id"]) - const fetchStore = async () => { + const fetchStore = async (id) => { await mecredApi - .get(`/items?filter={"state" : "active"}&item_type=badge&unlock_rule=purchase&limit=1000`) + .get(`public/user-items/${id}/items?filter={"state" : "active"}&item_type=badge&unlock_rule=purchase&limit=1000`) .then(({ data }) => { setStore(data) + console.log(data) }) .catch(() => setError(true)) } - fetchStore() + fetchStore(params.id) } else { const fetchUser = async (id) => { await mecredApi - .get(`/users/${id}`) + .get(`api/user/${id}`) .then(({ data }) => { setProfileData(data); }) @@ -112,7 +105,7 @@ export default function Perfil({ params }) { fetchUser(params.id) } - }, [params.id, client, token, uid]) + }, [params]) return ( <> diff --git a/src/app/publicar/components/AuthorSelection.js b/src/app/publicar/components/AuthorSelection.js index caa40ae5d73d73ec6481f0213f8709bffecd4e20..155aade65702e67ac69fdc67745186c3f1a52d8b 100644 --- a/src/app/publicar/components/AuthorSelection.js +++ b/src/app/publicar/components/AuthorSelection.js @@ -54,6 +54,11 @@ export default function AuthorSelection({ selectedValue, handleRadioChange, auth } /> </RadioGroup> + {selectedValue !== "a" && ( + <div className="text-sm text-darkGray-HC-white mb-1"> + Nomes dos autores devem ser separados por vírgula. + </div> + )} <CustomTextField fullWidth multiline @@ -62,9 +67,16 @@ export default function AuthorSelection({ selectedValue, handleRadioChange, auth value={author} onChange={handleAuthorChange} helperText={<div className=" w-full justify-end flex"> - {author?.length}/100 + <span className="text-red-HC-white justify-start"> + {selectedValue === "b" && !author.includes(",") && "Separe os nomes com vírgula."} + {(selectedValue === "b" || selectedValue === "c") && author.trim().endsWith(",") && "Não termine com vírgula."} + </span> + <span className="ml-auto"> + {author?.length}/255 + </span> </div>} - error={author?.length > 100} + error={(selectedValue === "b" && (!author.includes(",") || author.trim().endsWith(","))) || + author?.length > 255 || selectedValue === "c" && author.trim().endsWith(",")} className="mb-5" /> </div> diff --git a/src/app/publicar/components/RevisionForm.js b/src/app/publicar/components/RevisionForm.js index 9d6b5f23d4c7c5d739ed5fc61ff99f30941acd2a..8c238deb60c3fcc6e97bcb73281b50d507a893bf 100644 --- a/src/app/publicar/components/RevisionForm.js +++ b/src/app/publicar/components/RevisionForm.js @@ -156,7 +156,7 @@ export default function RevisionForm({ userData, setStep, draft, setDraft }) { </Button> {permission ? <Button - className="w-36 rounded-lg hover:bg-turquoise-hover border-turquoise-HC-white hover:bg-darkTurquoise-HC-dark bg-turquoise-HC-white text-base text-white-HC-dark-underline hover:text-white-HC-underline font-bold normal-case flex " + className="w-36 rounded-lg border-turquoise-HC-white hover:bg-darkTurquoise-HC-dark bg-turquoise-HC-white text-base text-white-HC-dark-underline hover:text-white-HC-underline font-bold normal-case flex " variant="outlined" onClick={fetchSubmit} > @@ -166,7 +166,7 @@ export default function RevisionForm({ userData, setStep, draft, setDraft }) { : <Button - className=" border-secondary w-36 rounded-lg hover:bg-turquoise-hover bg-turquoise text-base text-white-HC-dark-underline font-bold normal-case flex " + className="border-turquoise-HC-white w-36 rounded-lg hover:bg-darkTurquoise-HC-dark bg-turquoise-HC-white text-base text-white-HC-dark-underline hover:text-white-HC-underline font-bold normal-case flex " variant="outlined" onClick={submitHomologation} > diff --git a/src/app/recurso/[id]/components/actionButtons.js b/src/app/recurso/[id]/components/actionButtons.js index 342017b7e4e3d169bfc4323579e8052593a41991..1f5da660b33fc2a6f49708b2cf7f0984f8255c92 100644 --- a/src/app/recurso/[id]/components/actionButtons.js +++ b/src/app/recurso/[id]/components/actionButtons.js @@ -195,7 +195,7 @@ export default function ActionButtons({ learningObject, setNeedLoginOpen, state {/* Verifica se o usuário está logado antes de abrir o modal de colecionar */} {userData && <CollectModal open={collectOpen} onClose={() => setCollectOpen(false)} idLogin={userData["id"]} resourceId={learningObject.id} />} {!submitted ? - <div className="flex justify-start py-4 max-sm:no-scrollbar max-sm:overflow-x-auto animate-scrollHint"> + <div className="flex justify-start py-4 max-sm:no-scrollbar overflow-x-auto animate-scrollHint"> {buttonInfo.map(genButton)} </div> : diff --git a/src/app/recurso/[id]/components/authors.js b/src/app/recurso/[id]/components/authors.js new file mode 100644 index 0000000000000000000000000000000000000000..dd0d3b47b902982ba0ed237bb9f3b0574378bfed --- /dev/null +++ b/src/app/recurso/[id]/components/authors.js @@ -0,0 +1,8 @@ +export default function Authors({ data }) { + return ( + <div className="flex flex-col p-1 text-darkGray-HC-white"> + <div className="font-bold text-lg">Autores deste Recurso</div> + <div className="text-darkGray-HC-white p-3">{data}</div> + </div> + ); + } \ No newline at end of file diff --git a/src/app/recurso/[id]/components/createComments.js b/src/app/recurso/[id]/components/createComments.js index d3e1aafe96726172a9e927dcc7575c1a7856d284..8987e41f6de4ba738cf5a82895eb818a5804b951 100644 --- a/src/app/recurso/[id]/components/createComments.js +++ b/src/app/recurso/[id]/components/createComments.js @@ -9,19 +9,15 @@ import SendIcon from '@mui/icons-material/Send'; function getRandomBg(id) { const colors = [ - "bg-turquoise", - "bg-orange", - "bg-turquoise-hover", - "bg-darkOrange-HC-gray ", - "bg-violet", - "bg-pink", - "bg-red", + "bg-turquoise-HC-white", + "bg-orange-HC-white", + "bg-darkTurquoise-HC-white", + "bg-darkOrange-HC-white ", + "bg-violet-HC-white", + "bg-pink-HC-white", + "bg-red-HC-white", "bg-darkGray-HC-white", - "bg-darkGray-HC-white-click", - "bg-ice-HC-dark ", - "bg-darkGray-HC-white", - "bg-darkGray-HC-white", - "bg-turquoise-HC-dark", + "bg-ice-HC-white", ] return colors[id % colors.length]; @@ -71,11 +67,11 @@ export default function CreateComments({ user, logged, handleSubmitComment, newC value={newComment} /> <div className="flex justify-end gap-2 mt-2"> - <button className="w-24 h-8 border-black rounded-lg text-darkGray-HC-white-underline text-sm hover:text-white-HC-dark-underline hover:bg-ice-HC-white outline outline-1 outline-ice-HC-white" onClick={() => setNewComment("")}> cancelar </button> + <button className="w-24 h-8 border-black rounded-lg text-darkGray-HC-white-underline text-sm hover:text-darkGray-HC-dark-underline hover:bg-lightGray-HC-white outline outline-1 outline-white" onClick={() => setNewComment("")}> Cancelar </button> <button className="bg-turquoise-HC-white hover:bg-darkTurquoise-HC-dark hover:text-white w-24 h-8 rounded-lg text-white-HC-dark-underline text-sm hover:bg-turquoise-hover outline outline-1 outline-ice-HC-white" onClick={() => { if (!logged) setNeedLoginOpen(true) handleSubmitComment() - }}> comentar </button> + }}> Comentar </button> </div> </div> <div className="flex flex-row justify-center items-baseline gap-3 sm:hidden"> diff --git a/src/app/recurso/[id]/components/deleteCommentModal.js b/src/app/recurso/[id]/components/deleteCommentModal.js index 63e6186f2918f0c5cce984722d14aa6d28b3c3b0..2e051ce6e6544fd343ffc9de5b4efd64bfe03148 100644 --- a/src/app/recurso/[id]/components/deleteCommentModal.js +++ b/src/app/recurso/[id]/components/deleteCommentModal.js @@ -43,15 +43,15 @@ export default function DeleteCommentModal({ open, onClose, learningObjectId, id }, }} > - <div className="bg-ice-HC-dark p-6 rounded-lg"> + <div className="bg-ice-HC-dark p-6 rounded-lg outline outline-1 outline-ice-HC-white"> <div className="flex justify-center mb-4"> - <p className="text-darkGray-HC-white-underline text-xl font-bold ">Tem certeza que deseja excluir esse comentário?</p> + <p className="text-darkGray-HC-white text-xl font-bold ">Tem certeza que deseja excluir esse comentário?</p> </div> - <p className="text-darkGray-HC-white-underline text-lg ">A exclusão de um comentário é permanente. Não é possível desfazer essa ação.</p> + <p className="text-darkGray-HC-white text-lg ">A exclusão de um comentário é permanente. Não é possível desfazer essa ação.</p> <div className="flex justify-end mt-4"> - <button onClick={onClose} className="rounded-lg p-3 bg-ice-HC-dark hover:bg-ice-HC-dark-hover text-darkGray-HC-white-underline mr-1">Cancelar</button> - <button onClick={() => deleteComment()} className="rounded-lg p-3 bg-turquoise hover:bg-turquoise-hover text-white-HC-dark-underline">Excluir Comentário</button> + <button onClick={onClose} className="rounded-lg p-3 bg-ice-HC-dark hover:bg-lightGray-HC-white text-darkGray-HC-white-underline hover:text-darkGray-HC-dark mr-1 outline outline-1 outline-ice-HC-white">Cancelar</button> + <button onClick={() => deleteComment()} className="rounded-lg p-3 bg-turquoise-HC-white hover:bg-darkTurquoise-HC-dark text-white-HC-dark-underline hover:text-white outline outline-1 outline-ice-HC-white">Excluir Comentário</button> </div> </div> </Modal> diff --git a/src/app/recurso/[id]/components/editComments.js b/src/app/recurso/[id]/components/editComments.js index a30ef398fa700780d941eca513900b4b280b91a6..0164520c80f0514a87f78df57a90957c2448c36d 100644 --- a/src/app/recurso/[id]/components/editComments.js +++ b/src/app/recurso/[id]/components/editComments.js @@ -61,8 +61,8 @@ return ( value={editMessage} /> <div className="flex justify-end gap-2 mt-2"> - <button className="w-24 h-8 rounded-lg text-darkGray-HC-white text-sm hover:bg-ice-HC-dark" onClick={() => { setEdit(false); setEditMessage(comment?.description) }}> cancelar </button> - <button className="bg-turquoise w-24 h-8 rounded-lg text-white-HC-dark-underline text-sm hover:bg-turquoise-hover" onClick={handleSubmitEdit}> editar </button> + <button className="w-24 h-8 rounded-lg text-darkGray-HC-white text-sm hover:bg-lightGray-HC-dark" onClick={() => { setEdit(false); setEditMessage(comment?.description) }}> cancelar </button> + <button className="bg-turquoise-HC-white w-24 h-8 rounded-lg text-white-HC-dark-underline hover:text-white text-sm hover:bg-darkTurquoise-HC-dark outline outline-1 outline-ice-HC-white" onClick={handleSubmitEdit}> editar </button> </div> </div> diff --git a/src/app/recurso/[id]/components/homologationModal.js b/src/app/recurso/[id]/components/homologationModal.js index 03dc2de8d7d4a31149b4caa9a29c0d74ed8d94b5..9c31ee83a9b4b25cfc6dc3107417a02bdfdfff19 100644 --- a/src/app/recurso/[id]/components/homologationModal.js +++ b/src/app/recurso/[id]/components/homologationModal.js @@ -71,6 +71,8 @@ export default function HomologationModal({ open, onClose, name, id, setSubmitte } const ConfirmModal = ({ open, onClose }) => { + const accept = payload.some(item => item.accepted === false) + return ( <Modal @@ -85,13 +87,13 @@ export default function HomologationModal({ open, onClose, name, id, setSubmitte }, }} > - <div className="flex flex-col bg-ice-HC-dark p-5 rounded-lg "> - <p className="flex justify-center text-darkGray-HC-white-underline font-bold text-2xl">Recurso a ser aprovado</p> - <p className="pt-3 text-lg text-darkGray-HC-white-underline ">Este recurso será publicado na MEC RED. Você confirma essa avaliação?</p> + <div className="flex flex-col bg-ice-HC-dark p-5 rounded-lg outline outline-1 outline-ice-HC-white"> + <p className="flex justify-center text-darkGray-HC-white font-bold text-2xl">Recurso a ser aprovado</p> + <p className="pt-3 text-lg text-darkGray-HC-white">Este recurso {accept ? "não será" : "será"} publicado na MEC RED. Você confirma essa avaliação?</p> <div className="flex flex-row justify-end pt-5"> - <button onClick={() => onClose()} className="bg-ice-HC-dark px-3 py-2 mr-1 rounded-lg text-darkGray-HC-white-underline hover:bg-ice-HC-dark-hover">Alterar avaliação</button> - <button onClick={handleSubmit} className="bg-turquoise px-3 py-2 ml-1 rounded-lg text-white-HC-dark-underline font-semibold hover:bg-turquoise-hover">Confirmar</button> + <button onClick={() => onClose()} className="bg-ice-HC-dark px-3 py-2 mr-1 rounded-lg text-darkGray-HC-white-underline hover:text-darkGray-HC-dark-underline hover:bg-lightGray-HC-white outline outline-1 outline-white">Alterar avaliação</button> + <button onClick={handleSubmit} className="bg-turquoise-HC-white px-3 py-2 ml-1 rounded-lg text-white-HC-dark-underline hover:text-white font-semibold hover:bg-darkTurquoise-HC-dark outline outline-1 outline-ice-HC-white">Confirmar</button> </div> </div> @@ -143,7 +145,7 @@ export default function HomologationModal({ open, onClose, name, id, setSubmitte }, }} > - <div className="flex flex-col bg-ice-HC-dark p-5 rounded-lg "> + <div className="flex flex-col bg-ice-HC-dark p-5 rounded-lg outline outline-1 outline-ice-HC-white"> <ConfirmModal open={confirmOpen} onClose={() => { setConfirmOpen(false) }} /> <NotSucessModal open={notSucess} onClose={() => { setNotSucess(false) }} /> <p className="flex justify-center text-2xl text-darkGray-HC-white-underline font-bold pb-2">{`Você está avaliando a submissão ${name}`}</p> @@ -152,9 +154,28 @@ export default function HomologationModal({ open, onClose, name, id, setSubmitte return ( <div key={i} className="pb-4"> <p className="text-darkGray-HC-white-underline text-lg" key={i}>{item.description}</p> - <RadioGroup row onChange={(e) => { handleRadios(e, item.id) }}> - <FormControlLabel value={"Não"} control={<Radio />} label="Não" className="text-darkGray-HC-white-underline" /> - <FormControlLabel value={"Sim"} control={<Radio />} label="Sim" className="text-darkGray-HC-white-underline" /> + <RadioGroup row + onChange={(e) => { handleRadios(e, item.id) }}> + <FormControlLabel value={"Não"} control={ + <Radio + sx={{ + color: 'var(--darkGray-HC-white)', + '&.Mui-checked': { + color: 'var(--turquoise-HC-white)', + }, + }} + /> + } label="Não" className="text-darkGray-HC-white-underline" /> + <FormControlLabel value={"Sim"} control={ + <Radio + sx={{ + color: 'var(--darkGray-HC-white)', + '&.Mui-checked': { + color: 'var(--turquoise-HC-white)', + }, + }} + /> + } label="Sim" className="text-darkGray-HC-white-underline" /> </RadioGroup> </div> ) @@ -170,10 +191,27 @@ export default function HomologationModal({ open, onClose, name, id, setSubmitte multiline label="Justificativa (opcional)" variant="standard" + sx={{ + '& .MuiInputBase-input': { + color: 'var(--darkGray-HC-white)', // Cor do texto digitado + }, + '& .MuiInput-underline:before': { + borderBottomColor: 'var(--darkGray-HC-white)', // underline antes do foco + }, + '& .MuiInput-underline:after': { + borderBottomColor: 'var(--turquoise-HC-white)', // underline no foco + }, + '& .MuiInputLabel-root': { + color: 'var(--darkGray-HC-white)', // label normal + }, + '& .MuiInputLabel-root.Mui-focused': { + color: 'var(--turquoise-HC-white)', // label no foco + }, + }} /> <div className="flex justify-end mt-5"> - <button onClick={onClose} className="bg-ice-HC-dark px-3 py-2 mr-1 rounded-lg text-darkGray-HC-white-underline hover:bg-ice-HC-dark-hover">Cancelar</button> - <button onClick={() => { payload.length < 4 ? setNotSucess(true) : setConfirmOpen(true) }} className="bg-turquoise px-3 py-2 ml-1 rounded-lg text-white-HC-dark-underline font-semibold hover:bg-turquoise-hover">Enviar</button> + <button onClick={onClose} className="bg-ice-HC-dark px-3 py-2 mr-1 rounded-lg text-darkGray-HC-white-underline hover:text-darkGray-HC-dark-underline hover:bg-lightGray-HC-white outline outline-1 outline-white">Cancelar</button> + <button onClick={() => { payload.length < 4 ? setNotSucess(true) : setConfirmOpen(true) }} className="bg-turquoise-HC-white px-3 py-2 ml-1 rounded-lg text-white-HC-dark-underline hover:text-white font-semibold hover:bg-darkTurquoise-HC-dark outline outline-1 outline-ice-HC-white">Enviar</button> </div> </div> </Modal> diff --git a/src/app/recurso/[id]/components/metrics.js b/src/app/recurso/[id]/components/metrics.js index 1f2740f431f06bfd5c0842f8d3d6b59a343ae525..83cd2791bd08d2d08e764133bbeffed4b250b9dd 100644 --- a/src/app/recurso/[id]/components/metrics.js +++ b/src/app/recurso/[id]/components/metrics.js @@ -25,6 +25,10 @@ const genMetric = ({ icon, name, data }) => { } export default function Specifications({ learningObject }) { + console.log(learningObject) + console.log(learningObject.author) + console.log(learningObject.publisher?.name) + console.log(learningObject.author) const metricInfo = [ { icon: <IconViews className="text-2xl invertLogo-HC-white" />, name: "Visualizações", data: learningObject.stats.views }, { icon: <FavoriteOutlinedIcon />, name: "Curtidas", data: learningObject.stats.likes }, diff --git a/src/app/recurso/[id]/components/printComments.js b/src/app/recurso/[id]/components/printComments.js index 3d91e16a3d2956e1a712d08a399ad946deb1edc4..81e1df7934be56d8a071c5c7801a575aa6e2d9a2 100644 --- a/src/app/recurso/[id]/components/printComments.js +++ b/src/app/recurso/[id]/components/printComments.js @@ -10,19 +10,15 @@ import { s3URL } from "@/axiosConfig"; function getRandomBg(id) { const colors = [ - "bg-turquoise", - "bg-orange", - "bg-turquoise-hover", - "bg-darkOrange-HC-gray ", - "bg-violet", - "bg-pink", - "bg-red", + "bg-turquoise-HC-white", + "bg-orange-HC-white", + "bg-darkTurquoise-HC-white", + "bg-darkOrange-HC-white ", + "bg-violet-HC-white", + "bg-pink-HC-white", + "bg-red-HC-white", "bg-darkGray-HC-white", - "bg-darkGray-HC-white-click", - "bg-ice-HC-dark ", - "bg-darkGray-HC-white", - "bg-darkGray-HC-white", - "bg-turquoise-HC-dark", + "bg-ice-HC-white", ] return colors[id % colors.length]; diff --git a/src/app/recurso/[id]/components/resourceInfo.js b/src/app/recurso/[id]/components/resourceInfo.js index 1d285b8fe34f6e99d4e421e7f836041b2752a303..5b0de8d4a8409464b20bf8292e8a14d2c85ffc42 100644 --- a/src/app/recurso/[id]/components/resourceInfo.js +++ b/src/app/recurso/[id]/components/resourceInfo.js @@ -1,6 +1,8 @@ import { Tabs, Tab, Paper, Divider, Box } from "@mui/material"; +import AuthorsIcon from '@mui/icons-material/Groups2Rounded'; import { useState, useLayoutEffect, createRef } from "react"; import Specifications from "./specifications"; +import Authors from "./authors" import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; import ExpandLessIcon from "@mui/icons-material/ExpandLess"; import Description from "./description"; @@ -45,13 +47,14 @@ export default function ResourceInfo({ learningObject }) { description: <Description data={learningObject.description} />, specifications: <Specifications learningObject={learningObject} />, metrics: <Metrics learningObject={learningObject} />, + authors: <Authors data={learningObject.author}/> }; return ( <> <Paper className="bg-white-HC-dark outline outline-1 outline-ice-HC-white shadow-none flex flex-col flex-shrink-0 rounded-xl m-1 normal-case"> <Tabs - className="" + className="max-sm:no-scrollbar max-sm:overflow-x-auto max-sm:animate-scrollHint" value={value} variant="fullWidth" onChange={handleChange} @@ -102,6 +105,23 @@ export default function ResourceInfo({ learningObject }) { value="metrics" label="Métricas" /> + <Tab + sx={{ + display: { xs: "flex", sm: "none" }, // Show on small screens, hide on larger + justifyContent: "center", + borderBottom: value === "authors" ? "2px solid var(--turquoise-HC-white)" : "none", + }} + value="authors" + label={<AuthorsIcon className="text-darkGray-HC-white"/>} + /> + <Tab + sx={{ + display: { xs: "none", sm: "flex" }, // Hide on small screens, show on larger + }} + className="text-xl normal-case hover:bg-ice-HC-dark rounded-lg text-darkGray-HC-white-underline focus:text-turquoise-HC-white-underline" + value="authors" + label="Autores" + /> </Tabs> <hr style={{ borderTop: "1px solid var(--lightGray-HC-white)" }} /> {viewMore ? ( diff --git a/src/app/recurso/[id]/page.js b/src/app/recurso/[id]/page.js index 128297e40e88317264751940405bc42083ded4c5..43ea48aeea2dfee563513847f20e054026ca9888 100644 --- a/src/app/recurso/[id]/page.js +++ b/src/app/recurso/[id]/page.js @@ -29,6 +29,7 @@ export default function Recurso({ params }) { const [complained, setComplained] = useState(); const [isSmallScreen, setIsSmallScreen] = useState(false); const searchParams = useSearchParams(); + const [userData, setUserData] = useState(); const collectionId = searchParams.get("collectionId"); @@ -50,6 +51,10 @@ export default function Recurso({ params }) { setLearningObject(response.data); setState(response.data.state === "submitted"); setComplained(response.data.state === "suspended"); + + let data = JSON.parse(getStoredValue("user_data")); + setUserData(data) + } catch (error) { setError(true); } @@ -113,12 +118,16 @@ export default function Recurso({ params }) { </div> {state && ( <div className=" flex items-center mt-5"> - <button onClick={() => setSubmitOpen(true)} className="bg-orange p-2 text-white-HC-dark-underline font-semi-bold rounded-lg hover:bg-darkOrange-HC-gray ">Avaliar Submissão</button> + { + learningObject.publisher?.id !== userData.id ? + <button onClick={() => setSubmitOpen(true)} className="bg-orange-HC-white p-2 text-white-HC-dark-underline font-semi-bold rounded-lg hover:bg-darkOrange-HC-dark hover:text-white outline outline-1 outline-ice-HC-white">Avaliar Submissão</button> + : null + } </div> )} {complained && ( <div className=" flex items-center mt-5"> - <button onClick={() => setSubmitComplaintOpen(true)} className="bg-orange p-2 text-white-HC-dark-underline font-semi-bold rounded-lg hover:bg-darkOrange-HC-gray ">Avaliar Denúncia</button> + <button onClick={() => setSubmitComplaintOpen(true)} className="bg-orange-HC-white p-2 text-white-HC-dark-underline font-semi-bold rounded-lg hover:bg-darkOrange-HC-dark hover:text-white outline outline-1 outline-ice-HC-white">Avaliar Denúncia</button> </div> )} </div> diff --git a/src/app/sobre/page.js b/src/app/sobre/page.js index d07aa59c20feba92c0e9899e7065669f2aaedf5b..39fb675d5ec7e872ee98143f2a954f62760ea9fc 100644 --- a/src/app/sobre/page.js +++ b/src/app/sobre/page.js @@ -6,7 +6,7 @@ import { ContinueNavigation } from "../components/ContinueNavigation" export default function About() { return ( - <Overlay> + <Overlay type="twoColumns"> <AboutComponent /> <ContinueNavigation /> </Overlay> diff --git a/src/app/submit/components/InfoForm.js b/src/app/submit/components/InfoForm.js index d7a70a5cbc73c5532eb3f1267084585c158398e6..47b3d709e37a5762f8d8fa4e38482625033b7f00 100644 --- a/src/app/submit/components/InfoForm.js +++ b/src/app/submit/components/InfoForm.js @@ -190,7 +190,7 @@ export default function UploadForm({ setStep }) { Cancelar </Button> <Button - className=" border-secondary w-36 rounded-lg hover:bg-turquoise-hover bg-turquoise text-base text-white-HC-dark-underline font-bold normal-case flex " + className="w-36 rounded-lg border-turquoise-HC-white hover:bg-darkTurquoise-HC-dark bg-turquoise-HC-white text-base text-white-HC-dark-underline hover:text-white-HC-underline font-bold normal-case flex" variant="outlined" onClick={() => setStep((curr) => curr + 1)} > diff --git a/src/app/themes/theme_high_contrast.css b/src/app/themes/theme_high_contrast.css index 0a02a1dabc39a46201d7b6d34d9ffcc87a65e85e..eac8be81dfc12693c142038b1883a42ef0a95eb9 100644 --- a/src/app/themes/theme_high_contrast.css +++ b/src/app/themes/theme_high_contrast.css @@ -66,6 +66,12 @@ html[data-theme="theme_high_contrast"] { .text-black-HC-white-underline[data-theme="theme_high_contrast"] { text-decoration: underline; } +.text-lightGray-HC-white-underline[data-theme="theme_high_contrast"] { + text-decoration: underline; +} +.text-lightGray-HC-dark-underline[data-theme="theme_high_contrast"] { + text-decoration: underline; +} /* Em alto contraste: Icones pretos */ .invertIcon-HC-black[data-theme="theme_high_contrast"] { diff --git a/src/axiosConfig.js b/src/axiosConfig.js index 9be313ece58b962894093d7e475408707efa3647..080e28fb611761743ba2eaa5cea206612c59597d 100644 --- a/src/axiosConfig.js +++ b/src/axiosConfig.js @@ -3,8 +3,8 @@ import { saveToLocalStorage, } from "./app/handlers/localStorageHandler"; -export const s3URL = "https://s3.c3sl.ufpr.br/mecredteste/"; -export const mecredURLv1 = "https://api.mecred.c3sl.ufpr.br/v1"; +export const mecredURL = "http://localhost:3000"; +export const mecredURLv1 = "http://localhost:3000"; const wrapper = (method) => { return (...args) => { diff --git a/tailwind.config.js b/tailwind.config.js index dbbbab7ffb7348bc183c8762f49ce85c78ba8a8d..cda00e6e480204ccc23c586dc0ac8c9d346c374c 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -65,6 +65,8 @@ module.exports = { "lightGray": 'var(--lightGray)', "lightGray-HC-dark": 'var(--lightGray-HC-dark)', "lightGray-HC-white": 'var(--lightGray-HC-white)', + "lightGray-HC-white-underline": 'var(--lightGray-HC-white-underline)', + "lightGray-HC-dark-underline": 'var(--lightGray-HC-dark-underline)', "red-HC-white": 'var(--red-HC-white)', "mediumGray-HC-white": 'var(--mediumGray-HC-white)', "mediumGray-HC-dark": 'var(--mediumGray-HC-dark)', @@ -133,6 +135,12 @@ module.exports = { '.text-black-HC-white-underline': { 'text-decoration': 'var(--underline)', }, + '.text-lightGray-HC-white-underline': { + 'text-decoration': 'var(--underline)', + }, + '.text-lightGray-HC-dark-underline': { + 'text-decoration': 'var(--underline)', + }, '.invertLogo-HC-white': { 'filter': 'var(--filter)' }