- initial;

This commit is contained in:
Vitalii Kiiko
2024-08-09 08:51:20 +02:00
commit 987b1b0110
46 changed files with 30261 additions and 0 deletions

12
.babelrc Normal file
View File

@@ -0,0 +1,12 @@
{
"plugins": [
[
"@wordpress/babel-plugin-makepot",
{
"output": "./languages/gepafin.pot",
"domain": "gepafin"
}
],
"@babel/plugin-syntax-jsx"
]
}

3
.env Normal file
View File

@@ -0,0 +1,3 @@
REACT_APP_TAB_TITLE=Gepafin
REACT_APP_API_EXECUTION_ADDRESS=
REACT_APP_LOGO_FILENAME=logo.svg

24
.gitignore vendored Normal file
View File

@@ -0,0 +1,24 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
.vscode
npm-debug.log*
yarn-debug.log*
yarn-error.log*

8
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

8
.idea/gepafin.iml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/gepafin.iml" filepath="$PROJECT_DIR$/.idea/gepafin.iml" />
</modules>
</component>
</project>

19
.idea/php.xml generated Normal file
View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MessDetectorOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PHPCSFixerOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PHPCodeSnifferOptionsConfiguration">
<option name="highlightLevel" value="WARNING" />
<option name="transferred" value="true" />
</component>
<component name="PhpStanOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PsalmOptionsConfiguration">
<option name="transferred" value="true" />
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

16
.linguirc Normal file
View File

@@ -0,0 +1,16 @@
{
"locales": [
"en",
"it"
],
"sourceLocale": "it",
"catalogs": [
{
"path": "src/locales/{locale}/messages",
"include": [
"src"
]
}
],
"format": "po"
}

2
.npmrc Normal file
View File

@@ -0,0 +1,2 @@
@sinossi:registry=https://git.sinossi.it/api/v4/projects/271/packages/npm/
//git.sinossi.it/api/v4/projects/271/packages/npm/:_authToken=kdP6WxGtg71-MzJZDRe9

1
README.md Normal file
View File

@@ -0,0 +1 @@
# Gepafin

25
buildspec.prod.yml Normal file
View File

@@ -0,0 +1,25 @@
version: 0.2
phases:
install:
runtime-versions:
nodejs: 18
commands:
- npm install -g yarn
- echo yarn -v
- yarn -v
pre_build:
commands:
- echo "@sinossi:registry=https://git.sinossi.it/api/v4/projects/271/packages/npm/" > .npmrc
- echo "//git.sinossi.it/api/v4/projects/271/packages/npm/:_authToken=kdP6WxGtg71-MzJZDRe9" >> .npmrc
- yarn install
build:
commands:
- yarn extract
- yarn compile
- mkdir -pv public/loaded-files
- yarn build:prod
artifacts:
files:
- '**/*'
base-directory: 'build'

25
buildspec.staging.yml Normal file
View File

@@ -0,0 +1,25 @@
version: 0.2
phases:
install:
runtime-versions:
nodejs: 18
commands:
- npm install -g yarn
- echo yarn -v
- yarn -v
pre_build:
commands:
- echo "@sinossi:registry=https://git.sinossi.it/api/v4/projects/271/packages/npm/" > .npmrc
- echo "//git.sinossi.it/api/v4/projects/271/packages/npm/:_authToken=kdP6WxGtg71-MzJZDRe9" >> .npmrc
- yarn install
build:
commands:
- yarn extract
- yarn compile
- mkdir -pv public/loaded-files
- yarn build:staging
artifacts:
files:
- '**/*'
base-directory: 'build'

3
environments/dev/dev.env Normal file
View File

@@ -0,0 +1,3 @@
REACT_APP_TAB_TITLE=Gepafin
REACT_APP_API_EXECUTION_ADDRESS=
REACT_APP_LOGO_FILENAME=logo.svg

View File

@@ -0,0 +1,3 @@
REACT_APP_TAB_TITLE=Gepafin
REACT_APP_API_EXECUTION_ADDRESS=
REACT_APP_LOGO_FILENAME=logo.svg

View File

@@ -0,0 +1,3 @@
REACT_APP_TAB_TITLE=Gepafin
REACT_APP_API_EXECUTION_ADDRESS=
REACT_APP_LOGO_FILENAME=logo.svg

13
languages/en_US.json Normal file
View File

@@ -0,0 +1,13 @@
{
"domain": "gepafin",
"locale_data": {
"gepafin": {
"": {
"domain": "gepafin"
},
"Login page": [
"Login111 page"
]
}
}
}

8
languages/gepafin.pot Normal file
View File

@@ -0,0 +1,8 @@
msgid ""
msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"X-Generator: babel-plugin-makepot\n"
#: src/pages/Login/index.js:7
msgid "Login page"
msgstr ""

141
logo.svg Normal file
View File

@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: $$$/GeneralStr/196=Adobe Illustrator 27.6.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Livello_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 212.7 57" style="enable-background:new 0 0 212.7 57;" xml:space="preserve">
<style type="text/css">
.st0{clip-path:url(#SVGID_00000058564938444552568850000011671210144227177104_);}
.st1{fill:#EDEFED;}
.st2{fill:url(#Tracciato_1322_00000140007528026698576450000008493822996888926133_);}
.st3{fill-rule:evenodd;clip-rule:evenodd;fill:#EDEFED;}
.st4{fill-rule:evenodd;clip-rule:evenodd;fill:#50A55A;}
.st5{fill:#10254A;}
.st6{fill:#A4A3A3;}
.st7{fill:#1D5D2C;}
.st8{enable-background:new ;}
.st9{fill:#F4F4F4;}
.st10{fill:#1EA9E6;}
.st11{fill:#1B1B44;}
.st12{fill:url(#Tracciato_1322_00000139293701773537304240000008009627791954965639_);}
.st13{fill:#646363;}
</style>
<g id="Gruppo_di_maschere_3_00000137829315774319720650000007691311819899479979_" transform="translate(406 20)">
<path id="Tracciato_1312_00000106858671688356788210000000649906305471425694_" class="st11" d="M-327.7-1.6c0,4.9-1.8,6.3-6.9,6.3
c-0.9,0-1.9-0.1-2.8-0.2v6.4h-5.8V-7.6c2.6-0.2,5.2-0.3,7.8-0.3C-329.5-7.9-327.7-6.5-327.7-1.6 M-335.5,0.6c1.6,0,2-0.4,2-2.1
c0-1.8-0.4-2.2-2-2.2h-1.9v4.3L-335.5,0.6z"/>
<path id="Tracciato_1313_00000164508612597387298140000017556813643303852733_" class="st11" d="M-312.8,2.6v8.3h-4.5l-0.5-1.9
c-1.1,1.5-2.8,2.3-4.6,2.3c-2.5,0-4.6-1.3-4.6-3.8V6.1c0-2.1,1.7-3.5,4.4-3.5h4.2V2.6c0-0.9-0.4-1.3-1.6-1.3c-1.4,0-3.5,0-5.8,0.1
l-0.5-3.6c2.5-0.4,5.1-0.6,7.7-0.7C-314.9-2.9-312.8-1.6-312.8,2.6 M-321.6,6.6c0,0.5,0.4,0.8,1.1,0.8c0.7,0,1.4-0.3,2-0.7V5.4
h-2.1c-0.7,0-1,0.3-1,0.8L-321.6,6.6z"/>
<path id="Tracciato_1314_00000115495723131514862850000001058201557142650265_" class="st11" d="M-297.2-0.2c0.2,0.5,0.2,1,0.2,1.6
c0,3.1-1.8,4.2-6.9,4.2c-0.7,0-1.4,0-2-0.1c-0.3,0.4-0.2,1.2,0.8,1.2l4.9,0.3c3.1,0.2,4.3,1.6,4.3,4.2c0,3.8-2.3,4.5-7.8,4.5
c-6.4,0-7.7-1-7.7-3.8c0-1.3,0.5-2.1,2.1-2.8c-1-1.1-0.9-2.8,0.2-3.8c0.2-0.2,0.4-0.3,0.6-0.4c-1.5-0.5-2.4-2-2.3-3.6
c0-3.1,1.9-4.2,7-4.2c1.3,0,2.6,0.1,3.9,0.4h4.5l-0.3,2.1L-297.2-0.2z M-303.3,10.4l-2.4-0.2c-0.3,0.2-0.5,0.5-0.5,0.9
c0,0.7,0.5,0.9,2.4,0.9c2,0,2.6-0.1,2.6-0.7C-301.2,10.6-301.9,10.5-303.3,10.4 M-302.2,1.4c0-0.9-0.3-1.2-1.7-1.2
s-1.7,0.2-1.7,1.2s0.4,1.2,1.7,1.2S-302.2,2.3-302.2,1.4"/>
<path id="Tracciato_1315_00000004513449781377076020000017594958509754345867_" class="st11" d="M-279.8,0.9v10h-5.6V2.7
c0-0.6-0.3-0.8-1-0.8c-0.7,0-1.5,0.1-2.2,0.3v8.7h-5.6V-7.9h5.6l0,4c0,1-0.1,2-0.3,3c1.4-1.2,3.2-1.9,5.1-2
C-281.2-2.9-279.8-1.6-279.8,0.9"/>
<path id="Tracciato_1316_00000135653455172500280460000009652924552649599396_" class="st11" d="M-273.5-8.6
c0.8-0.1,1.5,0.4,1.6,1.2c0,0.1,0,0.3,0,0.4v1.4c0.1,0.8-0.4,1.5-1.2,1.7c-0.1,0-0.3,0-0.4,0h-2.4c-0.8,0.1-1.5-0.4-1.6-1.2
c0-0.1,0-0.3,0-0.4V-7c-0.1-0.8,0.4-1.5,1.2-1.7c0.1,0,0.3,0,0.4,0H-273.5z M-277.5-2.5h5.6v13.4h-5.6V-2.5z"/>
<path id="Tracciato_1317_00000039092972523437297100000009487910271573751708_" class="st11" d="M-255.8,2.6v8.3h-4.5l-0.5-1.9
c-1.1,1.5-2.8,2.3-4.6,2.3c-2.5,0-4.6-1.3-4.6-3.8V6.1c0-2.1,1.7-3.5,4.4-3.5h4.2V2.6c0-0.9-0.4-1.3-1.6-1.3c-1.4,0-3.5,0-5.8,0.1
l-0.5-3.6c2.5-0.4,5.1-0.6,7.7-0.7C-257.9-2.9-255.8-1.6-255.8,2.6 M-264.5,6.6c0,0.5,0.4,0.8,1.1,0.8c0.7,0,1.4-0.3,2-0.7V5.4
h-2.1c-0.7,0-1,0.3-1,0.8L-264.5,6.6z"/>
<path id="Tracciato_1318_00000168079963915968640480000000222458992304114578_" class="st11" d="M-232.1,0.9v10h-5.6V2.7
c0-0.6-0.2-0.8-0.9-0.8c-0.5,0-1.1,0.1-1.6,0.3v8.7h-5.4V2.7c0-0.6-0.3-0.8-0.9-0.8c-0.5,0-1,0.1-1.5,0.3v8.8h-5.6V-2.5h4.4l0.5,2
c1.2-1.5,2.9-2.3,4.8-2.3c1.8,0,3,0.7,3.5,2c1.1-1.3,2.8-2,4.5-2C-233.4-2.9-232.1-1.6-232.1,0.9"/>
<path id="Tracciato_1319_00000106838328843906219740000000765306438501474203_" class="st11" d="M-215.1,4.2c0,5.2-2,7-7.5,7
c-5.5,0-7.5-1.9-7.5-7c0-5.2,2-7.1,7.5-7.1C-217.1-2.9-215.1-1-215.1,4.2 M-224.2,4.2c0,2.7,0.3,3.2,1.6,3.2c1.3,0,1.6-0.5,1.6-3.2
c0-2.8-0.3-3.3-1.6-3.3C-223.9,0.9-224.2,1.5-224.2,4.2"/>
<path id="Tracciato_1320_00000063621272324291128790000015061499342844704914_" class="st11" d="M-200.9-1.9l-0.6,3.5h-4.1
c-1.7,0-2.3,0.5-2.3,2.6c0,2.1,0.5,2.6,2.3,2.6c1.4,0,2.9,0,4.3-0.2l0.5,3.5c-1.8,0.8-3.8,1.2-5.9,1.1c-5.3,0-7.1-1.9-7.1-7.1
s1.9-7.1,7.2-7.1C-204.6-2.9-202.6-2.6-200.9-1.9"/>
<path id="Tracciato_1321_00000126290441726012309050000012321652531482746263_" class="st11" d="M-194.9-8.6
c0.8-0.1,1.5,0.4,1.6,1.2c0,0.1,0,0.3,0,0.4v1.4c0.1,0.8-0.4,1.5-1.2,1.7c-0.1,0-0.3,0-0.4,0h-2.4c-0.8,0.1-1.5-0.4-1.6-1.2
c0-0.1,0-0.3,0-0.4V-7c-0.1-0.8,0.4-1.5,1.2-1.7c0.1,0,0.3,0,0.4,0H-194.9z M-198.9-2.5h5.6v13.4h-5.6V-2.5z"/>
<linearGradient id="Tracciato_1322_00000177460684992051479280000005205730633836918974_" gradientUnits="userSpaceOnUse" x1="-1020.1849" y1="500.7077" x2="-1020.1849" y2="499.7077" gradientTransform="matrix(56.809 0 0 -56.8 57578.082 28420.2012)">
<stop offset="0" style="stop-color:#E11E7B"/>
<stop offset="1" style="stop-color:#675DA4"/>
</linearGradient>
<path id="Tracciato_1322_00000005236860474443237370000017171500377395456921_" style="fill:url(#Tracciato_1322_00000177460684992051479280000005205730633836918974_);" d="
M-349.2,8.4c0,15.7-12.7,28.4-28.4,28.4c-15.7,0-28.4-12.7-28.4-28.4S-393.3-20-377.6-20c0,0,0,0,0,0
C-361.9-20-349.2-7.3-349.2,8.4"/>
<path id="Tracciato_1323_00000166673339959945891590000006791956076042917280_" class="st3" d="M-389.6,2c4.9,0,8.9,4,8.9,8.9
c0,4.9-4,8.9-8.9,8.9s-8.9-4-8.9-8.9l0,0C-398.6,6-394.6,2-389.6,2 M-389.6,4.9c3.4,0,6.1,2.7,6.1,6.1s-2.7,6.1-6.1,6.1
c-3.4,0-6.1-2.7-6.1-6.1l0,0C-395.7,7.6-393,4.9-389.6,4.9"/>
<path id="Tracciato_1324_00000005225925781860825400000004022602478308671114_" class="st3" d="M-368.2-3.1c0,1.5,1.2,2.7,2.7,2.7
s2.7-1.2,2.7-2.7c0-1.5-1.2-2.7-2.7-2.7C-367-5.8-368.2-4.6-368.2-3.1"/>
<path id="Tracciato_1325_00000176761091439225296580000010725916208274510263_" class="st3" d="M-365.6,2c4.9,0,8.9,4,8.9,8.9
c0,4.9-4,8.9-8.9,8.9c-4.9,0-8.9-4-8.9-8.9C-374.5,6-370.5,2-365.6,2 M-365.6,4.9c3.4,0,6.1,2.7,6.1,6.1s-2.7,6.1-6.1,6.1
c-3.4,0-6.1-2.7-6.1-6.1C-371.6,7.6-368.9,4.9-365.6,4.9"/>
<path id="Tracciato_1326_00000031898451844034338690000007981926532252117415_" class="st3" d="M-392.3-3.1c0,1.5,1.2,2.7,2.7,2.7
s2.7-1.2,2.7-2.7c0-1.5-1.2-2.7-2.7-2.7C-391.1-5.8-392.3-4.6-392.3-3.1"/>
<path id="Tracciato_1327_00000080209070003688870640000001493353427347600002_" class="st3" d="M-380.3-7.2c0,1.5,1.2,2.7,2.7,2.7
c1.5,0,2.7-1.2,2.7-2.7c0-1.5-1.2-2.7-2.7-2.7C-379.2-9.8-380.3-8.6-380.3-7.2"/>
<path id="Tracciato_1328_00000183945815550779116500000008924343682959670452_" class="st4" d="M-370,15.1c0.7,0.8,1.6,1.4,2.6,1.7
c-0.5,0.9-1.2,1.6-1.9,2.3c-1-0.5-1.9-1.1-2.6-1.8C-371.2,16.6-370.6,15.9-370,15.1"/>
<path id="Tracciato_1329_00000148642742736261572100000017459487759016315831_" class="st4" d="M-386.9,2.5c1,0.3,2,0.9,2.8,1.5
c-0.7,0.7-1.3,1.5-1.7,2.3c-0.8-0.7-1.8-1.1-2.8-1.3C-388.1,4.1-387.5,3.2-386.9,2.5"/>
<path id="Tracciato_1330_00000172432289523411573930000005677838029153875349_" class="st3" d="M-385.3,15.2L-385.3,15.2
c-2.7-4.2-1.5-9.7,2.7-12.4c3.6-2.3,8.3-1.8,11.3,1.3l0,0c0.8-0.7,1.8-1.2,2.8-1.6c-4.3-5.1-12-5.7-17.1-1.4
c-4.6,3.9-5.6,10.6-2.4,15.7C-386.9,16.5-386,15.9-385.3,15.2"/>
<path id="Tracciato_1331_00000037671671136664976650000007211065413075519892_" class="st3" d="M-366.8,5c-1,0.2-2,0.7-2.8,1.4v0
c2.2,4.5,0.3,9.8-4.2,12c-3.1,1.5-6.9,1.1-9.6-1.1v0c-0.8,0.8-1.7,1.4-2.7,1.8c4.9,4.6,12.5,4.4,17.1-0.5
C-365.4,15-364.6,9.6-366.8,5"/>
<path id="Tracciato_1332_00000031893163220611118630000011194324946715646095_" class="st5" d="M-366.8,5L-366.8,5L-366.8,5
M-369.3,7.1c-0.1-0.2-0.2-0.4-0.3-0.7C-369.5,6.7-369.4,6.9-369.3,7.1L-369.3,7.1"/>
<path id="Tracciato_1333_00000147943090431564400880000000838391038052167596_" class="st6" d="M-369.3,7.1
c-0.1-0.2-0.2-0.4-0.3-0.7l0,0v0c0.8-0.7,1.8-1.2,2.8-1.4v0c0.1,0.2,0.2,0.4,0.3,0.6C-367.6,5.8-368.5,6.4-369.3,7.1"/>
<path id="Tracciato_1334_00000132072477507067465560000011401922042482943643_" class="st5" d="M-383.3,17.3L-383.3,17.3
L-383.3,17.3 M-382.7,17.8c-0.2-0.1-0.4-0.3-0.6-0.5C-383.1,17.5-382.9,17.7-382.7,17.8L-382.7,17.8 M-386,19.2L-386,19.2
L-386,19.2"/>
<path id="Tracciato_1335_00000084505284409471917910000003550224882146089110_" class="st7" d="M-383.3,17.3L-383.3,17.3
L-383.3,17.3z M-386,19.2L-386,19.2"/>
<path id="Tracciato_1336_00000122696126891658954200000013844052331887732881_" class="st6" d="M-385.4,19.7
c-0.2-0.2-0.4-0.3-0.6-0.5l0,0c1-0.4,1.9-1.1,2.7-1.8v0l0,0l0,0l0,0c0.2,0.2,0.4,0.3,0.6,0.5C-383.5,18.5-384.4,19.2-385.4,19.7"/>
</g>
<g class="st8">
<path class="st11" d="M128.4,47.4c1.3,0,2.2,0.7,2.5,1.8h-1.2c-0.2-0.5-0.6-0.9-1.3-0.9c-0.9,0-1.5,0.7-1.5,1.9
c0,1.2,0.6,1.9,1.5,1.9c0.7,0,1.1-0.3,1.3-0.9h1.2c-0.3,1.1-1.2,1.8-2.5,1.8c-1.6,0-2.7-1.1-2.7-2.8
C125.7,48.5,126.8,47.4,128.4,47.4z"/>
<path class="st11" d="M134.4,53.1c-1.6,0-2.8-1.1-2.8-2.8c0-1.7,1.2-2.8,2.8-2.8s2.8,1.1,2.8,2.8C137.3,52,136,53.1,134.4,53.1z
M134.4,52.1c0.8,0,1.7-0.6,1.7-1.9c0-1.2-0.8-1.8-1.7-1.8c-0.9,0-1.6,0.6-1.6,1.8C132.8,51.5,133.6,52.1,134.4,52.1z"/>
<path class="st11" d="M142.3,49.9c0-1-0.5-1.5-1.4-1.5c-0.8,0-1.4,0.5-1.4,1.5V53h-1.1v-5.5h1.1v0.6c0.4-0.5,1-0.7,1.6-0.7
c1.3,0,2.3,0.8,2.3,2.3V53h-1.1V49.9z"/>
</g>
<path id="Tracciato_28_00000000211204610834567680000005720508230119712154_" class="st13" d="M168.5,45.4h-1.7v8.2h1.7v-1.7
l0.5-0.6l1.5,2.3h2l-2.3-3.5l2.3-2.4h-2.1l-1.8,2V45.4z"/>
<path id="Tracciato_29_00000124123000215720921620000016408069757550602368_" class="st13" d="M174.2,45.2c-0.5,0-1,0.5-1,1
c0,0.5,0.4,0.9,1,1h0c0.5,0,1-0.5,1-1C175.2,45.6,174.8,45.2,174.2,45.2L174.2,45.2 M175.1,47.6h-1.7v5.9h1.7L175.1,47.6z"/>
<path id="Tracciato_30_00000039854683079254541870000002819204944952482180_" class="st13" d="M178.6,45.9h-1.7v1.8h-0.7v1.2h0.7
v2.7c-0.1,1.1,0.8,2,1.8,2.1c0,0,0.1,0,0.1,0h0c0.6,0,1.2-0.3,1.6-0.7l-0.6-1.2c-0.2,0.3-0.5,0.4-0.8,0.4l0,0
c-0.2,0-0.3-0.1-0.4-0.2c-0.1-0.1-0.2-0.3-0.2-0.5v-2.7h1.4v-1.2h-1.4V45.9z"/>
<path id="Tracciato_31_00000112621048924245166300000002566300818136589955_" class="st13" d="M186.1,47.6h-4.8V49h2.6l-2.8,3.2v1.4
h5.2v-1.4h-3l2.9-3.3L186.1,47.6z"/>
<path id="Tracciato_32_00000001643147590553447810000012120551437516545423_" class="st13" d="M190.3,47.5c0,0-0.1,0-0.1,0h-0.1
c-0.9,0-1.8,0.3-2.6,0.8l0.7,1.1c0.2-0.2,0.5-0.3,0.8-0.4c0.3-0.1,0.6-0.2,0.9-0.2l0,0c0.7,0,1,0.3,1,0.9v0h-1.2c-0.1,0-0.1,0-0.2,0
c-0.6,0-1.1,0.2-1.6,0.5c-0.4,0.3-0.7,0.8-0.7,1.4c0,0.6,0.2,1.1,0.6,1.5c0.4,0.4,1,0.5,1.5,0.5h0.1c0.6,0,1.2-0.3,1.6-0.8v0.7h1.6
l0-3.8c0.1-0.6-0.2-1.3-0.7-1.7C191.4,47.7,190.9,47.5,190.3,47.5 M189.7,52.3c-0.2,0-0.4-0.1-0.6-0.2c-0.2-0.1-0.2-0.3-0.2-0.5
c0-0.4,0.3-0.6,1-0.6h1v0.3l0,0c0,0.3-0.1,0.5-0.3,0.7C190.4,52.2,190.1,52.3,189.7,52.3L189.7,52.3
C189.8,52.3,189.8,52.3,189.7,52.3"/>
<path id="Tracciato_33_00000156556411836716268190000010931947408658203563_" class="st13" d="M197.5,47.5L197.5,47.5
c-0.7,0-1.3,0.3-1.7,0.8v-0.7h-1.7v5.9h1.7v-3.3c0-0.4,0.1-0.8,0.4-1.1c0.2-0.2,0.5-0.4,0.9-0.4h0c0.7,0,1,0.5,1,1.4v3.3h1.7V50
c0-0.6-0.2-1.3-0.6-1.8C198.6,47.8,198.1,47.5,197.5,47.5"/>
<path id="Tracciato_34_00000001657046943341611510000013699085525589601152_" class="st13" d="M203.8,47.5c-0.8,0-1.6,0.3-2.1,0.9
c-1.2,1.2-1.2,3.1,0,4.3c0.6,0.6,1.3,0.9,2.1,0.9c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0c0.8,0,1.6-0.3,2.1-0.9c1.2-1.2,1.2-3.1,0-4.3
c-0.6-0.6-1.3-0.9-2.2-0.9C204,47.5,204,47.5,203.8,47.5C203.9,47.5,203.9,47.5,203.8,47.5 M203.9,48.9L203.9,48.9
c0.4,0,0.8,0.2,1.1,0.5c0.3,0.3,0.4,0.8,0.4,1.2c0,0.4-0.1,0.9-0.4,1.2c-0.3,0.3-0.6,0.5-1,0.5c0,0,0,0,0,0c0,0,0,0,0,0
c-0.4,0-0.8-0.2-1-0.5c-0.3-0.3-0.4-0.8-0.4-1.2c0-0.4,0.1-0.9,0.4-1.2C203.1,49.1,203.5,48.9,203.9,48.9L203.9,48.9"/>
<path id="Tracciato_35_00000173857628615946217310000016293583508846308004_" class="st13" d="M210.4,47.5c-0.6,0-1.1,0.2-1.6,0.5
c-0.4,0.3-0.7,0.8-0.7,1.3c0,0.5,0.2,1,0.7,1.2c0.2,0.1,0.4,0.2,0.6,0.3c0.2,0.1,0.4,0.2,0.7,0.3c0.3,0.1,0.5,0.2,0.8,0.3
c0.1,0.1,0.2,0.2,0.3,0.4c0,0.1-0.1,0.3-0.2,0.3c-0.1,0.1-0.3,0.1-0.5,0.1h0c-0.7,0-1.4-0.3-2-0.7l-0.7,1c0.4,0.3,0.8,0.5,1.3,0.7
c0.4,0.2,0.9,0.2,1.4,0.2c0,0,0.1,0,0.1,0c0.6,0,1.1-0.2,1.5-0.5c0.4-0.3,0.7-0.9,0.6-1.4c0-0.5-0.2-1-0.6-1.3
c-0.2-0.1-0.4-0.2-0.6-0.3c-0.2-0.1-0.4-0.2-0.8-0.3c-0.3-0.1-0.5-0.2-0.8-0.3c-0.1-0.1-0.2-0.2-0.2-0.4c0-0.3,0.3-0.4,0.8-0.4
c0.6,0,1.1,0.2,1.5,0.5l0.6-1.1c-0.6-0.4-1.3-0.7-2.1-0.7C210.5,47.5,210.4,47.5,210.4,47.5"/>
<path id="Tracciato_36_00000053503492734617689780000006005212477867466160_" class="st10" d="M159,45.4l-2.2,0l-3.4,8l2.2-0.1
L159,45.4z M148.8,54.7V44.2c0-1.2,1-2.2,2.2-2.2h10.5c1.2,0,2.2,1,2.2,2.2l0,0v10.5c0,1.2-1,2.2-2.2,2.2H151
C149.8,56.9,148.8,55.9,148.8,54.7"/>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

18658
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

67
package.json Normal file
View File

@@ -0,0 +1,67 @@
{
"name": "bflows-gepafin",
"version": "1.0.0",
"private": true,
"dependencies": {
"@babel/preset-react": "^7.24.7",
"@emotion/react": "11.13.0",
"@emotion/styled": "11.13.0",
"@wordpress/i18n": "^5.5.0",
"@wordpress/react-i18n": "^4.5.0",
"dompurify": "3.1.6",
"html-react-parser": "5.1.12",
"jwt-decode": "4.0.0",
"klona": "2.0.6",
"luxon": "3.5.0",
"ramda": "0.30.1",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-hook-form": "7.52.2",
"react-router-dom": "6.26.0",
"react-scripts": "^5.0.1",
"zustand": "4.5.4",
"zustand-x": "3.0.4"
},
"devDependencies": {
"@babel/cli": "7.24.8",
"@babel/core": "7.25.2",
"@babel/plugin-syntax-jsx": "^7.24.7",
"@wordpress/babel-plugin-makepot": "^6.5.0",
"babel-plugin-macros": "3.1.0",
"sass": "1.77.8"
},
"scripts": {
"start": "GENERATE_SOURCEMAP=false react-scripts start",
"start:dev": "cp environments/dev/* public/loaded-files && rm public/loaded-files/dev.env && cp environments/dev/dev.env .env && PORT=8000 react-scripts start",
"start:prod": "cp environments/prod/* public/loaded-files && rm public/loaded-files/prod.env && cp environments/prod/prod.env .env && react-scripts start",
"build": "react-scripts build",
"build:dev": "cp environments/dev/* public/loaded-files && rm public/loaded-files/dev.env && cp environments/dev/dev.env .env && react-scripts build",
"build:staging": "cp environments/staging/* public/loaded-files && rm public/loaded-files/staging.env && cp environments/staging/staging.env .env && react-scripts build",
"build:prod": "cp environments/prod/* public/loaded-files && rm public/loaded-files/prod.env && cp environments/prod/prod.env .env && react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"extract": "lingui extract",
"compile": "lingui compile"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
],
"rules": {
"react-hooks/exhaustive-deps": "off"
}
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

16
public/index.html Normal file
View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<link rel="icon" href="%PUBLIC_URL%/favicon.ico"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="description" content="Gepafin"/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png"/>
<link rel="manifest" href="%PUBLIC_URL%/manifest.json"/>
<title>%REACT_APP_TAB_TITLE%</title>
</head>
<body data-topbar="dark" data-layout-size="fluid" class="right-bar-enabled" data-layout="horizontal" data-sidebar-size>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1,32 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 215.26 58.92">
<defs>
<style>
.cls-1 {
fill: #43b29d;
}
.cls-2 {
fill: #034c66;
}
</style>
</defs>
<g id="Livello_2" data-name="Livello 2">
<g id="Livello_1-2" data-name="Livello 1">
<g>
<g>
<path class="cls-1" d="M29.08,19.61h6.56a3,3,0,0,0,3-3v-4a3,3,0,0,1,3-3h7.68C48.55,5.05,44.51,2.47,38,2.47H6.89L27.13,18.89A3,3,0,0,0,29.08,19.61Z"/>
<path class="cls-1" d="M27.26,46.33h8.38a3,3,0,0,0,3-3V35.19a3,3,0,0,1,3-3H51.81c-1.49-4.57-6-7.11-13-7.11H0L25.37,45.66A3,3,0,0,0,27.26,46.33Z"/>
<path class="cls-1" d="M60.23,28.57c4.59-2.4,6.65-5.73,6.58-10.84-.07-4.9-1.8-9.11-6.74-13.22C56.47,1.52,50.93,0,50.93,0c3.45,2.29,5.22,5.86,5.22,10.62,0,5.48-2.29,8.91-7.62,11.35,6.78,1.6,10.66,6.62,10.66,13.85a14.65,14.65,0,0,1-6.62,12.8c-3.43,2.21-7.92,3.19-14.62,3.19H21.43l7.94,6.44a2.94,2.94,0,0,0,1.88.67H48.61c6.7,0,11.19-1,14.62-3.2a14.65,14.65,0,0,0,6.62-12.79S70.45,32.11,60.23,28.57Z"/>
</g>
<g>
<path class="cls-2" d="M124.63,14.43l-1.29,0h-1.18a19.8,19.8,0,0,0-4.94.53A7.33,7.33,0,0,0,114,16.63a6.74,6.74,0,0,0-1.78,3.06,17.12,17.12,0,0,0-.55,4.63V44h6.49V28.57h6.2l1-5.1h-7.18a4.26,4.26,0,0,1,.88-3.08,4.54,4.54,0,0,1,3.24-.88l1.86,0c.69,0,1.24,0,1.65.06l1-5.1c-.24,0-.56,0-.94,0Z"/>
<rect class="cls-2" x="129.22" y="14.49" width="6.49" height="29.46"/>
<path class="cls-2" d="M158.7,24.12a7,7,0,0,0-3.25-1.67,24.3,24.3,0,0,0-9.71,0,7.08,7.08,0,0,0-3.26,1.67,6.77,6.77,0,0,0-1.84,3.14,17.86,17.86,0,0,0-.57,4.9V34.4a17.7,17.7,0,0,0,.57,4.86,6.77,6.77,0,0,0,1.84,3.14,7.29,7.29,0,0,0,3.26,1.69,23.36,23.36,0,0,0,9.71,0,7.2,7.2,0,0,0,3.25-1.69,7,7,0,0,0,1.81-3.14,17.7,17.7,0,0,0,.57-4.86V32.16a17.86,17.86,0,0,0-.57-4.9A7,7,0,0,0,158.7,24.12Zm-4.19,10.45a16.23,16.23,0,0,1-.16,2.57,3,3,0,0,1-.61,1.49,2.24,2.24,0,0,1-1.21.69,8.48,8.48,0,0,1-1.93.18,8.58,8.58,0,0,1-1.94-.18,2.18,2.18,0,0,1-1.2-.69,3.17,3.17,0,0,1-.64-1.49,14.82,14.82,0,0,1-.18-2.57V32a14.41,14.41,0,0,1,.18-2.55,3.14,3.14,0,0,1,.64-1.46,2.19,2.19,0,0,1,1.2-.7,8.58,8.58,0,0,1,1.94-.18,8.48,8.48,0,0,1,1.93.18,2.26,2.26,0,0,1,1.21.7,2.94,2.94,0,0,1,.61,1.46,15.78,15.78,0,0,1,.16,2.55Z"/>
<path class="cls-2" d="M207.39,22.45h-1.63a18.14,18.14,0,0,0-4.29.43,7.64,7.64,0,0,0-2.83,1.24,4.75,4.75,0,0,0-1.57,2,6.76,6.76,0,0,0-.49,2.67v.78a6.29,6.29,0,0,0,1.43,4.2q1.43,1.71,4.81,2l4,.28a3.59,3.59,0,0,1,1.84.43,1.29,1.29,0,0,1,.4,1,1.18,1.18,0,0,1-.59,1.19,6.12,6.12,0,0,1-2.3.28l-4.41,0c-1.63,0-3.06,0-4.42-.06l-1,5.1H206q4.81,0,7.06-1.59a5.67,5.67,0,0,0,2.24-5v-.69a8.74,8.74,0,0,0-.3-2.35,4.76,4.76,0,0,0-1.06-1.9,5.8,5.8,0,0,0-2-1.34,10.42,10.42,0,0,0-3.14-.7L205,30.08a4.11,4.11,0,0,1-1.83-.43,1.09,1.09,0,0,1-.41-1,1,1,0,0,1,.57-1,6.8,6.8,0,0,1,2-.2h2.94c.68,0,1.47,0,2.38,0l3.25.06,1-5.1Z"/>
<path class="cls-2" d="M187.5,29v7.61a2,2,0,0,1-1.82,2,9.69,9.69,0,0,1-1.32,0,2,2,0,0,1-1.81-2V22.45h-6.06V36.61a2,2,0,0,1-1.81,2,9.84,9.84,0,0,1-1.33,0,2,2,0,0,1-1.81-2V25A2.55,2.55,0,0,0,169,22.45h-4.7l-1.18,6.12h2.34v10.3a5.69,5.69,0,0,0,5.38,5.58,28.64,28.64,0,0,0,3.93,0,5.82,5.82,0,0,0,4.76-3.05,5.81,5.81,0,0,0,4.76,3.05,28.49,28.49,0,0,0,3.92,0,5.69,5.69,0,0,0,5.39-5.58V22.45H187.5Z"/>
<path class="cls-2" d="M83.67,14.9,82.49,21h2.34V44h13q4.86,0,7.41-1.9c1.7-1.26,2.55-3.3,2.55-6.1v-.73a7.28,7.28,0,0,0-1.17-4.33,6.28,6.28,0,0,0-3.24-2.32q3.59-1.52,3.59-6v-.45a6.72,6.72,0,0,0-2.1-5.42q-2.1-1.8-6.67-1.8ZM91.15,20h6a4,4,0,0,1,2.59.65,2.7,2.7,0,0,1,.75,2.13v.48a3,3,0,0,1-.81,2.33,4.22,4.22,0,0,1-2.82.73H91.15Zm10.08,15.42a3.22,3.22,0,0,1-.88,2.63,4.87,4.87,0,0,1-3,.72H91.15V31.46h6a5.08,5.08,0,0,1,3.16.76,3.36,3.36,0,0,1,.92,2.71Z"/>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

25
public/manifest.json Normal file
View File

@@ -0,0 +1,25 @@
{
"short_name": "Gepafin",
"name": "Gepafin project",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

3
public/robots.txt Normal file
View File

@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

30
src/App.js Normal file
View File

@@ -0,0 +1,30 @@
import { useState, useEffect } from 'react';
import { BrowserRouter } from 'react-router-dom';
import Routes from './routes';
import { createI18n, setLocaleData } from '@wordpress/i18n';
import { I18nProvider } from '@wordpress/react-i18n';
const i18n = createI18n();
function App() {
const [messages, setMessages] = useState({});
useEffect(() => {
/*import('../languages/en_US.json').then((translations) => {
setLocaleData(translations, 'gepafin');
});*/
fetch('/languages/en_US.json')
.then((res) => res.json())
.then(res => console.log(res))
}, []);
return (
<I18nProvider i18n={i18n}>
<BrowserRouter>
<Routes/>
</BrowserRouter>
</I18nProvider>
);
}
export default App;

View File

@@ -0,0 +1,3 @@
body {
background-color: moccasin;
}

View File

@@ -0,0 +1,28 @@
import React from 'react';
import { Navigate, Outlet } from 'react-router-dom';
// tools
import AuthenticationService from '../../service/authentication-service';
const ProtectedRoute = () => {
if (!AuthenticationService.wasLoggedIn()) {
return (<Navigate to={'/login'} replace/>);
}
if (AuthenticationService.isExpired()) {
return (<Navigate to={'/login?redirectReason=expired'} replace/>);
}
if (!AuthenticationService.isLoggedIn()) {
return (<Navigate to={'/login?redirectReason=auth_required'} replace/>);
}
if (window.location.pathname === '/') {
return (<Navigate to={'/pages/dashboard'} replace/>);
}
return <Outlet/>;
}
export default ProtectedRoute;

1
src/index.css Normal file
View File

@@ -0,0 +1 @@
@import './assets/scss/theme.scss';

15
src/index.js Normal file
View File

@@ -0,0 +1,15 @@
import React from 'react';
import { createRoot } from 'react-dom/client';
import './index.css';
import App from './App';
const rootEl = document.getElementById('root');
const rootReact = createRoot(rootEl);
rootReact.render(
<React.StrictMode>
<App/>
</React.StrictMode>
);

View File

@@ -0,0 +1,14 @@
import React from 'react';
const DefaultLayout = ({ children }) => {
return(
<div>
<div>
Top bar
</div>
{children}
</div>
)
}
export default DefaultLayout;

View File

@@ -0,0 +1,11 @@
import React from 'react';
const Dashboard = () => {
return(
<div>
Dashboard - main data
</div>
)
}
export default Dashboard;

12
src/pages/Login/index.js Normal file
View File

@@ -0,0 +1,12 @@
import React from 'react';
import { __ } from '@wordpress/i18n';
const Login = () => {
return(
<div>
{__('Login page', 'gepafin')}
</div>
)
}
export default Login;

View File

@@ -0,0 +1,11 @@
import React from 'react';
const PageNotFound = () => {
return(
<div>
Page not found
</div>
)
}
export default PageNotFound;

20
src/routes.js Normal file
View File

@@ -0,0 +1,20 @@
import { Route, Routes } from 'react-router-dom';
// components
import PageNotFound from './pages/PageNotFound';
import Login from './pages/Login';
import ProtectedRoute from './components/ProtectedRoute';
import Dashboard from './pages/Dashboard';
import DefaultLayout from './layouts/DefaultLayout';
const routes = () => (
<Routes>
<Route element={<ProtectedRoute/>}>
<Route path="/" element={<DefaultLayout><Dashboard/></DefaultLayout>}/>
</Route>
<Route exact path="/login" element={<Login/>}/>
{/*<Route exact path="/forgot-password" element={<ForgotPassword/>}/>*/}
<Route path="*" element={<PageNotFound/>}/>
</Routes>);
export default routes;

View File

@@ -0,0 +1,79 @@
import { NetworkService } from './network-service';
import { jwtDecode } from 'jwt-decode';
// store
import { storeGet } from '../store';
const API_BASE_URL = process.env.REACT_APP_API_EXECUTION_ADDRESS;
export default class AuthenticationService {
static wasLoggedIn = () => {
const token = storeGet.main.getToken();
return token ?? false;
};
static isExpired = () => {
const token = storeGet.main.getToken();
if (!token) {
return false;
}
let decoded = jwtDecode(token);
if (!decoded) {
return false;
}
let currentTs = new Date().getTime();
if (currentTs >= (decoded.exp * 1000)) {
return true; //FIXME: try refresh
}
return false;
};
static isLoggedIn = () => {
const token = storeGet.main.getToken();
if (!token) {
return false;
}
let decoded = jwtDecode(token);
if (!decoded) {
return false;
}
let currentTs = new Date().getTime();
if (currentTs >= decoded.exp * 1000) {
return false; //FIXME: try refresh
}
return true;
};
static login = (loginRequest, callback, errCallback) => {
NetworkService.unauthorizedPost(`${API_BASE_URL}/user/login/`, loginRequest, callback, errCallback);
};
static registerUser = (registerRequest, callback, errCallback) => {
NetworkService.post(`${API_BASE_URL}/user/register/`, registerRequest, callback, errCallback);
};
static forgotPassword = (request, callback, errCallback) => {
NetworkService.unauthorizedPost(`${API_BASE_URL}/user/reset_password_request/?email=` + request, {}, callback, errCallback);
}
static checkTokenForgotPassword = (request, callback, errCallback) => {
NetworkService.unauthorizedGet(`${API_BASE_URL}/user/reset_token_check/?token=` + request, {}, callback, errCallback);
}
static changePassword = (request, callback, errCallback) => {
NetworkService.unauthorizedPatch(`${API_BASE_URL}/user/reset_password/`, request, callback, errCallback);
}
}

View File

@@ -0,0 +1,374 @@
import { storeGet } from '../store';
export class NetworkService {
static TOKEN_KEY
static REFRESH_TOKEN_KEY
static postEmptyResponse = (url, body, callback, errorCallback) => {
fetch(url, {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
'Authorization': storeGet.main.getToken(),
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify(body)
})
.then(data => {
if (data.status >= 400 && data.status <= 599)
errorCallback(data.status)
else
callback()
})
.catch(err => errorCallback(err));
};
static putEmptyResponse = (url, body, callback, errorCallback) => {
fetch(url, {
method: 'PUT',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
'Authorization': storeGet.main.getToken(),
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify(body)
})
.then(data => {
if (data.status >= 400 && data.status <= 599)
errorCallback(data.status)
else
callback()
})
.catch(err => errorCallback(err));
};
static post = (url, body, callback, errorCallback, queryParams) => {
if (queryParams) {
url += '?'
for (let i = 0; i < queryParams.length; i++) {
if (queryParams[i] && this.isNotBlank(queryParams[i][0]) && this.isNotBlank(queryParams[i][1])) {
let param = queryParams[i][0] + '=' + queryParams[i][1]
if (i !== queryParams.length - 1)
param += '&'
url += param;
}
}
if (url.charAt(url.length) === '&')
url = url.substring(0, url.length - 1);
}
fetch(url, {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + storeGet.main.getToken(),
},
body: JSON.stringify(body)
})
.then(async response => {
let status = response.status;
return { response: await response.json(), status: status }
})
.then(data => {
if (data.status >= 400 && data.status <= 599)
errorCallback(data.response)
else
callback(data.response)
})
.catch(err => errorCallback(err));
};
static unauthorizedPost = (url, body, callback, errorCallback) => {
fetch(url, {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
})
.then(async response => {
let status = response.status;
return { response: await response.json(), status: status }
})
.then(data => {
if (data.status >= 400 && data.status <= 599)
errorCallback(data.response)
else
callback(data.response)
})
.catch(err => errorCallback(err));
};
static patch = (url, body, callback, errorCallback) => {
fetch(url, {
method: 'PATCH',
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
})
.then(async response => {
let status = response.status;
return { response: await response.json(), status: status }
})
.then(data => {
if (data.status >= 400 && data.status <= 599)
errorCallback(data.response)
else
callback(data.response)
})
.catch(err => errorCallback(err));
};
static put = (url, body, callback, errorCallback, queryParams = null) => {
if (queryParams) {
url += '?'
for (let i = 0; i < queryParams.length; i++) {
if (queryParams[i] && this.isNotBlank(queryParams[i][0]) && this.isNotBlank(queryParams[i][1])) {
let param = queryParams[i][0] + '=' + queryParams[i][1]
if (i !== queryParams.length - 1)
param += '&'
url += param;
}
}
if (url.charAt(url.length) === '&')
url = url.substring(0, url.length - 1);
}
fetch(url, {
method: 'PUT',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + storeGet.main.getToken(),
},
body: JSON.stringify(body)
})
.then(async response => {
let status = response.status;
return { response: await response.json(), status: status }
})
.then(data => {
if (data.status >= 400 && data.status <= 599)
errorCallback(data.response)
else
callback(data.response)
})
.catch(err => errorCallback(err));
};
static unauthorizedPostEmptyResponse = (url, body, callback, errorCallback) => {
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify(body)
})
.then(data => callback(data))
.catch(err => errorCallback(err));
};
static unauthorizedPutEmptyResponse = (url, body, callback, errorCallback) => {
fetch(url, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify(body)
})
.then(data => callback(data))
.catch(err => errorCallback(err));
};
static unauthorizedGet = (url, queryParams, callback, errorCallback) => {
fetch(url, {
method: 'GET',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
}
})
.then(async response => {
let status = response.status;
return { response: await response.json(), status: status }
})
.then(data => {
if (data.status >= 400 && data.status <= 599)
errorCallback(data.response)
else
callback(data.response)
})
.catch(err => errorCallback(err));
};
static unauthorizedPatch = (url, body, callback, errorCallback) => {
fetch(url, {
method: 'PATCH',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(body)
})
.then(async response => {
let status = response.status;
return { response: await response.json(), status: status }
})
.then(data => {
if (data.status >= 400 && data.status <= 599)
errorCallback(data.response)
else
callback(data.response)
})
.catch(err => errorCallback(err));
};
static isNotBlank(value) {
return value !== null && value !== undefined && value !== ''
}
static get = (url, callback, errorCallback, queryParams = null) => {
if (queryParams) {
url += '?'
for (let i = 0; i < queryParams.length; i++) {
if (queryParams[i] && this.isNotBlank(queryParams[i][0]) && this.isNotBlank(queryParams[i][1])) {
let param = queryParams[i][0] + '=' + queryParams[i][1]
if (i !== queryParams.length - 1)
param += '&'
url += param;
}
}
if (url.charAt(url.length) === '&')
url = url.substring(0, url.length - 1);
}
fetch(url, {
method: 'GET',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + storeGet.main.getToken(),
}
})
.then(async response => {
let status = response.status;
return { response: await response.json(), status: status }
})
.then(data => {
if (data.status >= 400 && data.status <= 599) {
errorCallback(data.response)
} else {
callback(data.response)
}
})
.catch(err => errorCallback(err));
};
static promiseGet = async (url, queryParams = null) => {
const response = await fetch(url, {
method: 'GET',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + storeGet.main.getToken(),
'Access-Control-Allow-Origin': '*'
}
});
const json = await response.json();
return json;
}
static deleteEmptyResponse = (url, callback, errorCallback, queryParams = null) => {
if (queryParams) {
let params = '?'
for (let i = 0; i < queryParams.length; i++) {
params += queryParams[i][0] + '=' + queryParams[i][1]
if (queryParams.length !== i + 1)
params += '&'
url += params
params = ''
}
}
fetch(url, {
method: 'DELETE',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
'Authorization': storeGet.main.getToken(),
'Access-Control-Allow-Origin': '*'
}
})
.then(data => {
if (data.status >= 400 && data.status <= 599)
errorCallback(data.status)
else
callback()
})
.catch(err => errorCallback(err));
}
static delete = (url, body, callback, errorCallback, queryParams = null) => {
if (queryParams) {
let params = '?'
for (let i = 0; i < queryParams.length; i++) {
params += queryParams[i][0] + '=' + queryParams[i][1]
if (queryParams.length !== i + 1)
params += '&'
url += params
params = ''
}
}
fetch(url, {
method: 'DELETE',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + storeGet.main.getToken(),
},
body: JSON.stringify(body)
})
.then(async response => {
let status = response.status;
return { response: await response.json(), status: status }
})
.then(data => {
if (data.status >= 400 && data.status <= 599)
errorCallback(data.response)
else
callback(data.response)
})
.catch(err => errorCallback(err));
};
}

16
src/setupProxy.js Normal file
View File

@@ -0,0 +1,16 @@
//made available by http-proxy-middleware
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
createProxyMiddleware(
"/api",
{
target: 'https://localhost:8000/',
changeOrigin: true,
}
)
);
};

15
src/store/actions.js Normal file
View File

@@ -0,0 +1,15 @@
export const actionsAlpha = (set, get, api) => ({
setAsyncRequest: () => {
const num = get.isAsyncRequest();
set.isAsyncRequest(num + 1);
},
unsetAsyncRequest: () => {
const num = get.isAsyncRequest();
set.isAsyncRequest(num - 1 < 0 ? 0 : num - 1);
},
})
export const actionsBeta = (set, get, api) => ({
});

20
src/store/index.js Normal file
View File

@@ -0,0 +1,20 @@
import { mapValuesKey } from 'zustand-x';
// stores
import { mainStore } from './main';
// Global store - initial data
const dashboardStore = {
main: mainStore
};
// Global hook selectors
export const useStore = () => mapValuesKey('use', dashboardStore);
// Global tracked hook selectors
export const useTrackedStore = () => mapValuesKey('useTracked', dashboardStore);
// Global getter selectors
export const storeGet = mapValuesKey('get', dashboardStore);
// Global actions
export const storeSet = mapValuesKey('set', dashboardStore);
export default dashboardStore;

6
src/store/initial.js Normal file
View File

@@ -0,0 +1,6 @@
const initialStore = {
// ui related
isAsyncRequest: 0, // number
}
export default initialStore;

11
src/store/main.js Normal file
View File

@@ -0,0 +1,11 @@
import { createStore } from 'zustand-x';
import zustandXOpts from './zustand-x-opts';
import initialStore from './initial';
import selectors from './selectors';
import { actionsAlpha, actionsBeta } from './actions';
export const mainStore = createStore('main')(initialStore, zustandXOpts)
.extendSelectors(selectors)
.extendActions(actionsAlpha)
.extendActions(actionsBeta);

10
src/store/selectors.js Normal file
View File

@@ -0,0 +1,10 @@
import { isEmpty } from 'ramda';
const selectors = (state, get, api) => ({
getToken: () => {
const userData = get.userData();
return userData.access && !isEmpty(userData.access) ? userData.access : null;
},
})
export default selectors;

View File

@@ -0,0 +1,16 @@
const zustandXOpts = {
devtools: {
enabled: true
},
persist: {
enabled: true,
partialize: (state) => ({
userData: state.userData,
hubsList: state.hubsList,
chosenHub: state.chosenHub,
groups: state.groups,
}),
}
}
export default zustandXOpts;

10440
yarn.lock Normal file

File diff suppressed because it is too large Load Diff