Compare commits
129 Commits
server_1.1
...
ChatBox
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d87c336de | ||
|
|
037ff6f7f9 | ||
|
|
b8dcd7f5e0 | ||
|
|
b35c99c8fb | ||
|
|
086e4ab8ba | ||
|
|
139d3fe241 | ||
|
|
6fe3ed7c8b | ||
|
|
81ae2df8ef | ||
|
|
997a7b8b98 | ||
|
|
331a5451b2 | ||
|
|
514c2488cc | ||
|
|
33e51bac0e | ||
|
|
c46d23cb83 | ||
|
|
acb685f819 | ||
|
|
18790ee379 | ||
|
|
70698fab44 | ||
|
|
c61572a715 | ||
|
|
00bdc278d8 | ||
|
|
5b1f3eafbc | ||
|
|
233c5fa28e | ||
|
|
aa877dea0a | ||
|
|
657dc79996 | ||
|
|
294155d5a3 | ||
|
|
1a342de24a | ||
|
|
00ce3bd919 | ||
|
|
adf1aac10f | ||
|
|
26a42b1f30 | ||
|
|
71fe2ae657 | ||
|
|
8d1dd45648 | ||
|
|
38c13eef28 | ||
|
|
8f54cd2791 | ||
|
|
610961d22c | ||
|
|
3f7eda05cf | ||
|
|
ebfd80da76 | ||
|
|
ede8a2db3d | ||
|
|
4e37475d00 | ||
|
|
6048cd526b | ||
|
|
1d52ab1d08 | ||
|
|
08cf4b6d9f | ||
|
|
4a05ddee50 | ||
|
|
c37280fa4a | ||
|
|
d00e086646 | ||
|
|
973875ca66 | ||
|
|
03c2bcb78e | ||
|
|
a2dd06bd68 | ||
|
|
7ba408c053 | ||
|
|
fcbc64cea8 | ||
|
|
2ee710b748 | ||
|
|
e3db42dcbc | ||
|
|
32210bb96a | ||
|
|
f26ae170bb | ||
|
|
a189aeb99c | ||
|
|
e118c30f47 | ||
|
|
fb11e15907 | ||
|
|
87c8bf4c45 | ||
|
|
efd1d12ba7 | ||
|
|
29437d9d7b | ||
|
|
ed27a6f6a5 | ||
|
|
d6579763f4 | ||
|
|
88cb2f13cc | ||
|
|
91ac7a5bde | ||
|
|
0b06f9f93a | ||
|
|
a13635ab4e | ||
|
|
31a93424aa | ||
|
|
8d4158c2c6 | ||
|
|
8c0619992b | ||
|
|
5668c620da | ||
|
|
6b9ddc8986 | ||
|
|
133dc6a502 | ||
|
|
25377090c1 | ||
|
|
d1d4b73da0 | ||
|
|
f88f433003 | ||
|
|
28a4fe1952 | ||
|
|
f85b8d0637 | ||
|
|
3d6455f23c | ||
|
|
f0c25366db | ||
|
|
d2aaf78c0e | ||
|
|
40214abe64 | ||
|
|
9efd193124 | ||
|
|
0e5d28d199 | ||
|
|
d6aaaabb00 | ||
|
|
10097f4238 | ||
|
|
a3c7b92c0c | ||
|
|
a374a7d7bc | ||
|
|
7e50299854 | ||
|
|
1da0e0f4b5 | ||
|
|
636136a077 | ||
|
|
3521a88395 | ||
|
|
768d299881 | ||
|
|
a76d6c9b12 | ||
|
|
0bf8d3c83c | ||
|
|
b2c19801e6 | ||
|
|
ee3846159c | ||
|
|
5ab24b2abd | ||
|
|
09a05a11d5 | ||
|
|
6c254a6a8e | ||
|
|
240a7be7f1 | ||
|
|
58839c32e1 | ||
|
|
b77a0579f1 | ||
|
|
6e8d1fcff1 | ||
|
|
192fd4706c | ||
|
|
fcc3755c19 | ||
|
|
97abe8b46d | ||
|
|
e40fbd550b | ||
|
|
3d4f8b0d04 | ||
|
|
95793fd73f | ||
|
|
4b4e3963ac | ||
|
|
85e2df56e1 | ||
|
|
58431c144c | ||
|
|
ad45ce60ee | ||
|
|
fba2ebd710 | ||
|
|
8e8a3204a7 | ||
|
|
e1ca4ef17f | ||
|
|
5431fe118e | ||
|
|
789dc1dcae | ||
|
|
76bacf3f5a | ||
|
|
d94cbde948 | ||
|
|
dfe492df45 | ||
|
|
6c50f35b2b | ||
|
|
a03c4cf613 | ||
|
|
7d845355a9 | ||
|
|
aeb83a512b | ||
|
|
e04247b1b6 | ||
|
|
f713f66369 | ||
|
|
f32bd189dc | ||
|
|
0017f04e45 | ||
|
|
65b29a6eee | ||
|
|
7827e49760 | ||
|
|
d106a59bb5 |
@@ -21,8 +21,8 @@ DELAY_SENDEMAIL=2000
|
||||
VAPI_KEY_SUBJECT=mailto:paolo@freeplanet.app
|
||||
PUBLIC_VAPI_KEY=BDncvMiUZmjaCG2Kr1V9N0_33hOG-AuNSbHSvL24y2dzBiUjAxKm02emx5SeJvz2IGmtRf6YqCgopeQwCwUmZw8
|
||||
PRIVATE_VAPI_KEY=uB2-jQkrbysyDtqN3ziMBDsVn0wdEaDsksX81zoOGQo
|
||||
PATH_CERT_KEY=localhost.key
|
||||
PATH_SERVER_CRT=localhost.crt
|
||||
PATH_CERT_KEY=localhost-key.pem
|
||||
PATH_SERVER_CRT=localhost.pem
|
||||
PATH_SSL_ROOT_PEM=root.pem
|
||||
PATH_SSL_CHAIN_PEM=chain.pem
|
||||
GCM_API_KEY=""
|
||||
@@ -42,5 +42,5 @@ MIAB_HOST=box.lamiaposta.org
|
||||
MIAB_ADMIN_EMAIL=admin@lamiaposta.org
|
||||
MIAB_ADMIN_PASSWORD=passpao1pabox@1A
|
||||
DS_API_KEY="sk-222e3addb3d8455d8b0516d93906eec7"
|
||||
API_KEY_MSSQL="m68yADSr123MIVIDA@154$DSAGVOK"
|
||||
SERVER_A_URL="http://51.77.156.69:3000"
|
||||
SERVER_A_URL="http://51.77.156.69:3000"
|
||||
API_KEY_MSSQL="m68yADSr123MIVIDA@154$DSAGVOK"
|
||||
@@ -21,16 +21,16 @@ DELAY_SENDEMAIL=2000
|
||||
VAPI_KEY_SUBJECT=mailto:paolo@freeplanet.app
|
||||
PUBLIC_VAPI_KEY=BDncvMiUZmjaCG2Kr1V9N0_33hOG-AuNSbHSvL24y2dzBiUjAxKm02emx5SeJvz2IGmtRf6YqCgopeQwCwUmZw8
|
||||
PRIVATE_VAPI_KEY=uB2-jQkrbysyDtqN3ziMBDsVn0wdEaDsksX81zoOGQo
|
||||
PATH_CERT_KEY=localhost.key
|
||||
PATH_SERVER_CRT=localhost.crt
|
||||
PATH_CERT_KEY=localhost-key.pem
|
||||
PATH_SERVER_CRT=localhost.pem
|
||||
PATH_SSL_ROOT_PEM=root.pem
|
||||
PATH_SSL_CHAIN_PEM=chain.pem
|
||||
GCM_API_KEY=""
|
||||
PROD=0
|
||||
PROJECT_DESCR_MAIN='__PROJECTS'
|
||||
SECRK=Askb38v23jjDFaoskBOWj92axXCQ
|
||||
TOKEN_LIFE=2h
|
||||
REFRESH_TOKEN_LIFE=14d
|
||||
TOKEN_LIFE=1m
|
||||
REFRESH_TOKEN_LIFE=30d
|
||||
FTPSERVER_HOST=139.162.166.31
|
||||
FTPSERVER_PORT=21
|
||||
FTPSERVER_USER=ftpusrsrv_
|
||||
|
||||
@@ -21,16 +21,16 @@ DELAY_SENDEMAIL=2000
|
||||
VAPI_KEY_SUBJECT=mailto:paolo@freeplanet.app
|
||||
PUBLIC_VAPI_KEY=BDncvMiUZmjaCG2Kr1V9N0_33hOG-AuNSbHSvL24y2dzBiUjAxKm02emx5SeJvz2IGmtRf6YqCgopeQwCwUmZw8
|
||||
PRIVATE_VAPI_KEY=uB2-jQkrbysyDtqN3ziMBDsVn0wdEaDsksX81zoOGQo
|
||||
PATH_CERT_KEY=localhost.key
|
||||
PATH_SERVER_CRT=localhost.crt
|
||||
PATH_CERT_KEY=localhost-key.pem
|
||||
PATH_SERVER_CRT=localhost.pem
|
||||
PATH_SSL_ROOT_PEM=root.pem
|
||||
PATH_SSL_CHAIN_PEM=chain.pem
|
||||
GCM_API_KEY=""
|
||||
PROD=0
|
||||
PROJECT_DESCR_MAIN='__PROJECTS'
|
||||
SECRK=Askb38v23jjDFaoskBOWj92axXCQ
|
||||
TOKEN_LIFE=1m
|
||||
REFRESH_TOKEN_LIFE=14d
|
||||
TOKEN_LIFE=30d
|
||||
REFRESH_TOKEN_LIFE=30d
|
||||
FTPSERVER_HOST=139.162.166.31
|
||||
FTPSERVER_PORT=21
|
||||
FTPSERVER_USER=ftpusrsrv_
|
||||
@@ -39,3 +39,9 @@ AUTH_NEW_SITES=123123123
|
||||
SCRIPTS_DIR=admin_scripts
|
||||
CLOUDFLARE_TOKENS=[{"label":"Paolo.arena77@gmail.com","value":"M9EM309v8WFquJKpYgZCw-TViM2wX6vB3wlK6GD0"},{"label":"gruppomacro.com","value":"bqmzGShoX7WqOBzkXocoECyBkPq3GfqcM5t6VFd8"}]
|
||||
DS_API_KEY="sk-222e3addb3d8455d8b0516d93906eec7"
|
||||
OLLAMA_URL=http://localhost:11434
|
||||
OLLAMA_DEFAULT_MODEL=llama3.2:3b
|
||||
GROK_API="xai-PcNM5obgPaETtmnfDWPZk235D75ZgxENU2QmeqPfMQCHh9dwCDVeRRe0oVVA2YOpiUDh1uJieZsMasja"
|
||||
REPLICATE_API_TOKEN="r8_AVhM6igwvoOnUA65cHVZdhEDfTqBVk94WTB0u"
|
||||
FAL_KEY="7d251c88-21b5-4b55-8b3e-4bafd910f99f:b81c0a36a25b052f26eb8ac226c7efff"
|
||||
HF_TOKEN="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"
|
||||
@@ -10,8 +10,9 @@ ENABLE_PUSHNOTIFICATION=1
|
||||
DIRECTORY_SERVER=/var/www/nodejs_piuchebuono_server
|
||||
SERVERDIR_WEBSITE=/var/www/piuchebuono.app
|
||||
PORT_APP1="0"
|
||||
DOMAIN=mongodb://localhost:32001/
|
||||
DOMAIN_AUTH=mongodb://{username}:{password}@127.0.0.1:32001/
|
||||
DOMAIN_OFF=mongodb://localhost:32001/
|
||||
DOMAIN_AUTH_OLD=mongodb://{username}:{password}@127.0.0.1:32001/
|
||||
DOMAIN_AUTH=mongodb://{username}:{password}@127.0.0.1:27030/
|
||||
AUTH_MONGODB=1
|
||||
AUTH_DB_PASSING=1
|
||||
MONGODB_USER=admin
|
||||
@@ -29,19 +30,15 @@ PATH_SERVER_CRT=fullchain.pem
|
||||
PROD=1
|
||||
PROJECT_DESCR_MAIN='__PROJECTS'
|
||||
SECRK=iUUb38v23jjDFaosWj92axkBOXCQ
|
||||
TOKEN_LIFE=2h
|
||||
REFRESH_TOKEN_LIFE=14d
|
||||
TOKEN_LIFE=30d
|
||||
REFRESH_TOKEN_LIFE=30d
|
||||
AUTH_NEW_SITES=B234HDSAOJ734ndcsdKWNVZZ
|
||||
DOMAINS=[{"hostname":"piuchebuono.app","port":"3030"},{"hostname":"gruppomacro.app","port":"3010"}]
|
||||
DOMAINS_ALLOWED=["gruppomacro.app","piuchebuono.app"]
|
||||
SCRIPTS_DIR=admin_scripts
|
||||
CLOUDFLARE_TOKENS=[{"label":"Paolo.arena77@gmail.com","value":"M9EM309v8WFquJKpYgZCw-TViM2wX6vB3wlK6GD0"},{"label":"gruppomacro.com","value":"bqmzGShoX7WqOBzkXocoECyBkPq3GfqcM5t6VFd8"}]
|
||||
MIAB_HOST=box.lamiaposta.org
|
||||
MIAB_ADMIN_EMAIL=admin@lamiaposta.org
|
||||
MIAB_ADMIN_PASSWORD=passpao1pabox@1A
|
||||
|
||||
#DB_CONNECTION=sqlsrv
|
||||
DB_HOST_SQLSRVTEST=31.3.180.50
|
||||
DB_PORT_SQLSRVTEST=14338
|
||||
DB_DATABASE_SQLSRVTEST=ANAG_MACRO
|
||||
DB_USERNAME_SQLSRVTEST=woo
|
||||
DB_PASSWORD_SQLSRVTEST=4n4traPe@
|
||||
SERVER_A_URL="http://51.77.156.69:3000"
|
||||
API_KEY_MSSQL="m68yADSr123MIVIDA@154$DSAGVOK"
|
||||
@@ -7,8 +7,9 @@ ENABLE_PUSHNOTIFICATION=1
|
||||
DIRECTORY_SERVER=/var/www/nodejs_riso_server
|
||||
SERVERDIR_WEBSITE=/var/www/riso.app
|
||||
PORT_APP1="0"
|
||||
DOMAIN=mongodb://localhost:32015/
|
||||
DOMAIN_AUTH=mongodb://{username}:{password}@127.0.0.1:32015/
|
||||
DOMAIN_OFF=mongodb://localhost:32015/
|
||||
DOMAIN_AUTH_OLD=mongodb://{username}:{password}@127.0.0.1:32015/
|
||||
DOMAIN_AUTH=mongodb://{username}:{password}@127.0.0.1:27030/
|
||||
AUTH_MONGODB=1
|
||||
AUTH_DB_PASSING=1
|
||||
MONGODB_USER=admin
|
||||
@@ -26,10 +27,12 @@ PATH_SERVER_CRT=fullchain.pem
|
||||
PROD=1
|
||||
PROJECT_DESCR_MAIN='__PROJECTS'
|
||||
SECRK=iUUb38v23jjDFaosWj92axkBOXCQ
|
||||
TOKEN_LIFE=2h
|
||||
REFRESH_TOKEN_LIFE=14d
|
||||
TOKEN_LIFE=30d
|
||||
REFRESH_TOKEN_LIFE=30d
|
||||
AUTH_NEW_SITES=B234HDSAOJ734ndcsdKWNV
|
||||
DOMAINS=[{"hostname":"riso.app","port":"3006"},{"hostname":"freeplanet.app","port":"3000"}]
|
||||
DOMAINS=[{"hostname":"riso.app","port":"3006"},{"hostname":"freeplanet.app","port":"3000"},{"hostname":"nuovomondo.app","port":"3032"}]
|
||||
DOMAINS_NEW=[{"hostname":"riso.app","port":"3006"},{"hostname":"freeplanet.app","port":"3000"},{"hostname":"nuovomondo.app","port":"3032"},{"hostname":"germogliamo.app","port":"3042"}]
|
||||
DOMAINS_ALLOWED=["riso.app","germogliamo.app","comunitanuovomondo.app","nuovomondo.app","kolibrilab.it","artenergetica.org","freeplanet.app","www.freeplanet.app","freeplanet.app:3000","freeplanet.app:3001","www.freeplanet.app:3000","www.freeplanet.app:3001"]
|
||||
#DOMAINS=[{"hostname":"abitaregliiblei.it","port":"3021"},{"hostname":"riso.app","port":"3005"}]
|
||||
SCRIPTS_DIR=admin_scripts
|
||||
CLOUDFLARE_TOKENS=[{"label":"Paolo.arena77@gmail.com","value":"M9EM309v8WFquJKpYgZCw-TViM2wX6vB3wlK6GD0"},{"label":"gruppomacro.com","value":"bqmzGShoX7WqOBzkXocoECyBkPq3GfqcM5t6VFd8"}]
|
||||
|
||||
@@ -15,7 +15,7 @@ DOMAIN_AUTH=mongodb://{username}:{password}@127.0.0.1:32002/
|
||||
AUTH_MONGODB=1
|
||||
AUTH_DB_PASSING=1
|
||||
MONGODB_USER=admin
|
||||
MONGODB_PWD=mypwadmin@1A
|
||||
MONGODB_PWD=mypwadminS1A
|
||||
SIGNCODE=SU2134hncaskjdbo231oihJSDNHEI$1@AB
|
||||
VITE_DEBUG=0
|
||||
LOCALE=0
|
||||
@@ -35,8 +35,11 @@ TOKEN_LIFE=2h
|
||||
REFRESH_TOKEN_LIFE=14d
|
||||
AUTH_NEW_SITES=B234HDSAOJ734ndcsdKWNV
|
||||
DOMAINS=[{"hostname":"piuchebuono.app","port":"3031"},{"hostname":"gruppomacro.app","port":"3011"}]
|
||||
DOMAINS_ALLOWED=[]
|
||||
SCRIPTS_DIR=admin_scripts
|
||||
CLOUDFLARE_TOKENS=[{"label":"Paolo.arena77@gmail.com","value":"M9EM309v8WFquJKpYgZCw-TViM2wX6vB3wlK6GD0"},{"label":"gruppomacro.com","value":"bqmzGShoX7WqOBzkXocoECyBkPq3GfqcM5t6VFd8"}]
|
||||
MIAB_HOST=box.lamiaposta.org
|
||||
MIAB_ADMIN_EMAIL=admin@lamiaposta.org
|
||||
MIAB_ADMIN_PASSWORD=passpao1pabox@1A
|
||||
MIAB_ADMIN_PASSWORD=passpao1pabox@1A
|
||||
SERVER_A_URL="http://51.77.156.69:3000"
|
||||
API_KEY_MSSQL="m68yADSr123MIVIDA@154$DSAGVOK"
|
||||
@@ -28,10 +28,11 @@ PATH_SSL_CHAIN_PEM=chain.pem
|
||||
PROD=0
|
||||
PROJECT_DESCR_MAIN='__PROJECTS'
|
||||
SECRK=iUUb38v23jjDFaosWj92axkBOXCQ
|
||||
TOKEN_LIFE=1m
|
||||
TOKEN_LIFE=2h
|
||||
REFRESH_TOKEN_LIFE=14d
|
||||
AUTH_NEW_SITES=B234HDSAOJ734ndcsdKWNV
|
||||
DOMAINS=[{"hostname":"riso.app","port":"3005"}]
|
||||
DOMAINS=[{"hostname":"riso.app","port":"3005"},{"hostname":"nuovomondo.app","port":"3033"}]
|
||||
DOMAINS_ALLOWED=["riso.app","comunitanuovomondo.app","kolibrilab.it","artenergetica.org","freeplanet.app","www.freeplanet.app","freeplanet.app:3000","freeplanet.app:3001","www.freeplanet.app:3000","www.freeplanet.app:3001"]
|
||||
SCRIPTS_DIR=admin_scripts
|
||||
CLOUDFLARE_TOKENS=[{"label":"Paolo.arena77@gmail.com","value":"M9EM309v8WFquJKpYgZCw-TViM2wX6vB3wlK6GD0"},{"label":"gruppomacro.com","value":"bqmzGShoX7WqOBzkXocoECyBkPq3GfqcM5t6VFd8"}]
|
||||
MIAB_HOST=box.lamiaposta.org
|
||||
|
||||
40
.vscode/launch.json
vendored
40
.vscode/launch.json
vendored
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
@@ -13,7 +13,7 @@
|
||||
"--inspect=9229" // Use "--inspect=0.0.0.0:9229" for remote debugging
|
||||
],
|
||||
"args": [
|
||||
"${workspaceFolder}/src/server/server.js"
|
||||
"${workspaceFolder}/src/server.js"
|
||||
], // Replace with your entry file
|
||||
"cwd": "${workspaceFolder}",
|
||||
"autoAttachChildProcesses": true,
|
||||
@@ -36,7 +36,7 @@
|
||||
"--trace-warnings" // Use "--inspect=0.0.0.0:9229" for remote debugging
|
||||
],
|
||||
"args": [
|
||||
"${workspaceFolder}/src/server/server.js"
|
||||
"${workspaceFolder}/src/server.js"
|
||||
], // Replace with your entry file
|
||||
"cwd": "${workspaceFolder}",
|
||||
"autoAttachChildProcesses": true,
|
||||
@@ -50,7 +50,7 @@
|
||||
},
|
||||
{
|
||||
"name": "ServerSide",
|
||||
"program": "${workspaceFolder}/src/server/server.js",
|
||||
"program": "${workspaceFolder}/src/server.js",
|
||||
"request": "launch",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
@@ -61,5 +61,37 @@
|
||||
"TESTING_ON": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Debug CheckSmartBot",
|
||||
"program": "${workspaceFolder}/../checksmartbot/bot.js",
|
||||
"console": "integratedTerminal",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/../**/*.js"
|
||||
],
|
||||
"envFile": "${workspaceFolder}/.env",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"autoAttachChildProcesses": true,
|
||||
"smartStep": true
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Avvia bot con pm2 (attach)",
|
||||
"runtimeExecutable": "pm2",
|
||||
"runtimeArgs": [
|
||||
"start",
|
||||
"bot.js",
|
||||
"--name",
|
||||
"checksmartbot"
|
||||
],
|
||||
"console": "integratedTerminal",
|
||||
"restart": true,
|
||||
"port": 9229,
|
||||
"attach": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -9,7 +9,7 @@ yarn
|
||||
|
||||
### Start the app in development mode (hot-code reloading, error reporting, etc.)
|
||||
```bash
|
||||
node src/server/server.js
|
||||
node src/server.js
|
||||
```
|
||||
|
||||
### Creating the ambient test
|
||||
|
||||
@@ -66,7 +66,7 @@ db.myelems.insertMany([
|
||||
"listcards": [],
|
||||
"list": [],
|
||||
"__v": 0,
|
||||
"containerHtml": "<style>\nbody {\n font-family: Arial, sans-serif;\n margin: 0;\n padding: 20px;\n background-color: #f0f0f0;\n color: #333;\n}\n\nh1 {\n color: #0056b3;\n text-align: center;\n}\n\n\np, li {\n line-height: 1.6;\n}\n\n\nul {\n list-style-type: none;\n padding: 0;\n}\n\n\nli {\n background-color: #fff !important;\n margin-bottom: 10px !important;\n padding: 10px !important;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) !important; \n}\n\n\na {\n color: #007bff;\n text-decoration: none;\n}\n\n\na:hover {\n text-decoration: underline;\n}\n\n\n.container {\n max-width: 800px;\n margin: 0 auto;\n background-color: #fff;\n padding: 20px;\n box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);\n}\n\n\n.strong {\n font-weight: bold;\n}\n</style>\n\n\n<p><strong>“Abitare gli Iblei”</strong> è una rete aperta che ha lo scopo di riunire tutte quelle persone che vogliono valorizzare e qualificare la vita nel territorio degli Iblei. </p>\n \n <p>Chi aderisce alla rete si riconosce in una <strong>Carta dei valori comuni</strong> e usa la rete per scambiare conoscenze, esperienze, risorse e prodotti sviluppati nell’ambito delle proprie iniziative (profit e non profit) individuali o collettive.</p>\n\n\n <p>L’area territoriale di questa rete è quella dei <strong>Monti Iblei orientali e occidentali</strong> (Noto, Avola, Canicattini, Siracusa, Palazzolo, Buccheri, Ferla, Modica, …).</p>\n\n\n <p>La rete <strong>“Abitare gli Iblei”</strong> offre i seguenti servizi utili per il territorio ed i suoi abitanti, frutto di una costruzione collettiva:</p>\n \n <ul>\n <li><strong>1. Mappa delle attività virtuose:</strong> permette di identificare attività pubbliche e private nel territorio che possono essere utili nella vita quotidiana. Queste attività possono riguardare artigiani, produttori o fornitori di servizi di cui almeno un membro della rete conosca la qualità e l’affidabilità (agricoltori, falegnami, fabbri, idraulici, imprese edili, strutture ricettive, …). Altre informazioni utili possono riguardare associazioni/istituzioni operanti in vari settori. – <strong>Accesso pubblico</strong></li>\n <li><strong>2. Calendario:</strong> permette di accedere ad annunci di eventi utili alla crescita culturale del territorio. La pubblicazione di eventi è riservata ai soli membri della rete che possono presentare iniziative anche di altri organizzatori. – <strong>Accesso pubblico</strong></li>\n <li><strong>3. Scambi di servizi, prodotti e ospitalità:</strong> questa funzione è riservata ai soli membri della rete e si realizza attraverso la Rete italiana di scambi orizzontali (RISO). – <strong>Accesso riservato</strong></li>\n <li><strong>4. Segnalazione di pericoli per il territorio:</strong> attraverso questa mappa è possibile segnalare incendi, immondizia abbandonata, discariche abusive, fonti di inquinamento per corsi d’acqua e spiagge, presenza di inquinamento nell’aria, … – <strong>Accesso riservato</strong></li>\n </ul>\n \n <p>Se vuoi aderire alla rete puoi richiederne la registrazione utilizzando questo Link <a href=\"#\"><strong>(Pagina in Costruzione)</strong></a>.</p>\n\n",
|
||||
"containerHtml": "<style>\nbody {\n font-family: Arial, sans-serif;\n margin: 0;\n padding: 20px;\n background-color: #f0f0f0;\n color: #333;\n}\n\nh1 {\n color: #0056b3;\n text-align: center;\n}\n\n\np, li {\n line-height: 1.6;\n}\n\n\nul {\n list-style-type: none;\n padding: 0;\n}\n\n\nli {\n background-color: #fff !important;\n margin-bottom: 10px !important;\n padding: 10px !important;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) !important; \n}\n\n\na {\n color: #007bff;\n text-decoration: none;\n}\n\n\na:hover {\n text-decoration: underline;\n}\n\n\n.container {\n max-width: 800px;\n margin: 0 auto;\n background-color: #fff;\n padding: 20px;\n box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);\n}\n\n\n.strong {\n font-weight: bold;\n}\n</style>\n\n\n<p><strong>“Abitare gli Iblei”</strong> è una rete aperta che ha lo scopo di riunire tutte quelle persone che vogliono valorizzare e qualificare la vita nel territorio degli Iblei. </p>\n \n <p>Chi aderisce alla rete si riconosce in una <strong>Carta dei valori comuni</strong> e usa la rete per scambiare conoscenze, esperienze, risorse e prodotti sviluppati nell’ambito delle proprie iniziative (profit e non profit) individuali o collettive.</p>\n\n\n <p>L’area territoriale di questa rete è quella dei <strong>Monti Iblei orientali e occidentali</strong> (Noto, Avola, Canicattini, Siracusa, Palazzolo, Buccheri, Ferla, Modica, …).</p>\n\n\n <p>La rete <strong>“Abitare gli Iblei”</strong> offre i seguenti servizi utili per il territorio ed i suoi abitanti, frutto di una costruzione collettiva:</p>\n \n <ul>\n <li><strong>1. Mappa delle attività virtuose:</strong> permette di identificare attività pubbliche e private nel territorio che possono essere utili nella vita quotidiana. Queste attività possono riguardare artigiani, produttori o fornitori di servizi di cui almeno un membro della rete conosca la qualità e l’affidabilità (agricoltori, falegnami, fabbri, idraulici, imprese edili, strutture ricettive, …). Altre informazioni utili possono riguardare associazioni/istituzioni operanti in vari settori. – <strong>Accesso pubblico</strong></li>\n <li><strong>2. Calendario:</strong> permette di accedere ad annunci di eventi utili alla crescita culturale del territorio. La pubblicazione di eventi è riservata ai soli membri della rete che possono presentare iniziative anche di altri organizzatori. – <strong>Accesso pubblico</strong></li>\n <li><strong>3. Scambi di servizi, prodotti e ospitalità:</strong> questa funzione è riservata ai soli membri della rete e si realizza attraverso la Rete Italiana scambio orizzontale (RISO). – <strong>Accesso riservato</strong></li>\n <li><strong>4. Segnalazione di pericoli per il territorio:</strong> attraverso questa mappa è possibile segnalare incendi, immondizia abbandonata, discariche abusive, fonti di inquinamento per corsi d’acqua e spiagge, presenza di inquinamento nell’aria, … – <strong>Accesso riservato</strong></li>\n </ul>\n \n <p>Se vuoi aderire alla rete puoi richiederne la registrazione utilizzando questo Link <a href=\"#\"><strong>(Pagina in Costruzione)</strong></a>.</p>\n\n",
|
||||
"anim": {
|
||||
"_id": new ObjectId("66db393e3b885ccdfaed28d6"),
|
||||
"name": "",
|
||||
|
||||
@@ -11,9 +11,9 @@ db.mypages.insertMany([
|
||||
"_id": new ObjectId("66db21118009ea4503bb6a03"),
|
||||
"order": 10,
|
||||
"idapp": "19",
|
||||
"path": "home_logout",
|
||||
"path": "presentazione",
|
||||
"active": true,
|
||||
"title": "Home NoLoggato",
|
||||
"title": "Presentazione",
|
||||
},
|
||||
{
|
||||
"_id": new ObjectId("66e322dd5a6360e3b3c71c5a"),
|
||||
|
||||
@@ -164,7 +164,9 @@ db.users.insertMany([
|
||||
"stepTutorial": 0,
|
||||
"noNameSurname": false,
|
||||
"noCircuit": false,
|
||||
"noComune": false,
|
||||
"noCircIta": false,
|
||||
"insert_circuito_ita": false,
|
||||
"noFoto": false,
|
||||
"resid_province": "",
|
||||
"resid_card": "",
|
||||
@@ -281,7 +283,9 @@ db.users.insertMany([
|
||||
"stepTutorial": 0,
|
||||
"noNameSurname": false,
|
||||
"noCircuit": false,
|
||||
"noComune": false,
|
||||
"noCircIta": false,
|
||||
"insert_circuito_ita": false,
|
||||
"noFoto": false,
|
||||
"resid_province": "",
|
||||
"resid_card": "",
|
||||
|
||||
1
aggiornaserver.txt
Executable file
1
aggiornaserver.txt
Executable file
@@ -0,0 +1 @@
|
||||
Aggiornamento Server...
|
||||
@@ -80,7 +80,8 @@ p {
|
||||
|
||||
/* Whitespace (imageless spacer) */
|
||||
.whitespace {
|
||||
line-height: 0; }
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
.firma {
|
||||
font-size: 0.75rem; }
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
source ./.env.prod.pcb
|
||||
|
||||
echo "Sincronizzazione in corso PCB PRODUZIONE ... $DIRECTORY_SERVER/"
|
||||
echo ""
|
||||
|
||||
msg="*** SERVER DI ### PRODUZIONE ### PCB **** INVIARE GLI AGGIORNAMENTI ? (Y/N)"
|
||||
msg="*** SERVER DI PRODUZIONE PCB **** INVIARE GLI AGGIORNAMENTI ? (Y/N)"
|
||||
|
||||
if [ "$1" = "" ]; then
|
||||
read -p "$msg" risposta
|
||||
@@ -17,7 +19,6 @@ if [[ $risposta == "Y" || $risposta == "y" ]]; then
|
||||
echo "Sincronizzazione in corso PCB PRODUZIONE ... $DIRECTORY_SERVER/"
|
||||
echo ""
|
||||
|
||||
|
||||
# Configurazione
|
||||
REMOTE_USER="pcbuser"
|
||||
REMOTE_HOST="pcb"
|
||||
@@ -25,6 +26,10 @@ if [[ $risposta == "Y" || $risposta == "y" ]]; then
|
||||
REMOTE_DIR="$DIRECTORY_SERVER"
|
||||
SSH_OPTIONS="-p $REMOTE_PORT"
|
||||
|
||||
CONFIG_JS="ecosystem.config.pcb_prod.js"
|
||||
ENV_FILE=".env.prod.pcb"
|
||||
ENV_OUT=".env.production"
|
||||
|
||||
# Array di cartelle e file da sincronizzare
|
||||
SYNC_ITEMS=(
|
||||
"css"
|
||||
@@ -54,7 +59,8 @@ if [[ $risposta == "Y" || $risposta == "y" ]]; then
|
||||
|
||||
# Sincronizza i file specifici
|
||||
rsync -avz -e "ssh $SSH_OPTIONS" \
|
||||
.env.prod.pcb "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/.env.production"
|
||||
$ENV_FILE "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/$ENV_OUT"
|
||||
|
||||
|
||||
echo ""
|
||||
echo "*** Copia del file package.json ... "
|
||||
@@ -62,15 +68,20 @@ if [[ $risposta == "Y" || $risposta == "y" ]]; then
|
||||
package.json "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/package.json"
|
||||
|
||||
echo ""
|
||||
echo "*** Copia del file ecosystem.config.js ... "
|
||||
echo "*** Copia del file $CONFIG_JS in ecosystem.config.js ... "
|
||||
rsync -avz -e "ssh $SSH_OPTIONS" \
|
||||
ecosystem.config.pcb.js "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/ecosystem.config.js"
|
||||
$CONFIG_JS "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/ecosystem.config.js"
|
||||
|
||||
echo ""
|
||||
echo "*** Copia del file aggiornaserver.txt ... "
|
||||
rsync -avz -e "ssh $SSH_OPTIONS" \
|
||||
aggiornaserver.txt "$REMOTE_USER@$REMOTE_HOST:/opt/scripts/aggiornaserver_pcb_prod.txt"
|
||||
|
||||
# Verifica il risultato
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Sincronizzazione completata con successo. SERVER PCB! "
|
||||
echo "Sincronizzazione completata con successo. SERVER PCB PRODUZIONE! "
|
||||
else
|
||||
echo "Errore durante la sincronizzazione. Controlla l'output per i dettagli."
|
||||
fi
|
||||
|
||||
fi
|
||||
fi
|
||||
@@ -26,8 +26,8 @@ if [[ $risposta == "Y" || $risposta == "y" ]]; then
|
||||
REMOTE_DIR="$DIRECTORY_SERVER"
|
||||
SSH_OPTIONS="-p $REMOTE_PORT"
|
||||
|
||||
CONFIG_JS="ecosystem.config.testriso.js"
|
||||
ENV_FILE=".env.test.risosrv"
|
||||
CONFIG_JS="ecosystem.config.pcb_test.js"
|
||||
ENV_FILE=".env.test.pcb"
|
||||
ENV_OUT=".env.test"
|
||||
|
||||
# Array di cartelle e file da sincronizzare
|
||||
@@ -67,16 +67,16 @@ if [[ $risposta == "Y" || $risposta == "y" ]]; then
|
||||
rsync -avz -e "ssh $SSH_OPTIONS" \
|
||||
package.json "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/package.json"
|
||||
|
||||
echo ""
|
||||
echo "*** Copia del file ecosystem.config.testpcb.js in ecosystem.config.js ... "
|
||||
rsync -avz -e "ssh $SSH_OPTIONS" \
|
||||
ecosystem.config.testpcb.js "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/ecosystem.config.js"
|
||||
|
||||
echo ""
|
||||
echo "*** Copia del file $CONFIG_JS in ecosystem.config.js ... "
|
||||
rsync -avz -e "ssh $SSH_OPTIONS" \
|
||||
$CONFIG_JS "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/ecosystem.config.js"
|
||||
|
||||
echo ""
|
||||
echo "*** Copia del file aggiornaserver.txt ... "
|
||||
rsync -avz -e "ssh $SSH_OPTIONS" \
|
||||
aggiornaserver.txt "$REMOTE_USER@$REMOTE_HOST:/opt/scripts/aggiornaserver_pcb_test.txt"
|
||||
|
||||
# Verifica il risultato
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Sincronizzazione completata con successo. SERVER PCB TEST! "
|
||||
|
||||
@@ -22,13 +22,10 @@ if [[ $risposta == "Y" || $risposta == "y" ]]; then
|
||||
REMOTE_PORT="8822"
|
||||
REMOTE_DIR="$DIRECTORY_SERVER"
|
||||
SSH_OPTIONS="-p $REMOTE_PORT"
|
||||
CONFIG_JS="ecosystem.config.prod_riso.js"
|
||||
CONFIG_JS="ecosystem.config.riso_prod.js"
|
||||
ENV_FILE=".env.prod.riso"
|
||||
ENV_OUT=".env.production"
|
||||
|
||||
#ENV_FILE=".env.prod.pcb"
|
||||
#ENV_OUT=".env.production"
|
||||
|
||||
# Array di cartelle e file da sincronizzare
|
||||
SYNC_ITEMS=(
|
||||
"css"
|
||||
@@ -70,6 +67,12 @@ if [[ $risposta == "Y" || $risposta == "y" ]]; then
|
||||
rsync -avz -e "ssh $SSH_OPTIONS" \
|
||||
"$CONFIG_JS" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/ecosystem.config.js"
|
||||
|
||||
echo ""
|
||||
echo "*** Copia del file aggiornaserver.txt ... "
|
||||
rsync -avz -e "ssh $SSH_OPTIONS" \
|
||||
aggiornaserver.txt "$REMOTE_USER@$REMOTE_HOST:/opt/scripts/aggiornaserver_riso_prod.txt"
|
||||
|
||||
|
||||
# Verifica il risultato
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✅ Sincronizzazione completata con successo. SERVER $REMOTE_DIR! "
|
||||
|
||||
@@ -22,7 +22,7 @@ if [[ $risposta == "Y" || $risposta == "y" ]]; then
|
||||
REMOTE_PORT="8822"
|
||||
REMOTE_DIR="$DIRECTORY_SERVER"
|
||||
SSH_OPTIONS="-p $REMOTE_PORT"
|
||||
CONFIG_JS="ecosystem.config.testriso.js"
|
||||
CONFIG_JS="ecosystem.config.riso_test.js"
|
||||
ENV_FILE=".env.test.risosrv"
|
||||
ENV_OUT=".env.test"
|
||||
|
||||
@@ -75,6 +75,11 @@ if [[ $risposta == "Y" || $risposta == "y" ]]; then
|
||||
rsync -avz -e "ssh $SSH_OPTIONS" \
|
||||
$CONFIG_JS "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/ecosystem.config.js"
|
||||
|
||||
echo ""
|
||||
echo "*** Copia del file aggiornaserver.txt ... "
|
||||
rsync -avz -e "ssh $SSH_OPTIONS" \
|
||||
aggiornaserver.txt "$REMOTE_USER@$REMOTE_HOST:/opt/scripts/aggiornaserver_riso_test.txt"
|
||||
|
||||
|
||||
# Verifica il risultato
|
||||
if [ $? -eq 0 ]; then
|
||||
|
||||
38
docs/aaa.json
Normal file
38
docs/aaa.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"id": "70606",
|
||||
"title": "Grande Libro dell'Autosufficienza - 50 anni - Nuovo",
|
||||
"description": "<em><strong>\"Il Grande Libro dell\u2019Autosufficienza\"<\/strong><\/em> di John Seymour \u00e8 un manuale completo che celebra 50 anni di pratiche di <strong>autosufficienza<\/strong> e <strong>sostenibilit\u00e0<\/strong>. Il libro offre insegnamenti pratici su come creare e gestire un <strong>orto biologico<\/strong>, raccogliere e conservare i raccolti, produrre <strong>energia rinnovabile<\/strong>, allevare animali e ridurre i rifiuti. Seymour ci guida passo passo in un viaggio verso una vita in armonia con la natura, promuovendo l\u2019indipendenza e la sostenibilit\u00e0. Un testo imprescindibile per chi desidera riscoprire le tradizioni agricole e applicarle per vivere in modo pi\u00f9 <strong>sostenibile<\/strong> e <strong>autonomo<\/strong>.\r\n<h2><strong>Con questo libro scoprirai<\/strong>:<\/h2>\r\n<ul>\r\n \t<li>Come <strong>coltivare un orto biologico<\/strong> e ottenere cibo sano.<\/li>\r\n \t<li>Le tecniche per <strong>conservare il raccolto<\/strong> e ottimizzare le risorse naturali.<\/li>\r\n \t<li>Come allevare animali per ottenere cibo e altri prodotti.<\/li>\r\n \t<li>Come produrre <strong>energia rinnovabile<\/strong> e ridurre l\u2019impatto ambientale.<\/li>\r\n \t<li>L\u2019arte di <strong>ridurre e riciclare<\/strong> rifiuti, promuovendo uno stile di vita pi\u00f9 sostenibile.<\/li>\r\n<\/ul>\r\n<h2><strong>Domande cruciali a cui <em>\"Il Grande Libro dell\u2019Autosufficienza\"<\/em> risponde<\/strong>:<\/h2>\r\n<ul>\r\n \t<li>Come posso vivere in modo <strong>autosufficiente<\/strong> e ridurre la mia dipendenza dalle risorse esterne?<\/li>\r\n \t<li>Quali sono le migliori tecniche per <strong>coltivare un orto biologico<\/strong> e garantire un raccolto abbondante?<\/li>\r\n \t<li>Come posso <strong>conservare il raccolto<\/strong> in modo naturale e duraturo?<\/li>\r\n \t<li>In che modo posso <strong>produrre energia rinnovabile<\/strong> a casa mia?<\/li>\r\n \t<li>Come posso vivere in <strong>armonia con la natura<\/strong> e promuovere la <strong>sostenibilit\u00e0<\/strong>?<\/li>\r\n<\/ul>\r\n<h2><strong>Questo libro \u00e8 dedicato a<\/strong>:<\/h2>\r\n<ul>\r\n \t<li>Lettori appassionati di <strong>giardinaggio<\/strong>, <strong>agricoltura biologica<\/strong> e vita rurale.<\/li>\r\n \t<li>Chiunque desideri adottare uno <strong>stile di vita sostenibile<\/strong> e autosufficiente.<\/li>\r\n \t<li><strong>Famiglie eco-consapevoli<\/strong> che vogliono ridurre il proprio impatto ambientale.<\/li>\r\n \t<li><strong>Amanti della natura<\/strong> e sostenitori delle <strong>energie rinnovabili<\/strong>.<\/li>\r\n<\/ul>\r\n<h2><strong>Contenuti chiave <em>\"Il Grande Libro dell\u2019Autosufficienza\"<\/em><\/strong>:<\/h2>\r\n<em>Il Grande Libro dell\u2019Autosufficienza<\/em> offre una panoramica completa di tutte le tecniche per vivere in modo <strong>autonomo<\/strong> e <strong>sostenibile<\/strong>. Attraverso 10 capitoli, il libro esplora vari aspetti dell\u2019autosufficienza, dalla coltivazione di ortaggi e frutti alla produzione di cibo dagli animali, fino alla gestione dell'energia e dei rifiuti. La guida si focalizza sul valore delle <strong>tradizioni agricole<\/strong>, sulla cura dell\u2019ambiente e sul benessere che deriva dal vivere in sintonia con la natura.\r\n\r\n ",
|
||||
"link": "https:\/\/www.fioredellavita.it\/grande-libro-dellautosufficienza-50-anni\/?attribute_pa_versione=nuovo",
|
||||
"image_link": "https:\/\/www.fioredellavita.it\/wp-content\/uploads\/2024\/09\/il-grande-libro-dell-autosufficienza-speciale-50-anni-copertina-web.jpg",
|
||||
"price": "39,00",
|
||||
"sale_price": "37,05",
|
||||
"categories": "Informazione Libera",
|
||||
"isbn": "",
|
||||
"Autore": "John,Seymour",
|
||||
"Editore": "Macro Edizioni",
|
||||
"Tipologia": "Libri",
|
||||
"Collezione": "Libri Informazione Libera,Informazione Libera",
|
||||
"Quantita": "1821",
|
||||
"Lunghezza": "",
|
||||
"Stato": "publish",
|
||||
"Pagine": "",
|
||||
"Edizione": "",
|
||||
"Traduzione": "",
|
||||
"Versione": "Nuovo",
|
||||
"StockStatus": "instock",
|
||||
"downloadable": "no",
|
||||
"img1": "https:\/\/www.fioredellavita.it\/wp-content\/uploads\/2024\/09\/quarta_nuovo_grande_libro_dell_autosufficienza_2024_17038.jpg",
|
||||
"img2": "",
|
||||
"img3": "",
|
||||
"formato": "Cartonato",
|
||||
"preOrderDate": "2025-02-25",
|
||||
"short_descr": null,
|
||||
"availability": "in stock",
|
||||
"checkout_link": "https:\/\/www.fioredellavita.it\/carrello\/?productId=70606",
|
||||
"seo_descr": "Versione: Nuovo",
|
||||
"preord": "no",
|
||||
"addtocart_link": "https:\/\/www.fioredellavita.it\/grande-libro-dellautosufficienza-50-anni\/?attribute_pa_versione=nuovo&variation_id=70606&add-to-cart=70606",
|
||||
"eta": "",
|
||||
"misure": "cm 22x28",
|
||||
"sku": "22464"
|
||||
},
|
||||
@@ -0,0 +1,4 @@
|
||||
Define MIODOMINIO riso.app
|
||||
Define MIODOMINIO_COMPLETO test.riso.app
|
||||
Define MIOURL_API testapi.riso.app
|
||||
Define PORTA 3005
|
||||
@@ -0,0 +1,30 @@
|
||||
<VirtualHost 65.108.222.97:80>
|
||||
ServerName ${MIODOMINIO_COMPLETO}
|
||||
RewriteEngine On
|
||||
|
||||
# Forza la connessione HTTPS
|
||||
RewriteCond %{HTTPS} off
|
||||
RewriteRule ^ https://${MIODOMINIO_COMPLETO}%{REQUEST_URI} [L,R=301]
|
||||
</VirtualHost>
|
||||
|
||||
<VirtualHost 65.108.222.97:443>
|
||||
ServerName ${MIODOMINIO_COMPLETO}
|
||||
DocumentRoot /var/www/${MIODOMINIO_COMPLETO}
|
||||
ServerAdmin surya@riso.app
|
||||
SSLEngine On
|
||||
SSLProtocol -ALL +TLSv1.2
|
||||
SSLCompression Off
|
||||
SSLHonorCipherOrder off
|
||||
SSLCipherSuite ECDH+AESGCM:ECDH+AES256:!aNULL:!MD5:!DSS:!DH:!AES128
|
||||
SSLVerifyDepth 10
|
||||
SSLCertificateFile /etc/letsencrypt/live/${MIODOMINIO}/cert.pem
|
||||
SSLCertificateKeyFile /etc/letsencrypt/live/${MIODOMINIO}/privkey.pem
|
||||
<Directory /var/www/${MIODOMINIO_COMPLETO}/>
|
||||
CGIPassAuth On
|
||||
Require all granted
|
||||
AllowOverride All
|
||||
</Directory>
|
||||
LogLevel warn
|
||||
ErrorLog "/var/www/${MIODOMINIO_COMPLETO}/logs/error.log"
|
||||
CustomLog "/var/www/${MIODOMINIO_COMPLETO}/logs/access.log" combined
|
||||
</VirtualHost>
|
||||
11
docs/apache2/sites-available/000-default-ssl.conf
Normal file
11
docs/apache2/sites-available/000-default-ssl.conf
Normal file
@@ -0,0 +1,11 @@
|
||||
<VirtualHost *:443>
|
||||
ServerName _default_
|
||||
SSLEngine on
|
||||
SSLCertificateFile /etc/letsencrypt/live/riso.app/fullchain.pem
|
||||
SSLCertificateKeyFile /etc/letsencrypt/live/riso.app/privkey.pem
|
||||
Include /etc/letsencrypt/options-ssl-apache.conf
|
||||
Protocols h2 http/1.1
|
||||
|
||||
# Puoi anche fare un 403:
|
||||
Redirect 403 /
|
||||
</VirtualHost>
|
||||
@@ -0,0 +1,4 @@
|
||||
Define MIODOMINIO riso.app
|
||||
Define MIODOMINIO_COMPLETO riso.app
|
||||
Define MIOURL_API api.riso.app
|
||||
Define PORTA 3006
|
||||
3
docs/apache2/sites-available/websites_ssl.riso.app.conf
Normal file
3
docs/apache2/sites-available/websites_ssl.riso.app.conf
Normal file
@@ -0,0 +1,3 @@
|
||||
Include /etc/apache2/sites-available/dominioinclude.riso.app.conf
|
||||
|
||||
Include /etc/apache2/sites-available/websites_ssl_virtualhost.conf
|
||||
@@ -0,0 +1,3 @@
|
||||
Include /etc/apache2/sites-available/dominioinclude_test.riso.app.conf
|
||||
|
||||
Include /etc/apache2/sites-available/websites_ssl_virtualhost_sottodomini.conf
|
||||
@@ -1,30 +1,94 @@
|
||||
<VirtualHost 65.108.222.97:80>
|
||||
ServerName ${MIODOMINIO_COMPLETO}
|
||||
RewriteEngine On
|
||||
# ==================== APEX (SITO) ====================
|
||||
# HTTP -> HTTPS
|
||||
<VirtualHost *:80>
|
||||
ServerName ${MIODOMINIO}
|
||||
ServerAlias www.${MIODOMINIO}
|
||||
|
||||
# Forza la connessione HTTPS
|
||||
RewriteCond %{HTTPS} off
|
||||
RewriteRule ^ https://${MIODOMINIO_COMPLETO}%{REQUEST_URI} [L,R=301]
|
||||
RewriteEngine On
|
||||
RewriteRule ^ https://${MIODOMINIO}%{REQUEST_URI} [R=301,L]
|
||||
|
||||
ErrorLog /var/log/apache2/${MIODOMINIO}-error.log
|
||||
CustomLog /var/log/apache2/${MIODOMINIO}-access.log combined
|
||||
</VirtualHost>
|
||||
|
||||
<VirtualHost 65.108.222.97:443>
|
||||
ServerName ${MIODOMINIO_COMPLETO}
|
||||
DocumentRoot /var/www/${MIODOMINIO_COMPLETO}
|
||||
ServerAdmin surya@riso.app
|
||||
SSLEngine On
|
||||
SSLProtocol -ALL +TLSv1.2
|
||||
SSLCompression Off
|
||||
SSLHonorCipherOrder off
|
||||
SSLCipherSuite ECDH+AESGCM:ECDH+AES256:!aNULL:!MD5:!DSS:!DH:!AES128
|
||||
SSLVerifyDepth 10
|
||||
SSLCertificateFile /etc/letsencrypt/live/${MIODOMINIO}/cert.pem
|
||||
SSLCertificateKeyFile /etc/letsencrypt/live/${MIODOMINIO}/privkey.pem
|
||||
<Directory /var/www/${MIODOMINIO_COMPLETO}/>
|
||||
CGIPassAuth On
|
||||
Require all granted
|
||||
AllowOverride All
|
||||
</Directory>
|
||||
LogLevel warn
|
||||
ErrorLog "/var/www/${MIODOMINIO_COMPLETO}/logs/error.log"
|
||||
CustomLog "/var/www/${MIODOMINIO_COMPLETO}/logs/access.log" combined
|
||||
# HTTPS (servizio sito - NO proxy qui)
|
||||
<VirtualHost *:443>
|
||||
ServerName ${MIODOMINIO}
|
||||
ServerAlias www.${MIODOMINIO}
|
||||
|
||||
DocumentRoot /var/www/${MIODOMINIO_COMPLETO}
|
||||
|
||||
SSLEngine on
|
||||
SSLCertificateFile /etc/letsencrypt/live/${MIODOMINIO}/fullchain.pem
|
||||
SSLCertificateKeyFile /etc/letsencrypt/live/${MIODOMINIO}/privkey.pem
|
||||
Include /etc/letsencrypt/options-ssl-apache.conf
|
||||
Protocols h2 http/1.1
|
||||
|
||||
<Directory "/var/www/${MIODOMINIO_COMPLETO}">
|
||||
Options Indexes FollowSymLinks
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
DirectoryIndex index.html
|
||||
|
||||
# (Opzionale per SPA Quasar/Vue)
|
||||
# RewriteEngine On
|
||||
# RewriteCond %{REQUEST_FILENAME} !-f
|
||||
# RewriteCond %{REQUEST_FILENAME} !-d
|
||||
# RewriteRule ^ /index.html [L]
|
||||
|
||||
ErrorLog /var/log/apache2/${MIODOMINIO}-error.log
|
||||
CustomLog /var/log/apache2/${MIODOMINIO}-access.log combined
|
||||
</VirtualHost>
|
||||
|
||||
|
||||
# ==================== API ====================
|
||||
# HTTP -> HTTPS
|
||||
<VirtualHost *:80>
|
||||
ServerName ${MIOURL_API}
|
||||
|
||||
RewriteEngine On
|
||||
RewriteRule ^ https://${MIOURL_API}%{REQUEST_URI} [R=301,L]
|
||||
|
||||
ErrorLog /var/log/apache2/${MIOURL_API}-error.log
|
||||
CustomLog /var/log/apache2/${MIOURL_API}-access.log combined
|
||||
</VirtualHost>
|
||||
|
||||
# HTTPS (proxy verso backend)
|
||||
<VirtualHost *:443>
|
||||
ServerName ${MIOURL_API}
|
||||
ServerAdmin surya@riso.app
|
||||
|
||||
SSLEngine on
|
||||
SSLCertificateFile /etc/letsencrypt/live/${MIODOMINIO}/fullchain.pem
|
||||
SSLCertificateKeyFile /etc/letsencrypt/live/${MIODOMINIO}/privkey.pem
|
||||
Include /etc/letsencrypt/options-ssl-apache.conf
|
||||
Protocols h2 http/1.1
|
||||
|
||||
ProxyPreserveHost On
|
||||
|
||||
# ===== SCEGLI UNO DEI DUE BLOCCHI, in base al TUO backend su ${PORTA} =====
|
||||
# --- Backend HTTP (più comune) ---
|
||||
# ProxyPass / http://127.0.0.1:${PORTA}/ retry=0 timeout=310 connectiontimeout=30
|
||||
# ProxyPassReverse / http://127.0.0.1:${PORTA}/
|
||||
|
||||
# --- Backend HTTPS (nel tuo caso probabile, visto l’“Empty reply” via HTTP) ---
|
||||
SSLProxyEngine On
|
||||
SSLProxyVerify none
|
||||
SSLProxyCheckPeerName off
|
||||
ProxyPass / https://127.0.0.1:${PORTA}/ retry=0 timeout=310 connectiontimeout=30
|
||||
ProxyPassReverse / https://127.0.0.1:${PORTA}/
|
||||
# ==========================================================================
|
||||
|
||||
<Proxy *>
|
||||
Require all granted
|
||||
</Proxy>
|
||||
|
||||
ProxyTimeout 310
|
||||
Timeout 310
|
||||
ProxyBadHeader Ignore
|
||||
|
||||
ErrorLog /var/log/apache2/${MIOURL_API}-error.log
|
||||
CustomLog /var/log/apache2/${MIOURL_API}-access.log combined
|
||||
</VirtualHost>
|
||||
@@ -0,0 +1,92 @@
|
||||
# ==================== APEX (SITO) ====================
|
||||
# HTTP -> HTTPS
|
||||
<VirtualHost *:80>
|
||||
ServerName ${MIODOMINIO_COMPLETO}
|
||||
|
||||
RewriteEngine On
|
||||
RewriteRule ^ https://${MIODOMINIO_COMPLETO}%{REQUEST_URI} [R=301,L]
|
||||
|
||||
ErrorLog /var/log/apache2/${MIODOMINIO_COMPLETO}-error.log
|
||||
CustomLog /var/log/apache2/${MIODOMINIO_COMPLETO}-access.log combined
|
||||
</VirtualHost>
|
||||
|
||||
# HTTPS (servizio sito - NO proxy qui)
|
||||
<VirtualHost *:443>
|
||||
ServerName ${MIODOMINIO_COMPLETO}
|
||||
|
||||
DocumentRoot /var/www/${MIODOMINIO_COMPLETO}
|
||||
|
||||
SSLEngine on
|
||||
SSLCertificateFile /etc/letsencrypt/live/${MIODOMINIO}/fullchain.pem
|
||||
SSLCertificateKeyFile /etc/letsencrypt/live/${MIODOMINIO}/privkey.pem
|
||||
Include /etc/letsencrypt/options-ssl-apache.conf
|
||||
Protocols h2 http/1.1
|
||||
|
||||
<Directory "/var/www/${MIODOMINIO_COMPLETO}">
|
||||
Options Indexes FollowSymLinks
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
DirectoryIndex index.html
|
||||
|
||||
# (Opzionale per SPA Quasar/Vue)
|
||||
# RewriteEngine On
|
||||
# RewriteCond %{REQUEST_FILENAME} !-f
|
||||
# RewriteCond %{REQUEST_FILENAME} !-d
|
||||
# RewriteRule ^ /index.html [L]
|
||||
|
||||
ErrorLog /var/log/apache2/${MIODOMINIO_COMPLETO}-error.log
|
||||
CustomLog /var/log/apache2/${MIODOMINIO_COMPLETO}-access.log combined
|
||||
</VirtualHost>
|
||||
|
||||
|
||||
# ==================== API ====================
|
||||
# HTTP -> HTTPS
|
||||
<VirtualHost *:80>
|
||||
ServerName ${MIOURL_API}
|
||||
|
||||
RewriteEngine On
|
||||
RewriteRule ^ https://${MIOURL_API}%{REQUEST_URI} [R=301,L]
|
||||
|
||||
ErrorLog /var/log/apache2/${MIOURL_API}-error.log
|
||||
CustomLog /var/log/apache2/${MIOURL_API}-access.log combined
|
||||
</VirtualHost>
|
||||
|
||||
# HTTPS (proxy verso backend)
|
||||
<VirtualHost *:443>
|
||||
ServerName ${MIOURL_API}
|
||||
ServerAdmin surya@riso.app
|
||||
|
||||
SSLEngine on
|
||||
SSLCertificateFile /etc/letsencrypt/live/${MIODOMINIO}/fullchain.pem
|
||||
SSLCertificateKeyFile /etc/letsencrypt/live/${MIODOMINIO}/privkey.pem
|
||||
Include /etc/letsencrypt/options-ssl-apache.conf
|
||||
Protocols h2 http/1.1
|
||||
|
||||
ProxyPreserveHost On
|
||||
|
||||
# ===== SCEGLI UNO DEI DUE BLOCCHI, in base al TUO backend su ${PORTA} =====
|
||||
# --- Backend HTTP (più comune) ---
|
||||
# ProxyPass / http://127.0.0.1:${PORTA}/ retry=0 timeout=310 connectiontimeout=30
|
||||
# ProxyPassReverse / http://127.0.0.1:${PORTA}/
|
||||
|
||||
# --- Backend HTTPS (nel tuo caso probabile, visto l’“Empty reply” via HTTP) ---
|
||||
SSLProxyEngine On
|
||||
SSLProxyVerify none
|
||||
SSLProxyCheckPeerName off
|
||||
ProxyPass / https://127.0.0.1:${PORTA}/ retry=0 timeout=310 connectiontimeout=30
|
||||
ProxyPassReverse / https://127.0.0.1:${PORTA}/
|
||||
# ==========================================================================
|
||||
|
||||
<Proxy *>
|
||||
Require all granted
|
||||
</Proxy>
|
||||
|
||||
ProxyTimeout 310
|
||||
Timeout 310
|
||||
ProxyBadHeader Ignore
|
||||
|
||||
ErrorLog /var/log/apache2/${MIOURL_API}-error.log
|
||||
CustomLog /var/log/apache2/${MIOURL_API}-access.log combined
|
||||
</VirtualHost>
|
||||
@@ -1,839 +0,0 @@
|
||||
require('./config/config');
|
||||
require('./config/config');
|
||||
|
||||
// console.log(" lodash");
|
||||
|
||||
console.log(process.versions);
|
||||
|
||||
const _ = require('lodash');
|
||||
// console.log(" cors");
|
||||
const cors = require('cors');
|
||||
|
||||
// console.log(" 2) fs");
|
||||
const fs = require('fs');
|
||||
|
||||
var https = require('https');
|
||||
|
||||
const NUOVO_METODO_TEST = true;
|
||||
|
||||
const server_constants = require('./tools/server_constants');
|
||||
|
||||
//const throttle = require('express-throttle-bandwidth');
|
||||
// app.use(throttle(1024 * 128)) // throttling bandwidth
|
||||
|
||||
const port = process.env.PORT;
|
||||
|
||||
// var cookieParser = require('cookie-parser')
|
||||
// var csrf = require('csurf')
|
||||
const express = require('express');
|
||||
const bodyParser = require('body-parser');
|
||||
const path = require('path');
|
||||
|
||||
const cron = require('node-cron');
|
||||
console.log('Starting mongoose...');
|
||||
|
||||
const tls = require('tls');
|
||||
|
||||
require('./db/mongoose');
|
||||
|
||||
// console.log('Starting pem...');
|
||||
|
||||
// const pem = require('pem')
|
||||
|
||||
const { Settings } = require('./models/settings');
|
||||
|
||||
const Site = require('./models/site');
|
||||
|
||||
// test
|
||||
|
||||
const i18n = require('i18n');
|
||||
|
||||
let credentials = null;
|
||||
|
||||
// OBTAIN
|
||||
// https://www.psclistens.com/insight/blog/enabling-a-nodejs-ssl-webserver-using-let-s-encrypt-pem-certificates/
|
||||
|
||||
|
||||
if ((process.env.NODE_ENV === 'production')) {
|
||||
console.log('*** AMBIENTE DI PRODUZIONE (Aprile 2024) !!!!')
|
||||
} else if (process.env.NODE_ENV === 'test') {
|
||||
console.log('*** ### AMBIENTE DI TEST ')
|
||||
}
|
||||
|
||||
|
||||
console.log('DB: ' + process.env.DATABASE);
|
||||
// console.log("PORT: " + port);
|
||||
// console.log("MONGODB_URI: " + process.env.MONGODB_URI);
|
||||
|
||||
var app = express();
|
||||
|
||||
|
||||
let telegrambot = null;
|
||||
|
||||
const tools = require('./tools/general');
|
||||
|
||||
const shared_consts = require('./tools/shared_nodejs');
|
||||
|
||||
var mongoose = require('mongoose').set('debug', false);
|
||||
|
||||
mongoose.set('debug', false);
|
||||
|
||||
const { CfgServer } = require('./models/cfgserver');
|
||||
const { ObjectId } = require('mongodb');
|
||||
|
||||
const populate = require('./populate/populate');
|
||||
const { Circuit } = require('./models/circuit');
|
||||
|
||||
const printf = require('util').format;
|
||||
|
||||
myLoad().then(ris => {
|
||||
|
||||
const { User } = require('./models/user');
|
||||
|
||||
require('./models/todo');
|
||||
require('./models/project');
|
||||
require('./models/subscribers');
|
||||
require('./models/booking');
|
||||
require('./models/sendmsg');
|
||||
require('./models/sendnotif');
|
||||
require('./models/mailinglist');
|
||||
require('./models/newstosent');
|
||||
require('./models/mypage');
|
||||
require('./models/myelem');
|
||||
require('./models/bot');
|
||||
require('./models/calzoom');
|
||||
const mysql_func = require('./mysql/mysql_func');
|
||||
|
||||
const index_router = require('./router/index_router');
|
||||
const push_router = require('./router/push_router');
|
||||
const newsletter_router = require('./router/newsletter_router');
|
||||
const booking_router = require('./router/booking_router');
|
||||
const dashboard_router = require('./router/dashboard_router');
|
||||
const myevent_router = require('./router/myevent_router');
|
||||
const subscribe_router = require('./router/subscribe_router');
|
||||
const sendmsg_router = require('./router/sendmsg_router');
|
||||
const sendnotif_router = require('./router/sendnotif_router');
|
||||
const email_router = require('./router/email_router');
|
||||
const todos_router = require('./router/todos_router');
|
||||
const test_router = require('./router/test_router');
|
||||
const projects_router = require('./router/projects_router');
|
||||
const report_router = require('./router/report_router');
|
||||
const users_router = require('./router/users_router');
|
||||
const reactions_router = require('./router/reactions_router');
|
||||
const mygroups_router = require('./router/mygroups_router');
|
||||
const circuits_router = require('./router/circuits_router');
|
||||
const accounts_router = require('./router/accounts_router');
|
||||
const iscrittiConacreis_router = require('./router/iscrittiConacreis_router');
|
||||
const iscrittiArcadei_router = require('./router/iscrittiArcadei_router');
|
||||
const site_router = require('./router/site_router');
|
||||
const admin_router = require('./router/admin_router');
|
||||
const products_router = require('./router/products_router');
|
||||
const cart_router = require('./router/cart_router');
|
||||
const orders_router = require('./router/orders_router');
|
||||
const city_router = require('./router/city_router');
|
||||
const myskills_router = require('./router/myskills_router');
|
||||
const mygoods_router = require('./router/mygoods_router');
|
||||
const mygen_router = require('./router/mygen_router');
|
||||
const aitools_router = require('./router/aitools_router');
|
||||
|
||||
const { MyEvent } = require('./models/myevent');
|
||||
|
||||
app.use(bodyParser.json({ limit: '50mb' }));
|
||||
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
|
||||
|
||||
app.use(express.static('views'));
|
||||
|
||||
// app.use(express.static(path.join(__dirname, 'client')));
|
||||
|
||||
app.use(bodyParser.json());
|
||||
|
||||
// app.set('view engine', 'pug');
|
||||
|
||||
// Set static folder
|
||||
// app.use(express.static(path.join(__dirname, 'public')));
|
||||
|
||||
i18n.configure({
|
||||
locales: ['it', 'enUs', 'es', 'fr', 'pt', 'si'],
|
||||
defaultLocale: 'it',
|
||||
// cookie: 'cook',
|
||||
directory: __dirname + '/locales',
|
||||
api: {
|
||||
'__': 'translate',
|
||||
'__n': 'translateN'
|
||||
},
|
||||
});
|
||||
|
||||
app.use(cors({
|
||||
exposedHeaders: ['x-auth', 'x-refrtok'],
|
||||
}));
|
||||
|
||||
app.use(bodyParser.json());
|
||||
|
||||
// app.use(express.cookieParser());
|
||||
app.use(i18n.init);
|
||||
|
||||
console.log('Use Routes \...');
|
||||
|
||||
|
||||
// Use Routes
|
||||
app.use('/', index_router);
|
||||
app.use('/subscribe', subscribe_router);
|
||||
app.use('/sendmsg', sendmsg_router);
|
||||
app.use('/sendnotif', sendnotif_router);
|
||||
app.use('/push', push_router);
|
||||
app.use('/news', newsletter_router);
|
||||
app.use('/booking', booking_router);
|
||||
app.use('/dashboard', dashboard_router);
|
||||
app.use('/event', myevent_router);
|
||||
app.use('/email', email_router);
|
||||
app.use('/todos', todos_router);
|
||||
app.use('/test', test_router);
|
||||
app.use('/projects', projects_router);
|
||||
app.use('/users', users_router);
|
||||
app.use('/reactions', reactions_router);
|
||||
app.use('/mygroup', mygroups_router);
|
||||
app.use('/circuit', circuits_router);
|
||||
app.use('/account', accounts_router);
|
||||
app.use('/iscritti_conacreis', iscrittiConacreis_router);
|
||||
app.use('/iscritti_arcadei', iscrittiArcadei_router);
|
||||
app.use('/report', report_router);
|
||||
app.use('/site', site_router);
|
||||
app.use('/admin', admin_router);
|
||||
app.use('/products', products_router);
|
||||
app.use('/cart', cart_router);
|
||||
app.use('/orders', orders_router);
|
||||
app.use('/city', city_router);
|
||||
app.use('/myskills', myskills_router);
|
||||
app.use('/mygoods', mygoods_router);
|
||||
app.use('/mygen', mygen_router);
|
||||
app.use('/aitools', aitools_router);
|
||||
|
||||
// catch 404 and forward to error handler
|
||||
// app.use(function (req, res, next) {
|
||||
// var err = new Error('Not Found');
|
||||
// err.status = 404;
|
||||
// next(err);
|
||||
// });
|
||||
|
||||
// app.set('views', path.join(__dirname, 'views'));
|
||||
// app.set('view engine', 'pug');
|
||||
|
||||
// development error handler
|
||||
// will print stacktrace
|
||||
if (app.get('env') === 'development') {
|
||||
|
||||
app.use(function (err, req, res, next) {
|
||||
console.log('Server Error: ', err.message);
|
||||
// console.trace();
|
||||
res.status(err.status || 500).send({ error: err.message });
|
||||
// res.render('error', {
|
||||
// message: err.message,
|
||||
// error: err
|
||||
// });
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// require('./telegram/telegrambot');
|
||||
|
||||
// *** DB CONNECTIONS ***
|
||||
// mysql_func.mySqlConn_Shen.connect((err) => {
|
||||
// if (!err)
|
||||
// console.log('DB connection to Shen Database succeded.');
|
||||
// else
|
||||
// console.log('DB connection to Shen Database FAILED \n Error: ' + JSON.stringify(err, undefined, 2));
|
||||
// });
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
console.log('*** PRODUCTION! ');
|
||||
}
|
||||
|
||||
if ((process.env.NODE_ENV === 'production') ||
|
||||
(process.env.NODE_ENV === 'test')) {
|
||||
|
||||
const keyStream = path.resolve(`./${process.env.PATH_CERT_KEY}`);
|
||||
const certificateStream = path.resolve(`./${process.env.PATH_SERVER_CRT}`);
|
||||
|
||||
let privateKey = fs.readFileSync(keyStream, "utf8");
|
||||
let certificate = fs.readFileSync(certificateStream, "utf8");
|
||||
|
||||
let credentials = null;
|
||||
|
||||
|
||||
// arrSecureContext = ['piuchebuono.app', 'gruppomacro.app'];
|
||||
arrSecureContext = ['freeplanet.app', 'riso.app', 'comunitanuovomondo.app'];
|
||||
|
||||
let secureContext = {};
|
||||
|
||||
for (let i = 0; i < arrSecureContext.length; i++) {
|
||||
try {
|
||||
secureContext = {
|
||||
...secureContext,
|
||||
[arrSecureContext[i]]: tls.createSecureContext({
|
||||
key: fs.readFileSync('/etc/letsencrypt/live/' + arrSecureContext[i] + '/privkey.pem'),
|
||||
cert: fs.readFileSync('/etc/letsencrypt/live/' + arrSecureContext[i] + '/fullchain.pem')
|
||||
// ca: fs.readFileSync('../path_to_certificate_authority_bundle.ca-bundle1', 'utf8'), // this ca property is optional
|
||||
})
|
||||
}
|
||||
|
||||
credentials = {
|
||||
SNICallback: function (domain, cb) {
|
||||
if (secureContext) {
|
||||
if (cb) {
|
||||
cb(null, secureContext);
|
||||
} else {
|
||||
// compatibility for older versions of node
|
||||
return secureContext;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('Error: ' + err);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
let secureContext = {
|
||||
'piuchebuono.app': tls.createSecureContext({
|
||||
key: fs.readFileSync('/etc/letsencrypt/live/piuchebuono.app/privkey.pem'),
|
||||
cert: fs.readFileSync('/etc/letsencrypt/live/piuchebuono.app/fullchain.pem')
|
||||
// ca: fs.readFileSync('../path_to_certificate_authority_bundle.ca-bundle1', 'utf8'), // this ca property is optional
|
||||
}),
|
||||
'gruppomacro.app': tls.createSecureContext({
|
||||
key: fs.readFileSync('/etc/letsencrypt/live/gruppomacro.app/privkey.pem'),
|
||||
cert: fs.readFileSync('/etc/letsencrypt/live/gruppomacro.app/fullchain.pem')
|
||||
// ca: fs.readFileSync('../path_to_certificate_authority_bundle.ca-bundle1', 'utf8'), // this ca property is optional
|
||||
}),
|
||||
}*/
|
||||
|
||||
console.log('secureContext', secureContext);
|
||||
|
||||
if (NUOVO_METODO_TEST) {
|
||||
credentials = {
|
||||
SNICallback: function (domain, cb) {
|
||||
if (secureContext[domain]) {
|
||||
if (cb) {
|
||||
cb(null, secureContext[domain]);
|
||||
} else {
|
||||
// compatibility for older versions of node
|
||||
return secureContext[domain];
|
||||
}
|
||||
} else {
|
||||
throw new Error('No keys/certificates for domain requested');
|
||||
}
|
||||
},
|
||||
// must list a default key and cert because required by tls.createServer()
|
||||
key: privateKey,
|
||||
cert: certificate,
|
||||
}
|
||||
|
||||
/*} else {
|
||||
// NON USATO !
|
||||
credentials = {
|
||||
key: privateKey,
|
||||
cert: certificate,
|
||||
ca: [
|
||||
fs.readFileSync(process.env.PATH_SSL_ROOT_PEM, 'utf8'),
|
||||
fs.readFileSync(process.env.PATH_SSL_CHAIN_PEM, 'utf8'),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
/*} else {
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if (process.env.HTTPS_LOCALHOST === "true") {
|
||||
privateKey = fs.readFileSync(process.env.PATH_CERT_KEY, 'utf8');
|
||||
certificate = fs.readFileSync(process.env.PATH_SERVER_CRT, 'utf8');
|
||||
credentials = {
|
||||
key: privateKey,
|
||||
cert: certificate,
|
||||
ciphers: 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES256-SHA384',
|
||||
honorCipherOrder: true,
|
||||
secureProtocol: 'TLSv1_2_method',
|
||||
};
|
||||
|
||||
} else {
|
||||
var http = require('http');
|
||||
}
|
||||
|
||||
if ((process.env.NODE_ENV === 'production') ||
|
||||
(process.env.NODE_ENV === 'test') || process.env.HTTPS_LOCALHOST === "true") {
|
||||
|
||||
const httpsServer = https.createServer(credentials, app);
|
||||
|
||||
console.log('httpsServer: port ', port);
|
||||
httpsServer.listen(port);
|
||||
} else {
|
||||
console.log('httpServer: port ', port);
|
||||
const httpServer = http.createServer(app);
|
||||
httpServer.listen(port);
|
||||
}
|
||||
|
||||
mystart();
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
// app.use(throttle(1024 * 128)); // throttling bandwidth
|
||||
|
||||
// app.use((req, res, next) => {
|
||||
// res.header('Access-Control-Allow-Origin', '*')
|
||||
// res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept')
|
||||
// next()
|
||||
// });
|
||||
|
||||
async function myLoad() {
|
||||
|
||||
return tools.loadApps();
|
||||
}
|
||||
|
||||
async function mystart() {
|
||||
|
||||
// await estraiTutteLeImmagini();
|
||||
|
||||
await tools.getApps();
|
||||
|
||||
if (process.env.PROD !== 1) {
|
||||
|
||||
testmsgwebpush();
|
||||
|
||||
// tools.sendNotifToAdmin('Riparti', 'Riparti');
|
||||
|
||||
let miapass = '';
|
||||
|
||||
if (miapass !== '') {
|
||||
let crypt = tools.cryptdata(miapass);
|
||||
let decrypt = tools.decryptdata(crypt);
|
||||
|
||||
console.log('crypted:', crypt);
|
||||
console.log('decrypted:', decrypt);
|
||||
}
|
||||
|
||||
mycron();
|
||||
if (!process.env.VITE_DEBUG) {
|
||||
mycron();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
telegrambot = require('./telegram/telegrambot');
|
||||
|
||||
await inizia();
|
||||
|
||||
await resetProcessingJob();
|
||||
|
||||
populate.popolaTabelleNuove();
|
||||
|
||||
faitest();
|
||||
|
||||
// ----------------- MAILCHIMP -----
|
||||
const querystring = require('querystring');
|
||||
const mailchimpClientId = 'xxxxxxxxxxxxxxxx';
|
||||
|
||||
app.get('/mailchimp/auth/authorize', function (req, res) {
|
||||
res.redirect('https://login.mailchimp.com/oauth2/authorize?' +
|
||||
querystring.stringify({
|
||||
'response_type': 'code',
|
||||
'client_id': mailchimpClientId,
|
||||
'redirect_uri': 'http://127.0.0.1:3000/mailchimp/auth/callback',
|
||||
}));
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// -----------------
|
||||
|
||||
function populateDBadmin() {
|
||||
const cfgserv = [
|
||||
{
|
||||
_id: new ObjectId(),
|
||||
idapp: '9',
|
||||
chiave: 'vers',
|
||||
userId: 'ALL',
|
||||
valore: '0.1.2',
|
||||
}];
|
||||
|
||||
let cfg = new CfgServer(cfgserv[0]).save();
|
||||
}
|
||||
|
||||
async function mycron() {
|
||||
|
||||
try {
|
||||
const sendemail = require('./sendemail');
|
||||
|
||||
const arr = await tools.getApps();
|
||||
|
||||
for (const app of arr) {
|
||||
sendemail.checkifPendingNewsletter(app.idapp);
|
||||
sendemail.checkifSentNewsletter(app.idapp);
|
||||
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Err mycron', e);
|
||||
}
|
||||
}
|
||||
|
||||
async function mycron_30min() {
|
||||
for (const app of await tools.getApps()) {
|
||||
let enablecrontab = false;
|
||||
|
||||
enablecrontab = await Settings.getValDbSettings(app.idapp,
|
||||
tools.ENABLE_CRONTAB, false);
|
||||
|
||||
if (enablecrontab) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function mycron_everyday() {
|
||||
try {
|
||||
|
||||
const { User } = require('./models/user');
|
||||
|
||||
const arrapps = await tools.getApps();
|
||||
for (const app of arrapps) {
|
||||
|
||||
// Azzera le richieste di password:
|
||||
const usersblocked = await User.find({ idapp: app.idapp, retry_pwd: { $exists: true, $gte: 29 } }).lean();
|
||||
for (const user of usersblocked) {
|
||||
await User.findOneAndUpdate({ _id: user._id }, { $set: { retry_pwd: 20 } });
|
||||
let text = `⚠️⚠️⚠️ L\'utente ${user.username} (${user.name} ${user.surname}) viene sbloccato dal numero massimo di tentativi di richiesta password!\nTelerlo d\'occhio !\n@${user.profile.username_telegram}`;
|
||||
await telegrambot.sendMsgTelegramToTheAdminAllSites(text, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Crea un file con all'interno il nome del dominio per ogni app:
|
||||
await tools.createFileWithDomainName();
|
||||
|
||||
} catch (e) {
|
||||
console.error('mycron_everyday: ', e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function testmsgwebpush() {
|
||||
const { User } = require('./models/user');
|
||||
|
||||
// console.log('nomeapp 1: ' , tools.getNomeAppByIdApp(1));
|
||||
// console.log('nomeapp 2: ' , tools.getNomeAppByIdApp(2));
|
||||
|
||||
User.find({ username: 'paoloar77', idapp: '1' }).then(async (arrusers) => {
|
||||
if (arrusers !== null) {
|
||||
for (const user of arrusers) {
|
||||
await tools.sendNotificationToUser(user._id, 'Server',
|
||||
'Il Server è Ripartito', '/', '', 'server', []).then(ris => {
|
||||
if (ris) {
|
||||
|
||||
} else {
|
||||
// already sent the error on calling sendNotificationToUser
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// Cron every X minutes
|
||||
cron.schedule('*/1 * * * *', () => {
|
||||
// console.log('Running Cron Job');
|
||||
// if (!process.env.VITE_DEBUG) {
|
||||
mycron();
|
||||
// }
|
||||
});
|
||||
|
||||
// Cron every X minutes
|
||||
cron.schedule('*/60 * * * *', async () => {
|
||||
if (!process.env.VITE_DEBUG) {
|
||||
mycron_30min();
|
||||
}
|
||||
});
|
||||
|
||||
// Cron every 21:00 (1 volta al giorno)
|
||||
cron.schedule('0 21 * * *', async () => {
|
||||
mycron_everyday();
|
||||
});
|
||||
|
||||
// mycron_30min();
|
||||
|
||||
// tools.writelogfile('test', 'prova.txt');
|
||||
|
||||
async function resetProcessingJob() {
|
||||
|
||||
const { Newstosent } = require('./models/newstosent');
|
||||
|
||||
arrrec = await Newstosent.find({});
|
||||
|
||||
for (const rec of arrrec) {
|
||||
rec.processing_job = false;
|
||||
await Newstosent.findOneAndUpdate({ _id: rec.id }, { $set: rec }, { new: false }).
|
||||
then((item) => {
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//app.listen(port, () => {
|
||||
// console.log(`Server started at port ${port}`);
|
||||
//});
|
||||
|
||||
async function inizia() {
|
||||
|
||||
try {
|
||||
if (true) {
|
||||
const url = 'https://raw.githubusercontent.com/matteocontrini/comuni-json/master/comuni.json';
|
||||
const outputPath = './comuni_italia_geojson.json';
|
||||
downloadGeoJSON(url, outputPath);
|
||||
}
|
||||
|
||||
mycron_everyday();
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
await telegrambot.sendMsgTelegram(tools.FREEPLANET,
|
||||
shared_consts.ADMIN_USER_SERVER,
|
||||
`Ciao ${telegrambot.ADMIN_USER_NAME_SERVER}!`);
|
||||
|
||||
await telegrambot.sendMsgTelegramByIdTelegram(tools.FREEPLANET,
|
||||
telegrambot.ADMIN_IDTELEGRAM_SERVER,
|
||||
`Ciao ${telegrambot.ADMIN_USER_NAME_SERVER}\n` +
|
||||
`🔅 Il Server ${process.env.DATABASE} è appena ripartito!`);
|
||||
|
||||
} else {
|
||||
|
||||
await telegrambot.sendMsgTelegramToTheAdminAllSites(`Ciao Admin\n` + `🔅🔅🔅 Il Server col BOT di {appname} è appena ripartito!`, false);
|
||||
|
||||
}
|
||||
|
||||
await Site.createFirstUserAdmin();
|
||||
|
||||
/*const {Circuit} = require('./models/circuit');
|
||||
|
||||
await Circuit.setDeperimentoOff();
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
// telegrambot.sendMsgTelegramToTheManagers('7', 'PROVAAA!');
|
||||
|
||||
// if (process.env.PROD !== 1) {
|
||||
// const reg = require('./reg/registration');
|
||||
// const link = reg.getlinkregByEmail('7', 'tomasihelen@dasdasgmail.comAAAA' , 'HelenTomasidasdasd');
|
||||
// const link2 = reg.getlinkregByEmail('7', 'tomasihelen@gmail.com' , 'HelenTomasi');
|
||||
// //const link2 = reg.getlinkregByEmail('7', 'elenaliubicich@gmail.com' , 'Elenaliu');
|
||||
//
|
||||
// console.log(link);
|
||||
// console.log(link2);
|
||||
// }
|
||||
|
||||
async function estraiImmagini(table) {
|
||||
const { User } = require('./models/user');
|
||||
|
||||
let idapp = '13';
|
||||
|
||||
let arrlist;
|
||||
|
||||
const globalTables = require('./tools/globalTables');
|
||||
|
||||
|
||||
const mytable = globalTables.getTableByTableName(table);
|
||||
if (!mytable)
|
||||
return;
|
||||
|
||||
console.log('INIZIO - estraiImmagini', table);
|
||||
|
||||
arrlist = await mytable.find({ idapp }).lean();
|
||||
|
||||
let file = '';
|
||||
let filetocheck = '';
|
||||
let dirmain = '';
|
||||
let filefrom = '';
|
||||
let filefrom2 = '';
|
||||
let dir = tools.getdirByIdApp(idapp) + dirmain + '/upload/';
|
||||
|
||||
try {
|
||||
if (!tools.sulServer()) {
|
||||
dirmain = '/public';
|
||||
}
|
||||
|
||||
for (const rec of arrlist) {
|
||||
const myuser = await User.findOne({ idapp, _id: rec.userId }).lean();
|
||||
if (myuser) {
|
||||
const myphotos = rec.photos;
|
||||
|
||||
if (myphotos.length > 0) {
|
||||
let folderprof = dir + 'profile/' + myuser.username;
|
||||
|
||||
try {
|
||||
// console.log('checkdir', folderprof);
|
||||
if (!fs.existsSync(folderprof)) {
|
||||
console.log('*** Creadir', folderprof);
|
||||
fs.mkdirSync(folderprof);
|
||||
}
|
||||
|
||||
folderprof = dir + 'profile/' + myuser.username + '/' + table;
|
||||
// console.log('checkdir', folderprof);
|
||||
if (!fs.existsSync(folderprof)) {
|
||||
console.log('creadir', folderprof);
|
||||
fs.mkdirSync(folderprof);
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for (const photo of myphotos) {
|
||||
|
||||
if (photo.imagefile) {
|
||||
file = dir + 'profile/' + myuser.username + '/' + table + '/' +
|
||||
photo.imagefile;
|
||||
filefrom = dir + 'profile/undefined/' + table + '/' + photo.imagefile;
|
||||
filefrom2 = dir + 'profile/' + myuser.username + '/' + photo.imagefile;
|
||||
|
||||
// console.log('file', file);
|
||||
// console.log('filefrom', filefrom);
|
||||
|
||||
if (!tools.isFileExists(file)) {
|
||||
// non esiste
|
||||
console.log('non esiste', file);
|
||||
console.log(' filefrom', filefrom);
|
||||
console.log(' filefrom2', filefrom2);
|
||||
}
|
||||
|
||||
if (!tools.isFileExists(file) && tools.isFileExists(filefrom)) {
|
||||
console.log('@@@@@@ copia file:', filefrom, 'a', file);
|
||||
tools.copy(filefrom, file);
|
||||
}
|
||||
if (!tools.isFileExists(file) && tools.isFileExists(filefrom2)) {
|
||||
console.log('@@@@@@ copia file 2:', filefrom2, 'a', file);
|
||||
tools.copy(filefrom2, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log('FINE - estraiImmagini', table);
|
||||
} catch (e) {
|
||||
console.error('e', e);
|
||||
}
|
||||
}
|
||||
|
||||
async function estraiTutteLeImmagini() {
|
||||
|
||||
await estraiImmagini('myskills');
|
||||
await estraiImmagini('mygoods');
|
||||
await estraiImmagini('mybachecas');
|
||||
}
|
||||
|
||||
async function faitest() {
|
||||
// console.log('Fai Test:')
|
||||
|
||||
const testfind = false;
|
||||
|
||||
// const $vers = tools.getVersionint('1.92.45');
|
||||
|
||||
if (true) {
|
||||
// tools.execScript("ls -la");
|
||||
}
|
||||
|
||||
if (false) {
|
||||
prova = tools.removeAtChar('@prova');
|
||||
}
|
||||
|
||||
if (false) {
|
||||
const prova = tools.getConfSiteOptionEnabledByIdApp('13', shared_consts.ConfSite.Notif_Reg_Push_Admin);
|
||||
console.log('prova', prova);
|
||||
}
|
||||
|
||||
if (testfind) {
|
||||
const { City } = require('./models/city');
|
||||
|
||||
let miacity = 'roma';
|
||||
const ris = await City.findByCity(miacity);
|
||||
|
||||
console.log('ris', ris);
|
||||
}
|
||||
|
||||
const { User } = require('./models/user');
|
||||
|
||||
if (false) {
|
||||
let myuser = await User.findOne({
|
||||
idapp: '1',
|
||||
username: 'paoloar77',
|
||||
});
|
||||
const langdest = 'it';
|
||||
|
||||
telegrambot.askConfirmationUser(myuser.idapp, shared_consts.CallFunz.REGISTRATION, myuser);
|
||||
|
||||
}
|
||||
|
||||
if (false) {
|
||||
|
||||
const user = await User.findOne({
|
||||
idapp: 12,
|
||||
username: 'paolotest1',
|
||||
});
|
||||
|
||||
await sendemail.sendEmail_Registration('it', 'paolo@arcodiluce.it', user,
|
||||
'12', '');
|
||||
|
||||
}
|
||||
|
||||
if (false) {
|
||||
|
||||
const { User } = require('./models/user');
|
||||
|
||||
const idapp = tools.FREEPLANET;
|
||||
const idreg = 0;
|
||||
|
||||
try {
|
||||
|
||||
const user = await User.findOne({
|
||||
idapp,
|
||||
username: 'paoloar773',
|
||||
});
|
||||
|
||||
user.aportador_solidario = 'paoloar77';
|
||||
|
||||
let mylocalsconf = {
|
||||
idapp,
|
||||
dataemail: null,
|
||||
locale: user.lang,
|
||||
nomeapp: tools.getNomeAppByIdApp(idapp),
|
||||
strlinksito: tools.getHostByIdApp(idapp),
|
||||
strlinkreg: '',
|
||||
username: user.username,
|
||||
name: user.name,
|
||||
surname: user.surname,
|
||||
forgetpwd: tools.getHostByIdApp(idapp) + '/requestresetpwd',
|
||||
emailto: '',
|
||||
user,
|
||||
};
|
||||
|
||||
await telegrambot.notifyToTelegram(telegrambot.phase.REGISTRATION,
|
||||
mylocalsconf);
|
||||
} catch (e) {
|
||||
console.log('error ' + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { app };
|
||||
|
||||
@@ -1 +1,12 @@
|
||||
<div class="row align-start" style="gap:0px;flex-direction:column;flex:1;display:flex;justify-content:space-between;"><!-- Parte superiore --><div class="justify-start" style="flex-grow:0"><span style="font-size:calc(12 * var(--scalecatalog) * 1px)" class="book-author">{autore}</span><div style="font-size:calc(16 * var(--scalecatalog) * 1px);font-weight:bold;" class="book-title">{titolo}</div><span class="book-descr">{descrizione}</span></div><!-- Parte inferiore (book-details e barcode) --><div style="margin-top:auto;width:100%"><div class="justify-end book-details" style="flex-grow:0;font-size:calc(10 * var(--scalecatalog) * 1px);">Pagine: <b>{pagine}</b><br />Formato: <b>{misure}</b><br />Prezzo: <b>{prezzo} €</b><br /></div></div></div>
|
||||
<div class="row align-start" style="gap:0px;flex-direction:column;flex:1;display:flex;justify-content:space-between;">
|
||||
<!-- Parte superiore -->
|
||||
<div class="justify-start" style="flex-grow:0"><span style="font-size:calc(12 * var(--scalecatalogx) * 1px)"
|
||||
class="book-author">{autore}</span>
|
||||
<div style="font-size:calc(16 * var(--scalecatalogx) * 1px);font-weight:bold;" class="book-title">{titolo}</div>
|
||||
<span class="book-descr">{descrizione}</span>
|
||||
</div><!-- Parte inferiore (book-details e barcode) -->
|
||||
<div style="margin-top:auto;width:100%">
|
||||
<div class="justify-end book-details" style="flex-grow:0;font-size:calc(10 * var(--scalecatalog) * 1px);">
|
||||
Pagine: <b>{pagine}</b><br />Formato: <b>{misure}</b><br />Prezzo: <b>{prezzo} €</b><br /></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2,7 +2,7 @@ module.exports = {
|
||||
apps : [
|
||||
{
|
||||
name: "FreePlanetServerSide",
|
||||
script: "./src/server/server.js",
|
||||
script: "./src/server.js",
|
||||
ignore_watch : ["node_modules"],
|
||||
watch: false,
|
||||
//autorestart: true,
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
module.exports = {
|
||||
apps: [
|
||||
{
|
||||
name: "PiuCheBuono",
|
||||
script: "/var/www/nodejs_piuchebuono_server/src/server/server.js",
|
||||
name: "PCB-PROD",
|
||||
script: "/var/www/nodejs_piuchebuono_server/src/server.js",
|
||||
ignore_watch: ["node_modules", "logs"],
|
||||
//autorestart: true,
|
||||
// interpreter: "/root/.nvm/versions/node/v22.13.1/bin/node",
|
||||
//autorestart: true,
|
||||
instances: 1,
|
||||
watch: false,
|
||||
env: {
|
||||
@@ -1,11 +1,10 @@
|
||||
module.exports = {
|
||||
apps: [
|
||||
{
|
||||
name: "PiuCheBuono (TEST)",
|
||||
script: "/var/www/nodejs_test.piuchebuono_server/src/server/server.js",
|
||||
name: "PCB-TEST",
|
||||
script: "/var/www/nodejs_test.piuchebuono_server/src/server.js",
|
||||
ignore_watch: ["node_modules", "logs"],
|
||||
interpreter: "/root/.nvm/versions/node/v22.13.1/bin/node",
|
||||
//autorestart: true,
|
||||
// interpreter: "/root/.nvm/versions/node/v22.13.1/bin/node",
|
||||
instances: 1,
|
||||
watch: false,
|
||||
env: {
|
||||
@@ -2,9 +2,9 @@ module.exports = {
|
||||
apps: [
|
||||
{
|
||||
name: "PRODUZIONE - FREEPLANET",
|
||||
script: "/var/www/www.freeplanet_server/src/server/server.js",
|
||||
script: "/var/www/www.freeplanet_server/src/server.js",
|
||||
ignore_watch: ["node_modules", "logs"],
|
||||
interpreter: "/root/.nvm/versions/node/v16.19.0/bin/node",
|
||||
// interpreter: "/root/.nvm/versions/node/v16.19.0/bin/node",
|
||||
//autorestart: true,
|
||||
instances: 1,
|
||||
watch: false,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
module.exports = {
|
||||
apps: [
|
||||
{
|
||||
name: "RISO",
|
||||
script: "/var/www/nodejs_riso_server/src/server/server.js",
|
||||
name: "RISO-PROD",
|
||||
script: "/var/www/nodejs_riso_server/src/server.js",
|
||||
ignore_watch: ["node_modules", "logs"],
|
||||
interpreter: "/root/.nvm/versions/node/v22.13.1/bin/node",
|
||||
// interpreter: "/root/.nvm/versions/node/v22.13.1/bin/node",
|
||||
//autorestart: true,
|
||||
instances: 1,
|
||||
watch: false,
|
||||
@@ -1,12 +1,11 @@
|
||||
module.exports = {
|
||||
apps: [
|
||||
{
|
||||
name: "RISO (TEST)",
|
||||
script: "./src/server/server.js",
|
||||
name: "RISO-TEST",
|
||||
script: "./src/server.js",
|
||||
ignore_watch: ["node_modules", "logs"],
|
||||
interpreter: "/root/.nvm/versions/node/v22.13.1/bin/node",
|
||||
// interpreter: "/root/.nvm/versions/node/v22.13.1/bin/node",
|
||||
watch: false,
|
||||
//autorestart: true,
|
||||
instances: 1,
|
||||
env_test: {
|
||||
"PORT": 3001,
|
||||
BIN
emails/.DS_Store
vendored
BIN
emails/.DS_Store
vendored
Binary file not shown.
492
emails/RISO/circuit_abilitato_al_fido_membro/it/html.pug
Executable file
492
emails/RISO/circuit_abilitato_al_fido_membro/it/html.pug
Executable file
@@ -0,0 +1,492 @@
|
||||
doctype html
|
||||
html(lang="it")
|
||||
head
|
||||
meta(charset="UTF-8")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1.0")
|
||||
style(type="text/css").
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.header-logo {
|
||||
width: 120px;
|
||||
height: auto;
|
||||
margin-bottom: 16px;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.email-container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
background: linear-gradient(135deg, #7cb342 0%, #558b2f 100%);
|
||||
color: white;
|
||||
padding: 40px 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
margin: 0 0 8px 0;
|
||||
font-size: 26px;
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.email-header .subtitle {
|
||||
margin: 8px 0 0 0;
|
||||
font-size: 17px;
|
||||
opacity: 0.95;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 32px 24px;
|
||||
}
|
||||
|
||||
.intro-text {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.congrats-card {
|
||||
background: linear-gradient(135deg, #e8f5e9 0%, #f1f8f4 100%);
|
||||
border: 2px solid #7cb342;
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.congrats-card .congrats-icon {
|
||||
font-size: 48px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.congrats-card h3 {
|
||||
font-size: 22px;
|
||||
color: #558b2f;
|
||||
margin-bottom: 12px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.congrats-card .territory-name {
|
||||
font-size: 20px;
|
||||
color: #7cb342;
|
||||
font-weight: 600;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.info-section {
|
||||
background: #ffffff;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 24px 0;
|
||||
}
|
||||
|
||||
.info-section h3 {
|
||||
font-size: 18px;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 16px;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.info-section p {
|
||||
font-size: 15px;
|
||||
color: #555;
|
||||
line-height: 1.7;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.info-section ul {
|
||||
margin: 12px 0;
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
.info-section li {
|
||||
font-size: 15px;
|
||||
color: #555;
|
||||
line-height: 1.7;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.highlight-box {
|
||||
background: linear-gradient(135deg, #fff8dc 0%, #fef9f3 100%);
|
||||
border-left: 4px solid #f0ad4e;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.highlight-box h4 {
|
||||
font-size: 17px;
|
||||
color: #f0ad4e;
|
||||
margin-bottom: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.highlight-box p {
|
||||
font-size: 15px;
|
||||
color: #555;
|
||||
line-height: 1.7;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.example-box {
|
||||
background: #e3f2fd;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.example-box h4 {
|
||||
font-size: 16px;
|
||||
color: #1976d2;
|
||||
margin-bottom: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.example-box .transaction {
|
||||
background: white;
|
||||
border-radius: 6px;
|
||||
padding: 12px;
|
||||
margin: 8px 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.example-box .benefit {
|
||||
background: #c8e6c9;
|
||||
border-radius: 6px;
|
||||
padding: 12px;
|
||||
margin-top: 12px;
|
||||
font-size: 14px;
|
||||
color: #2e7d32;
|
||||
}
|
||||
|
||||
.steps-box {
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.steps-box h4 {
|
||||
font-size: 17px;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 16px;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.step-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 16px;
|
||||
padding: 12px;
|
||||
background: white;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.step-number {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: #7cb342;
|
||||
min-width: 40px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.step-content h5 {
|
||||
font-size: 16px;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 6px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.step-content p {
|
||||
font-size: 14px;
|
||||
color: #555;
|
||||
line-height: 1.6;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.cta-section {
|
||||
text-align: center;
|
||||
margin: 32px 0;
|
||||
padding: 24px 0;
|
||||
border-top: 2px solid #e0e0e0;
|
||||
border-bottom: 2px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.cta-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
display: inline-block;
|
||||
padding: 18px 56px;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: white;
|
||||
background: linear-gradient(135deg, #7cb342 0%, #558b2f 100%);
|
||||
border-radius: 50px;
|
||||
text-decoration: none;
|
||||
box-shadow: 0 6px 20px rgba(124, 179, 66, 0.4);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.button-icon {
|
||||
font-size: 20px;
|
||||
margin-right: 10px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.community-box {
|
||||
background: linear-gradient(135deg, #e8f5e9 0%, #f1f8f4 100%);
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.community-box h4 {
|
||||
font-size: 17px;
|
||||
color: #558b2f;
|
||||
margin-bottom: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.community-box p {
|
||||
font-size: 15px;
|
||||
color: #555;
|
||||
line-height: 1.7;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.community-box a {
|
||||
color: #2196f3;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.email-footer {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
background: #f8f9fa;
|
||||
color: #777;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.email-footer p {
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
background: linear-gradient(to right, transparent, #e0e0e0, transparent);
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
body {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.congrats-card .congrats-icon {
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
.congrats-card h3 {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
padding: 16px 40px;
|
||||
font-size: 18px;
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.step-item {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.step-number {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
body
|
||||
.email-container
|
||||
//- Header
|
||||
.email-header
|
||||
img.header-logo(src=baseurl+'/images/logo.png' alt=nomeapp)
|
||||
h1 🎉 Benvenuto nel #{nomeTerritorio}!
|
||||
p.subtitle Sei stato abilitato con successo
|
||||
|
||||
//- Body
|
||||
.email-body
|
||||
//- Intro
|
||||
.intro-text
|
||||
| Ciao <strong>#{usernameMembro}</strong>,<br>
|
||||
| complimenti! Sei stato abilitato #{nomeTerritorio} da #{usernameInvitante}.
|
||||
|
||||
if linkProfiloAdmin
|
||||
.divider(style="margin: 16px 0;")
|
||||
p(style="text-align: center; margin: 16px 0;")
|
||||
a.profile-button(href=linkProfiloAdmin target="_blank" style="display: inline-block; padding: 10px 24px; font-size: 15px; font-weight: 600; color: #7cb342; background: white; border: 2px solid #7cb342; border-radius: 20px; text-decoration: none; transition: all 0.3s ease;")
|
||||
span(style="margin-right: 6px;") 👤
|
||||
| Profilo #{usernameInvitante}
|
||||
|
||||
//- Congratulazioni
|
||||
.congrats-card
|
||||
.congrats-icon ✅
|
||||
h3 Abilitazione Completata
|
||||
p(style="font-size: 15px; color: #555; margin-top: 8px;")
|
||||
| Ora puoi utilizzare i #{symbol} per i tuoi scambi nella comunità
|
||||
.territory-name 📍 #{nomeTerritorio}
|
||||
|
||||
//- Info comunità
|
||||
.community-box
|
||||
h4 💬 Unisciti alla Comunità Territoriale
|
||||
p
|
||||
| Entra nel gruppo Telegram di <strong>#{nomeTerritorio}</strong> per interagire con i partecipanti, rimanere aggiornato su eventi, mercatini e opportunità di scambio nella tua zona, e per poter inserire, anche tu, annunci di offro/cerco.
|
||||
|
||||
if linkTelegramTerritorio
|
||||
a.telegram-button(href=linkTelegramTerritorio target="_blank" style="display: inline-block; margin-top: 16px; padding: 14px 32px; font-size: 17px; font-weight: 600; color: white; background: linear-gradient(135deg, #0088cc 0%, #006699 100%); border-radius: 25px; text-decoration: none; box-shadow: 0 4px 12px rgba(0, 136, 204, 0.3); transition: all 0.3s ease;")
|
||||
span(style="font-size: 20px; margin-right: 8px; vertical-align: middle;") ✈️
|
||||
| Unisciti al gruppo Telegram
|
||||
|
||||
//- Cos'è RIS
|
||||
.info-section
|
||||
h3
|
||||
span 💰
|
||||
| Cosa sono i RIS?
|
||||
p
|
||||
| <strong>RIS</strong> (Rete Italiana Scambio) è un sistema di <strong>credito comunitario</strong> basato sulla fiducia reciproca. Non sono soldi tradizionali, ma un'unità di misura che rappresenta il valore degli scambi all'interno della comunità RISO.
|
||||
p
|
||||
| <strong>Parità con l'Euro:</strong> 1 RIS = 1 Euro (solo come riferimento di valore, non come convertibilità)
|
||||
|
||||
//- Come funziona la fiducia
|
||||
.highlight-box
|
||||
h4 🤝 Come Funziona la "Fiducia Concessa"
|
||||
p
|
||||
| <strong>Parti da 0 RIS</strong> - Non devi avere un "saldo positivo" per iniziare a scambiare!
|
||||
p
|
||||
| <strong>Quando ricevi</strong> un bene o servizio pagando in RIS → il tuo saldo <strong>diventa positivo</strong>
|
||||
p
|
||||
| <strong>Quando offri</strong> un bene o servizio ricevendo RIS → il tuo saldo <strong>diventa negativo</strong>
|
||||
p(style="margin-top: 12px; padding-top: 12px; border-top: 1px solid #f0ad4e;")
|
||||
| 💡 <strong>Il saldo negativo non è un debito!</strong> È la fiducia che la comunità ti concede. Significa che hai ricevuto prima di aver dato, e la comunità si fida che restituirai nel tempo.
|
||||
|
||||
//- Esempio pratico
|
||||
.example-box
|
||||
h4 📖 Esempio Pratico
|
||||
.transaction
|
||||
| <strong>Situazione:</strong> Sei un grafico e vuoi comprare 100€ di verdure da un produttore locale
|
||||
.transaction
|
||||
| <strong>Transazione mista:</strong>
|
||||
| <br>• Paghi <strong>80€ in Euro</strong>
|
||||
| <br>• Paghi <strong>20 RIS</strong> (20% in RIS)
|
||||
| <br><br>🔻 Il tuo saldo RIS passa da 0 a <strong>-20 RIS</strong>
|
||||
.benefit
|
||||
| <strong>✓ Beneficio:</strong> Hai ridotto del 20% l'uso degli Euro, sostenendo il produttore locale e rafforzando la comunità! Puoi iniziare con percentuali basse (5-10%) e aumentare man mano che acquisisci fiducia.
|
||||
|
||||
//- Come riequilibrare
|
||||
.info-section
|
||||
h3
|
||||
span ⚖️
|
||||
| Come Riequilibrare il Saldo
|
||||
p
|
||||
| Per riportare il tuo saldo verso lo zero (o in positivo), puoi:
|
||||
ul
|
||||
li <strong>Offrire beni o servizi</strong> ricevendo RIS in cambio
|
||||
li <strong>Vendere prodotti</strong> accettando pagamenti parziali o totali in RIS
|
||||
li <strong>Mettere annunci</strong> sulla piattaforma specificando che accetti RIS
|
||||
li <strong>Partecipare ai mercatini</strong> locali della comunità RISO
|
||||
|
||||
//- Primi passi
|
||||
.steps-box
|
||||
h4 🚀 I Tuoi Primi Passi
|
||||
.step-item
|
||||
.step-number 1
|
||||
.step-content
|
||||
h5 Esplora la Piattaforma
|
||||
p Familiarizza con gli annunci, i membri e le funzionalità del #{nomeTerritorio}
|
||||
.step-item
|
||||
.step-number 2
|
||||
.step-content
|
||||
h5 Crea il Tuo Primo Annuncio
|
||||
p Pubblica cosa offri o cosa cerchi, specificando se accetti pagamenti in RIS
|
||||
.step-item
|
||||
.step-number 3
|
||||
.step-content
|
||||
h5 Inizia con Piccole Transazioni
|
||||
p Comincia con percentuali basse di RIS (5-10%) per prendere confidenza e vedi cosa succede. Più siamo aperti noi e più l'Universo ci aiuta e sostiene e ci dona quello di cui abbiamo bisogno.
|
||||
.step-item
|
||||
.step-number 4
|
||||
.step-content
|
||||
h5 Partecipa alla Comunità
|
||||
p Unisciti agli incontri locali e ai mercatini per conoscere altri membri. Se non ci sono membri che propongono incontri, puoi proporti anche tu!
|
||||
|
||||
//- CTA
|
||||
.cta-section
|
||||
.cta-title Inizia Subito a Usare i RIS!
|
||||
a.cta-button(href=strlinksito target="_blank")
|
||||
span.button-icon 🌾
|
||||
| Vai alla Piattaforma
|
||||
|
||||
//- Supporto
|
||||
.info-section
|
||||
h3
|
||||
span ❓
|
||||
| Hai Domande?
|
||||
p
|
||||
| Se hai dubbi sul funzionamento dei RIS o sulla piattaforma, non esitare a:
|
||||
ul
|
||||
li Contattare il facilitatore del tuo territorio
|
||||
li Chiedere nel gruppo Telegram locale
|
||||
li Partecipare agli incontri di comunità
|
||||
|
||||
//- Footer
|
||||
.email-footer
|
||||
.divider
|
||||
p Benvenuto nella Rete Italiana Scambio orizzontale - #{nomeTerritorio}
|
||||
p(style="margin-top: 12px; font-size: 12px;")
|
||||
| #{new Date().getFullYear()} #{nomeapp}
|
||||
1
emails/RISO/circuit_abilitato_al_fido_membro/it/subject.pug
Executable file
1
emails/RISO/circuit_abilitato_al_fido_membro/it/subject.pug
Executable file
@@ -0,0 +1 @@
|
||||
=`Abilitazione avvenuta su ${nomeTerritorio} in ${nomeapp} - (${usernameMembro})`
|
||||
401
emails/RISO/circuit_chiedi_facilitatori_di_entrare/it/html.pug
Executable file
401
emails/RISO/circuit_chiedi_facilitatori_di_entrare/it/html.pug
Executable file
@@ -0,0 +1,401 @@
|
||||
doctype html
|
||||
html(lang="it")
|
||||
head
|
||||
meta(charset="UTF-8")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1.0")
|
||||
style(type="text/css").
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.header-logo {
|
||||
width: 120px;
|
||||
height: auto;
|
||||
margin-bottom: 16px;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.email-container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
background: linear-gradient(135deg, #7cb342 0%, #558b2f 100%);
|
||||
color: white;
|
||||
padding: 40px 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
margin: 0 0 8px 0;
|
||||
font-size: 26px;
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.email-header .subtitle {
|
||||
margin: 8px 0 0 0;
|
||||
font-size: 17px;
|
||||
opacity: 0.95;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.alert-icon {
|
||||
font-size: 56px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 32px 24px;
|
||||
}
|
||||
|
||||
.intro-text {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.request-card {
|
||||
background: linear-gradient(135deg, #e3f2fd 0%, #f0f7ff 100%);
|
||||
border: 2px solid #2196f3;
|
||||
border-radius: 8px;
|
||||
padding: 24px;
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.request-card h3 {
|
||||
font-size: 14px;
|
||||
text-transform: uppercase;
|
||||
color: #2196f3;
|
||||
margin-bottom: 12px;
|
||||
letter-spacing: 0.5px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.request-card .member-name {
|
||||
font-size: 28px;
|
||||
color: #1a1a1a;
|
||||
font-weight: 700;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.request-card .member-detail {
|
||||
font-size: 15px;
|
||||
color: #555;
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
.request-card .member-detail strong {
|
||||
color: #2196f3;
|
||||
}
|
||||
|
||||
.territory-badge {
|
||||
background: linear-gradient(135deg, #4caf50 0%, #388e3c 100%);
|
||||
color: white;
|
||||
display: inline-block;
|
||||
padding: 8px 20px;
|
||||
border-radius: 20px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.question-box {
|
||||
background: #e1f5fe;
|
||||
border-left: 4px solid #2196f3;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 24px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.question-box p {
|
||||
font-size: 20px;
|
||||
color: #1a1a1a;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.cta-section {
|
||||
text-align: center;
|
||||
margin: 32px 0;
|
||||
padding: 24px 0;
|
||||
border-top: 2px solid #e0e0e0;
|
||||
border-bottom: 2px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.cta-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
display: inline-block;
|
||||
padding: 18px 56px;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: white;
|
||||
background: linear-gradient(135deg, #2196f3 0%, #1976d2 100%);
|
||||
border-radius: 50px;
|
||||
text-decoration: none;
|
||||
box-shadow: 0 6px 20px rgba(33, 150, 243, 0.4);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.button-icon {
|
||||
font-size: 20px;
|
||||
margin-right: 10px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.info-box {
|
||||
background: #e8f5e9;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.info-box p {
|
||||
margin: 0 0 8px 0;
|
||||
color: #2e7d32;
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.info-box p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.responsibility-box {
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.responsibility-box h3 {
|
||||
font-size: 17px;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 12px;
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.responsibility-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 10px;
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
.responsibility-icon {
|
||||
font-size: 20px;
|
||||
margin-right: 10px;
|
||||
min-width: 24px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.responsibility-text {
|
||||
font-size: 15px;
|
||||
color: #555;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.email-footer {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
background: #f8f9fa;
|
||||
color: #777;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.email-footer p {
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
background: linear-gradient(to right, transparent, #e0e0e0, transparent);
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
body {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.alert-icon {
|
||||
font-size: 48px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.request-card .member-name {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.territory-badge {
|
||||
font-size: 14px;
|
||||
padding: 6px 16px;
|
||||
}
|
||||
|
||||
.question-box p {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
padding: 16px 40px;
|
||||
font-size: 18px;
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.responsibility-item {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
body
|
||||
.email-container
|
||||
//- Header
|
||||
.email-header
|
||||
img.header-logo(src=baseurl+'/images/logo.png' alt=nomeapp)
|
||||
h1 🎯 Richiesta Abilitazione #{nomeTerritorio}
|
||||
p.subtitle Nuovo membro in attesa di attivazione
|
||||
|
||||
//- Body
|
||||
.email-body
|
||||
//- Intro
|
||||
.intro-text
|
||||
| Ciao <strong>#{nomeFacilitatore}</strong>,<br>
|
||||
| un nuovo membro richiede l'abilitazione alla fiducia al Circuito del tuo territorio!
|
||||
|
||||
//- Card richiesta
|
||||
.request-card
|
||||
h3 👤 Richiesta Ingresso Circuito
|
||||
.member-name #{usernameMembro}
|
||||
if nomeMembro
|
||||
if cognomeMembro
|
||||
.member-detail
|
||||
strong Nome:
|
||||
| #{nomeMembro} #{cognomeMembro}
|
||||
else
|
||||
.member-detail
|
||||
strong Nome:
|
||||
| #{nomeMembro}
|
||||
if emailMembro
|
||||
.member-detail
|
||||
strong Email:
|
||||
| #{emailMembro}
|
||||
if telegramMembro
|
||||
.member-detail
|
||||
strong Telegram:
|
||||
a(href=`https://t.me/${telegramMembro}` target="_blank" style="color: #2196f3; text-decoration: none;") @#{telegramMembro}
|
||||
if comuneResidenza
|
||||
.member-detail
|
||||
strong Comune:
|
||||
| #{comuneResidenza} (#{provinciaResidenza})
|
||||
|
||||
.territory-badge 📍 #{nomeTerritorio}
|
||||
|
||||
if usernameInvitante
|
||||
.divider(style="margin: 20px auto; width: 80%;")
|
||||
h3(style="font-size: 14px; text-transform: uppercase; color: #2196f3; margin-bottom: 12px;") 👥 Invitato da
|
||||
.member-detail
|
||||
strong Invitante:
|
||||
| #{usernameInvitante}
|
||||
if nomeInvitante
|
||||
if cognomeInvitante
|
||||
.member-detail
|
||||
strong Nome:
|
||||
| #{nomeInvitante} #{cognomeInvitante}
|
||||
else
|
||||
.member-detail
|
||||
strong Nome:
|
||||
| #{nomeInvitante}
|
||||
if telegramInvitante
|
||||
.member-detail
|
||||
strong Telegram:
|
||||
a(href=`https://t.me/${telegramInvitante}` target="_blank" style="color: #2196f3; text-decoration: none;") @#{telegramInvitante}
|
||||
|
||||
//- CTA principale
|
||||
.cta-section
|
||||
a.cta-button(href=linkAbilitazione target="_blank")
|
||||
span.button-icon ✓
|
||||
| Abilita fiducia
|
||||
|
||||
.divider(style="margin: 24px 0;")
|
||||
p(style="font-size: 16px; color: #666; margin-bottom: 16px;") Visualizza i profili
|
||||
.button-group(style="display: flex; gap: 12px; justify-content: center; flex-wrap: wrap;")
|
||||
a.secondary-button(href=linkProfiloMembro target="_blank" style="display: inline-block; padding: 12px 24px; font-size: 16px; font-weight: 600; color: #2196f3; background: white; border: 2px solid #2196f3; border-radius: 25px; text-decoration: none; transition: all 0.3s ease;")
|
||||
span(style="margin-right: 6px;") 👤
|
||||
| Profilo Membro
|
||||
if linkProfiloInvitante
|
||||
a.secondary-button(href=linkProfiloInvitante target="_blank" style="display: inline-block; padding: 12px 24px; font-size: 16px; font-weight: 600; color: #7cb342; background: white; border: 2px solid #7cb342; border-radius: 25px; text-decoration: none; transition: all 0.3s ease;")
|
||||
span(style="margin-right: 6px;") 👥
|
||||
| Profilo Invitante
|
||||
|
||||
//- Responsabilità
|
||||
.responsibility-box
|
||||
h3 📋 Compiti del Facilitatore RISO
|
||||
.responsibility-item
|
||||
span.responsibility-icon 🔍
|
||||
span.responsibility-text
|
||||
strong Verifica:
|
||||
| Contatta il membro, se non lo conosci, oppure il suo invitante: #{usernameInvitante}
|
||||
.responsibility-item
|
||||
span.responsibility-icon 🌍
|
||||
span.responsibility-text
|
||||
strong Territorio:
|
||||
| Assicurati che il membro appartenga effettivamente al territorio di competenza
|
||||
.responsibility-item
|
||||
span.responsibility-icon 👥
|
||||
span.responsibility-text
|
||||
strong Integrazione:
|
||||
| Supporta il nuovo membro nell'attivazione e utilizzo del Circuito locale
|
||||
|
||||
//- Info box
|
||||
.info-box
|
||||
p
|
||||
| ✓ Dopo l'abilitazione, #{usernameMembro} potrà accedere al #{nomeTerritorio}
|
||||
p
|
||||
| ✓ Il membro riceverà una notifica automatica dell'avvenuta attivazione
|
||||
|
||||
//- Footer
|
||||
.email-footer
|
||||
.divider
|
||||
p Hai ricevuto questa email in qualità di Facilitatore RISO per #{nomeTerritorio}
|
||||
p(style="margin-top: 12px; font-size: 12px;")
|
||||
| #{new Date().getFullYear()} #{nomeapp}
|
||||
1
emails/RISO/circuit_chiedi_facilitatori_di_entrare/it/subject.pug
Executable file
1
emails/RISO/circuit_chiedi_facilitatori_di_entrare/it/subject.pug
Executable file
@@ -0,0 +1 @@
|
||||
=`Richiesta ingresso di ${usernameMembro} - ${nomeMembro} ${cognomeMembro} su ${nomeTerritorio} in ${nomeapp}`
|
||||
370
emails/RISO/reg_chiedi_ammettere_all_invitante/it/html.pug
Executable file
370
emails/RISO/reg_chiedi_ammettere_all_invitante/it/html.pug
Executable file
@@ -0,0 +1,370 @@
|
||||
doctype html
|
||||
html(lang="it")
|
||||
head
|
||||
meta(charset="UTF-8")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1.0")
|
||||
style(type="text/css").
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.header-logo {
|
||||
width: 120px;
|
||||
height: auto;
|
||||
margin-bottom: 16px;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.email-container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
background: linear-gradient(135deg, #7cb342 0%, #558b2f 100%);
|
||||
color: white;
|
||||
padding: 40px 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
margin: 0 0 8px 0;
|
||||
font-size: 26px;
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.email-header .subtitle {
|
||||
margin: 8px 0 0 0;
|
||||
font-size: 17px;
|
||||
opacity: 0.95;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.alert-icon {
|
||||
font-size: 56px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 32px 24px;
|
||||
}
|
||||
|
||||
.intro-text {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.request-card {
|
||||
background: linear-gradient(135deg, #fff8dc 0%, #fef9f3 100%);
|
||||
border: 2px solid #f0ad4e;
|
||||
border-radius: 8px;
|
||||
padding: 24px;
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.request-card h3 {
|
||||
font-size: 14px;
|
||||
text-transform: uppercase;
|
||||
color: #f0ad4e;
|
||||
margin-bottom: 12px;
|
||||
letter-spacing: 0.5px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.request-card .member-name {
|
||||
font-size: 28px;
|
||||
color: #1a1a1a;
|
||||
font-weight: 700;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.request-card .member-detail {
|
||||
font-size: 15px;
|
||||
color: #555;
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
.request-card .member-detail strong {
|
||||
color: #f0ad4e;
|
||||
}
|
||||
|
||||
.question-box {
|
||||
background: #fff3cd;
|
||||
border-left: 4px solid #f0ad4e;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 24px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.question-box p {
|
||||
font-size: 20px;
|
||||
color: #1a1a1a;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.cta-section {
|
||||
text-align: center;
|
||||
margin: 32px 0;
|
||||
padding: 24px 0;
|
||||
border-top: 2px solid #e0e0e0;
|
||||
border-bottom: 2px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.cta-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
display: inline-block;
|
||||
padding: 18px 56px;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: white;
|
||||
background: linear-gradient(135deg, #7cb342 0%, #558b2f 100%);
|
||||
border-radius: 50px;
|
||||
text-decoration: none;
|
||||
box-shadow: 0 6px 20px rgba(124, 179, 66, 0.4);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.button-icon {
|
||||
font-size: 20px;
|
||||
margin-right: 10px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.info-box {
|
||||
background: #e8f5e9;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.info-box p {
|
||||
margin: 0 0 8px 0;
|
||||
color: #2e7d32;
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.info-box p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.warning-box {
|
||||
background: #f8d7da;
|
||||
border-left: 4px solid #dc3545;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.warning-box p {
|
||||
margin: 0;
|
||||
color: #721c24;
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.warning-box strong {
|
||||
color: #dc3545;
|
||||
}
|
||||
|
||||
.responsibility-box {
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.responsibility-box h3 {
|
||||
font-size: 17px;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 12px;
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.responsibility-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 10px;
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
.responsibility-icon {
|
||||
font-size: 20px;
|
||||
margin-right: 10px;
|
||||
min-width: 24px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.responsibility-text {
|
||||
font-size: 15px;
|
||||
color: #555;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.email-footer {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
background: #f8f9fa;
|
||||
color: #777;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.email-footer p {
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
background: linear-gradient(to right, transparent, #e0e0e0, transparent);
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
body {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.alert-icon {
|
||||
font-size: 48px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.request-card .member-name {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.question-box p {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
padding: 16px 40px;
|
||||
font-size: 18px;
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.responsibility-item {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
body
|
||||
.email-container
|
||||
//- Header
|
||||
.email-header
|
||||
img.header-logo(src=baseurl+'/images/logo.png' alt=nomeapp)
|
||||
h1 🔔 Richiesta di Ammissione
|
||||
p.subtitle Nuovo membro in attesa
|
||||
|
||||
//- Body
|
||||
.email-body
|
||||
//- Intro
|
||||
.intro-text
|
||||
| Ciao <strong>#{nomeInvitante}</strong>,<br>
|
||||
| hai una nuova richiesta di ammissione da confermare!
|
||||
|
||||
//- Card richiesta
|
||||
.request-card
|
||||
h3 👤 Richiesta di Ingresso
|
||||
.member-name #{usernameInvitato}
|
||||
if nomeInvitato
|
||||
.member-detail
|
||||
strong Nome:
|
||||
| #{nomeInvitato}
|
||||
if emailInvitato
|
||||
.member-detail
|
||||
strong Email:
|
||||
| #{emailInvitato}
|
||||
if userprofile && userprofile.profile.resid_str_comune && userprofile.profile.resid_province
|
||||
.member-detail
|
||||
strong Comune Residenza:
|
||||
| #{userprofile.profile.resid_str_comune} (#{userprofile.profile.resid_province})
|
||||
|
||||
//- Domanda di conferma
|
||||
.question-box
|
||||
p 🤔 Confermi di conoscere #{nomeInvitato}?
|
||||
|
||||
//- CTA principale
|
||||
.cta-section
|
||||
a.cta-button(href=linkAmmissione target="_blank")
|
||||
span.button-icon ✓
|
||||
| Sì, Confermo
|
||||
|
||||
//- Responsabilità
|
||||
.responsibility-box
|
||||
h3 📋 La tua responsabilità come invitante
|
||||
.responsibility-item
|
||||
span.responsibility-icon 🤝
|
||||
span.responsibility-text
|
||||
strong Conoscenza diretta:
|
||||
| Dovresti ammettere solo persone che conosci personalmente e di cui ti fidi
|
||||
.responsibility-item
|
||||
span.responsibility-icon 🛡️
|
||||
span.responsibility-text
|
||||
strong Fiducia:
|
||||
| L'ammissione si basa sulla fiducia reciproca nella comunità #{nomeapp}
|
||||
.responsibility-item
|
||||
span.responsibility-icon 👥
|
||||
span.responsibility-text
|
||||
strong Supporto:
|
||||
| Come invitante, aiuterai il nuovo membro a integrarsi nella comunità
|
||||
|
||||
//- Info box
|
||||
.info-box
|
||||
p
|
||||
| ✓ Dopo l'ammissione, #{usernameInvitato} potrà completare il profilo
|
||||
|
||||
//- Warning box
|
||||
.warning-box
|
||||
p
|
||||
strong ⚠️ Importante:
|
||||
| Se non conosci questa persona o hai dubbi sull'ammissione, ti consigliamo di non procedere. Puoi contattare il facilitatore locale per ulteriori informazioni o semplicemente non cliccare sul pulsante di conferma.
|
||||
|
||||
//- Footer
|
||||
.email-footer
|
||||
.divider
|
||||
p Hai ricevuto questa email perché #{usernameInvitato} ha indicato te come invitante su #{nomeapp}
|
||||
p(style="margin-top: 12px; font-size: 12px;")
|
||||
| #{new Date().getFullYear()} #{nomeapp}
|
||||
1
emails/RISO/reg_chiedi_ammettere_all_invitante/it/subject.pug
Executable file
1
emails/RISO/reg_chiedi_ammettere_all_invitante/it/subject.pug
Executable file
@@ -0,0 +1 @@
|
||||
=`🎉 ${name ? ', ' + name : username} chiede di essere ammesso su ${nomeapp} !`
|
||||
534
emails/RISO/reg_email_benvenuto_ammesso/it/html.pug
Executable file
534
emails/RISO/reg_email_benvenuto_ammesso/it/html.pug
Executable file
@@ -0,0 +1,534 @@
|
||||
doctype html
|
||||
html(lang="it")
|
||||
head
|
||||
meta(charset="UTF-8")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1.0")
|
||||
style(type="text/css").
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.header-logo {
|
||||
width: 80px;
|
||||
height: auto;
|
||||
margin-bottom: 16px;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.email-container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
background: linear-gradient(135deg, #2E7D32 0%, #1B5E20 100%);
|
||||
color: white;
|
||||
padding: 40px 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
margin: 0 0 8px 0;
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.email-header p {
|
||||
margin: 8px 0 0 0;
|
||||
font-size: 16px;
|
||||
opacity: 0.95;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.welcome-icon {
|
||||
font-size: 48px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 24px 20px;
|
||||
}
|
||||
|
||||
.intro-text {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
line-height: 1.7;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.intro-text strong {
|
||||
color: #2E7D32;
|
||||
}
|
||||
|
||||
.welcome-message {
|
||||
background: linear-gradient(135deg, #E8F5E9 0%, #C8E6C9 100%);
|
||||
border-left: 4px solid #2E7D32;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin-bottom: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.welcome-message h2 {
|
||||
color: #1B5E20;
|
||||
font-size: 20px;
|
||||
margin-bottom: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.welcome-message p {
|
||||
color: #2E7D32;
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.credentials-box {
|
||||
background: #f8f9fa;
|
||||
border-left: 4px solid #2E7D32;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.credentials-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #555;
|
||||
margin-bottom: 12px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.credential-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.credential-row:last-child {
|
||||
border-bottom: none;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.credential-label {
|
||||
font-weight: 600;
|
||||
color: #666;
|
||||
min-width: 120px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.credential-value {
|
||||
color: #1a1a1a;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
flex: 1;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.credential-value a {
|
||||
color: #2E7D32;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.credential-value a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.cta-section {
|
||||
margin: 24px 0;
|
||||
padding: 20px 0;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.cta-title {
|
||||
font-size: 19px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.cta-subtitle {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-bottom: 16px;
|
||||
text-align: center;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.cta-buttons-wrapper {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
justify-content: center;
|
||||
align-items: stretch;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
display: inline-block;
|
||||
padding: 16px 28px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
background: linear-gradient(135deg, #2E7D32 0%, #1B5E20 100%);
|
||||
border-radius: 50px;
|
||||
text-decoration: none;
|
||||
box-shadow: 0 4px 12px rgba(46, 125, 50, 0.3);
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
flex: 1;
|
||||
min-width: 160px;
|
||||
max-width: 200px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.cta-button:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 16px rgba(46, 125, 50, 0.4);
|
||||
}
|
||||
|
||||
.cta-button-secondary {
|
||||
background: linear-gradient(135deg, #388E3C 0%, #2E7D32 100%);
|
||||
box-shadow: 0 4px 12px rgba(56, 142, 60, 0.3);
|
||||
}
|
||||
|
||||
.cta-button-secondary:hover {
|
||||
box-shadow: 0 6px 16px rgba(56, 142, 60, 0.4);
|
||||
}
|
||||
|
||||
.cta-button-tertiary {
|
||||
background: linear-gradient(135deg, #66BB6A 0%, #4CAF50 100%);
|
||||
box-shadow: 0 4px 12px rgba(76, 175, 80, 0.3);
|
||||
}
|
||||
|
||||
.cta-button-tertiary:hover {
|
||||
box-shadow: 0 6px 16px rgba(76, 175, 80, 0.4);
|
||||
}
|
||||
|
||||
.button-icon {
|
||||
font-size: 18px;
|
||||
margin-right: 6px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.next-steps {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 24px 0;
|
||||
}
|
||||
|
||||
.next-steps-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #2E7D32;
|
||||
margin-bottom: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.step-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding: 12px;
|
||||
margin-bottom: 12px;
|
||||
background: #f8fdf9;
|
||||
border-radius: 8px;
|
||||
border-left: 3px solid #4CAF50;
|
||||
}
|
||||
|
||||
.step-number {
|
||||
background: linear-gradient(135deg, #4CAF50 0%, #388E3C 100%);
|
||||
color: white;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
margin-right: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.step-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.step-content h3 {
|
||||
font-size: 16px;
|
||||
color: #1B5E20;
|
||||
margin-bottom: 4px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.step-content p {
|
||||
font-size: 14px;
|
||||
color: #555;
|
||||
line-height: 1.5;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.info-box {
|
||||
background: linear-gradient(135deg, #E8F5E9 0%, #C8E6C9 100%);
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
border: 1px solid #A5D6A7;
|
||||
}
|
||||
|
||||
.info-box p {
|
||||
margin: 0;
|
||||
color: #1B5E20;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.info-box strong {
|
||||
color: #2E7D32;
|
||||
}
|
||||
|
||||
.community-note {
|
||||
background: #fff3e0;
|
||||
border-left: 4px solid #FF9800;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.community-note p {
|
||||
color: #E65100;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.email-footer {
|
||||
padding: 20px 16px;
|
||||
text-align: center;
|
||||
background: #f8f9fa;
|
||||
color: #777;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.email-footer p {
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
background: linear-gradient(to right, transparent, #e0e0e0, transparent);
|
||||
margin: 24px 0;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
body {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.email-header p {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 20px 14px;
|
||||
}
|
||||
|
||||
.welcome-message {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.credentials-box {
|
||||
padding: 16px 12px;
|
||||
}
|
||||
|
||||
.credential-row {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.credential-label {
|
||||
margin-bottom: 4px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.credential-value {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.cta-buttons-wrapper {
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
padding: 14px 24px;
|
||||
font-size: 15px;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.step-item {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.step-number {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.step-content h3 {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.step-content p {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
body
|
||||
.email-container
|
||||
.email-header
|
||||
- var baseimg = baseurl + '/';
|
||||
img.header-logo(src=baseimg+"images/logo.png" alt=nomeapp || 'Logo')
|
||||
h1 Benvenuto/a #{name || username} nella community RISO! 💚
|
||||
|
||||
.email-body
|
||||
.welcome-message
|
||||
if ammessoUtente
|
||||
h2 🎉 Il tuo invitante #{nomeInvitante} ti ha ammesso!
|
||||
p Sei ora un membro della Rete Italiana di Scambio Orizzontale
|
||||
p Inizia subito a scoprire beni, servizi e ospitalità nella tua comunità territoriale
|
||||
|
||||
.intro-text
|
||||
| La tua comunità RISO ti aspetta! 🌱 Qui potrai
|
||||
strong scambiare beni e servizi
|
||||
| usando i
|
||||
strong RIS
|
||||
| , conoscere persone straordinarie e contribuire a costruire
|
||||
strong un'economia più umana e solidale
|
||||
| .
|
||||
|
||||
.next-steps
|
||||
.next-steps-title 🎯 I tuoi primi passi nella community RISO
|
||||
|
||||
.step-item
|
||||
.step-number 1
|
||||
.step-content
|
||||
h3 ✅ Completa il tuo profilo
|
||||
p Collega il tuo profilo a Telegram ed accedi ai Circuiti Territoriali per poter iniziare ad usare i RIS. Un profilo completo aiuta gli altri membri a conoscerti meglio!
|
||||
|
||||
.step-item
|
||||
.step-number 2
|
||||
.step-content
|
||||
h3 🔍 Esplora gli annunci
|
||||
p Scopri cosa offrono gli altri membri nella tua area. Potresti trovare esattamente ciò che cerchi!
|
||||
|
||||
.step-item
|
||||
.step-number 3
|
||||
.step-content
|
||||
h3 📢 Pubblica il tuo primo annuncio
|
||||
p Cosa puoi offrire? Beni, servizi o ospitalità - ogni contributo arricchisce la comunità. Ricorda di includere come strumento di scambio il RIS e sperimentalo da subito!
|
||||
|
||||
.step-item
|
||||
.step-number 4
|
||||
.step-content
|
||||
h3 💬 Unisciti al gruppo territoriale
|
||||
p Partecipa alle conversazioni, agli eventi e alle iniziative della tua comunità locale sulle chat Telegram di RISO
|
||||
|
||||
.cta-section
|
||||
.cta-title 🚀 Accedi e inizia il tuo viaggio RISO
|
||||
.cta-subtitle Scegli come vuoi accedere alla piattaforma
|
||||
|
||||
.credentials-box
|
||||
.credentials-title 📋 I tuoi dati di accesso
|
||||
|
||||
if username
|
||||
.credential-row
|
||||
.credential-label Username:
|
||||
.credential-value #{username}
|
||||
|
||||
if emailto
|
||||
.credential-row
|
||||
.credential-label Email:
|
||||
.credential-value #{emailto}
|
||||
|
||||
if forgetpwd
|
||||
.credential-row
|
||||
.credential-label Password:
|
||||
.credential-value
|
||||
| (la password che hai inserito)
|
||||
br
|
||||
a(href=forgetpwd target="_blank") Hai dimenticato la password?
|
||||
|
||||
if strlinksito
|
||||
.cta-buttons-wrapper
|
||||
a.cta-button(href=strlinksito target="_blank")
|
||||
span.button-icon 🌐
|
||||
| Accedi da Web
|
||||
|
||||
a.cta-button.cta-button-secondary(href=strlinksito+'/installaapp' target="_blank")
|
||||
span.button-icon 📱
|
||||
| Installa l'App
|
||||
|
||||
a.cta-button.cta-button-tertiary(href=strlinksito+'/guida' target="_blank")
|
||||
span.button-icon 📖
|
||||
| Leggi la Guida
|
||||
|
||||
.info-box
|
||||
p
|
||||
strong 💰 Cos'è il RIS?
|
||||
br
|
||||
| Il RIS è l'unità di scambio della comunità RISO, basata sulla
|
||||
strong fiducia reciproca
|
||||
| . Parti da 0 RIS e accumula crediti offrendo i tuoi beni/servizi. Usalo per ottenere ciò di cui hai bisogno. Il bilancio totale della comunità è sempre zero - ogni credito corrisponde al debito di qualcun altro.
|
||||
|
||||
.community-note
|
||||
p
|
||||
| 🤝
|
||||
strong Ricorda:
|
||||
| Ogni scambio che fai, ogni annuncio che pubblichi, ogni interazione che hai rafforza la rete RISO. Non sei solo un utente -
|
||||
strong sei un membro attivo
|
||||
| di una comunità che crede nella solidarietà e nella condivisione!
|
||||
|
||||
|
||||
.email-footer
|
||||
.divider
|
||||
p 💚 Benvenuto/a nella famiglia RISO!
|
||||
p(style="margin-top: 8px;") Hai ricevuto questa email perché sei stato/a ammesso/a nella comunità #{nomeapp || 'RISO'}
|
||||
p(style="margin-top: 12px; font-size: 12px;")
|
||||
| © #{new Date().getFullYear()} #{nomeapp || 'RISO'} - Rete Italiana di Scambio Orizzontale
|
||||
p(style="margin-top: 8px; font-size: 11px; color: #999;")
|
||||
| Costruiamo insieme un'economia più umana e solidale
|
||||
1
emails/RISO/reg_email_benvenuto_ammesso/it/subject.pug
Executable file
1
emails/RISO/reg_email_benvenuto_ammesso/it/subject.pug
Executable file
@@ -0,0 +1 @@
|
||||
=`Benvenuto in ${nomeapp}`
|
||||
394
emails/RISO/reg_notifica_all_invitante/it/html.pug
Executable file
394
emails/RISO/reg_notifica_all_invitante/it/html.pug
Executable file
@@ -0,0 +1,394 @@
|
||||
doctype html
|
||||
html(lang="it")
|
||||
head
|
||||
meta(charset="UTF-8")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1.0")
|
||||
style(type="text/css").
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.header-logo {
|
||||
width: 120px;
|
||||
height: auto;
|
||||
margin-bottom: 16px;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.email-container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
background: linear-gradient(135deg, #7cb342 0%, #558b2f 100%);
|
||||
color: white;
|
||||
padding: 40px 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
margin: 0 0 8px 0;
|
||||
font-size: 26px;
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.email-header .subtitle {
|
||||
margin: 8px 0 0 0;
|
||||
font-size: 17px;
|
||||
opacity: 0.95;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.success-icon {
|
||||
font-size: 56px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 32px 24px;
|
||||
}
|
||||
|
||||
.intro-text {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.highlight-box {
|
||||
background: #fff8dc;
|
||||
border-left: 4px solid #7cb342;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.highlight-box p {
|
||||
margin: 0;
|
||||
font-size: 17px;
|
||||
color: #1a1a1a;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.member-card {
|
||||
background: linear-gradient(135deg, #f8fdf8 0%, #e8f5e9 100%);
|
||||
border: 2px solid #7cb342;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.member-card h3 {
|
||||
font-size: 14px;
|
||||
text-transform: uppercase;
|
||||
color: #558b2f;
|
||||
margin-bottom: 12px;
|
||||
letter-spacing: 0.5px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.member-card .member-name {
|
||||
font-size: 24px;
|
||||
color: #1a1a1a;
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.member-card .member-detail {
|
||||
font-size: 15px;
|
||||
color: #555;
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
.member-card .member-detail strong {
|
||||
color: #558b2f;
|
||||
}
|
||||
|
||||
.info-box {
|
||||
background: #e8f5e9;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.info-box p {
|
||||
margin: 0 0 8px 0;
|
||||
color: #2e7d32;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.info-box p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.tips-section {
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.tips-section h3 {
|
||||
font-size: 17px;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 12px;
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.tip-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 10px;
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
.tip-icon {
|
||||
font-size: 20px;
|
||||
margin-right: 10px;
|
||||
min-width: 24px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.tip-text {
|
||||
font-size: 16px;
|
||||
color: #555;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.buttprof-section {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.cta-section {
|
||||
text-align: center;
|
||||
margin: 24px 0;
|
||||
padding: 20px 0;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.cta-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
display: inline-block;
|
||||
padding: 16px 48px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
background: linear-gradient(135deg, #7cb342 0%, #558b2f 100%);
|
||||
border-radius: 50px;
|
||||
text-decoration: none;
|
||||
box-shadow: 0 4px 12px rgba(124, 179, 66, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.thank-you-box {
|
||||
background: linear-gradient(135deg, #fff8dc 0%, #fef9f3 100%);
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.thank-you-box p {
|
||||
font-size: 17px;
|
||||
color: #555;
|
||||
line-height: 1.7;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.thank-you-box strong {
|
||||
color: #558b2f;
|
||||
}
|
||||
|
||||
.email-footer {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
background: #f8f9fa;
|
||||
color: #777;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.email-footer p {
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
background: linear-gradient(to right, transparent, #e0e0e0, transparent);
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.profile-button {
|
||||
display: inline-block;
|
||||
margin-top: 16px;
|
||||
padding: 12px 32px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
background: linear-gradient(135deg, #7cb342 0%, #558b2f 100%);
|
||||
border-radius: 25px;
|
||||
text-decoration: none;
|
||||
box-shadow: 0 3px 10px rgba(124, 179, 66, 0.25);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
body {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.success-icon {
|
||||
font-size: 48px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
padding: 14px 32px;
|
||||
font-size: 16px;
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.member-card .member-name {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.tip-item {
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
body
|
||||
.email-container
|
||||
//- Header
|
||||
.email-header
|
||||
img.header-logo(src=baseurl+'/images/logo.png' alt=nomeapp+' - Rete Italiana Scambio orizzontale')
|
||||
h1 🎉 Il tuo invito è stato accettato!
|
||||
p.subtitle Un nuovo membro si è unito a #{nomeapp}
|
||||
|
||||
//- Body
|
||||
.email-body
|
||||
//- Intro
|
||||
.intro-text
|
||||
| Ciao <strong>#{nomeInvitante}</strong>,<br>
|
||||
| la persona che hai invitato, o che ha usato il tuo username come invitante, si è appena registrata su #{nomeapp}!
|
||||
|
||||
//- Card nuovo membro
|
||||
.member-card
|
||||
h3 👤 Nuovo Membro Registrato
|
||||
.member-name #{nomeInvitato}
|
||||
if emailInvitato
|
||||
.member-detail
|
||||
strong Email:
|
||||
a(href=`mailto:${emailInvitato}` style="color: #667eea; text-decoration: none;") #{emailInvitato}
|
||||
if usernameInvitato
|
||||
.member-detail
|
||||
strong Username:
|
||||
| #{usernameInvitato}
|
||||
|
||||
//- Bottone profilo
|
||||
if usernameInvitato
|
||||
.buttprof-section
|
||||
a.profile-button(href=strlinksito + '/my/' + usernameInvitato target="_blank")
|
||||
| 👤 Visualizza Profilo di #{usernameInvitato}
|
||||
|
||||
//- Ringraziamento
|
||||
.thank-you-box
|
||||
p
|
||||
| 🙏 <strong>Grazie per aver contribuito alla crescita di #{nomeapp}!</strong>
|
||||
p
|
||||
| Ogni nuovo ingresso rende la nostra comunità più forte e ricca di opportunità.
|
||||
| Il tuo invito aiuta #{nomeInvitato} a scoprire un nuovo modo di fare economia,
|
||||
| basato su fiducia, comunità e scambi solidali.
|
||||
|
||||
//- Suggerimenti
|
||||
.tips-section
|
||||
h3 💡 Come puoi aiutare #{nomeInvitato}
|
||||
.tip-item
|
||||
span.tip-icon 🤝
|
||||
span.tip-text
|
||||
strong Connettiti con loro:
|
||||
| Aiutali a sentirsi parte della comunità e presentali ad altri membri del circuito
|
||||
.tip-item
|
||||
span.tip-icon 📱
|
||||
span.tip-text
|
||||
strong Mostra come funziona #{nomeapp}:
|
||||
| Spiega come creare annunci, usare i RIS e partecipare agli scambi nella tua zona
|
||||
.tip-item
|
||||
span.tip-icon 📲
|
||||
span.tip-text
|
||||
strong Gruppo Telegram:
|
||||
| Incoraggiali a unirsi al gruppo Telegram del vostro circuito provinciale
|
||||
.tip-item
|
||||
span.tip-icon 🎯
|
||||
span.tip-text
|
||||
strong Profilo completo:
|
||||
| Ricorda loro di completare il profilo per poter iniziare a scambiare
|
||||
|
||||
//- Info box
|
||||
.info-box
|
||||
p
|
||||
| ✓ #{nomeInvitato} ha ricevuto un'email di benvenuto con tutte le istruzioni
|
||||
p
|
||||
| ✓ Dovrà completare il profilo prima di poter usare i RIS
|
||||
p
|
||||
| ✓ Il facilitatore locale valuterà l'abilitazione all'uso dei RIS
|
||||
|
||||
//- CTA
|
||||
.cta-section
|
||||
.cta-title Visita la Piattaforma
|
||||
a.cta-button(href=strlinksito target="_blank") Vai su #{nomeapp}
|
||||
|
||||
//- Highlight box
|
||||
.highlight-box
|
||||
p
|
||||
| 🌱 <strong>Costruiamo insieme un'economia più solidale!</strong><br>
|
||||
| Continua a condividere #{nomeapp} con persone di fiducia della tua comunità.
|
||||
| Più siamo, più scambi possibili ci sono per tutti!
|
||||
|
||||
//- Footer
|
||||
.email-footer
|
||||
.divider
|
||||
p Hai ricevuto questa email perché hai invitato #{nomeInvitato} su #{nomeapp} oppure la persona ha usato il tuo username come invitante
|
||||
p(style="margin-top: 12px; font-size: 12px;")
|
||||
| #{new Date().getFullYear()} #{nomeapp} - Rete Italiana Scambio orizzontale
|
||||
p(style="margin-top: 12px; font-size: 12px;")
|
||||
| 🍚 Comunità · Fiducia · Scambi Solidali · Sostenibilità
|
||||
1
emails/RISO/reg_notifica_all_invitante/it/subject.pug
Executable file
1
emails/RISO/reg_notifica_all_invitante/it/subject.pug
Executable file
@@ -0,0 +1 @@
|
||||
=`🎉 Il tuo invito è stato accettato su RISO da ${name ? name : username} !`
|
||||
@@ -1,71 +0,0 @@
|
||||
p #{username} (#{name} #{surname}) si è appena Iscritto ad Arcadei Foundation su #{nomeapp}
|
||||
p Con i seguenti dati di accesso:
|
||||
span Nome:
|
||||
strong #{iscritto.name}<br>
|
||||
span Cognome:
|
||||
strong #{iscritto.surname}<br>
|
||||
span Email:
|
||||
strong #{iscritto.email}<br>
|
||||
span Email Secondaria:
|
||||
strong #{iscritto.email2}<br>
|
||||
span Indirizzo di Residenza:
|
||||
strong #{iscritto.residency_address}<br>
|
||||
span Città di Residenza:
|
||||
strong #{iscritto.residency_city}<br>
|
||||
span Provincia:
|
||||
strong #{iscritto.residency_province}<br>
|
||||
span CAP:
|
||||
strong #{iscritto.residency_zipcode}<br>
|
||||
span Nazione:
|
||||
strong #{iscritto.residency_country}<br>
|
||||
span Data di Nascita:
|
||||
strong #{data_nascita}<br>
|
||||
span Città di Nascita:
|
||||
strong #{iscritto.born_city}<br>
|
||||
span Provincia di Nascita:
|
||||
strong #{iscritto.born_province}<br>
|
||||
span Paese di Nascita:
|
||||
strong #{iscritto.born_country}<br>
|
||||
span Telefono:
|
||||
strong #{iscritto.cell_phone}<br>
|
||||
span Telefono2:
|
||||
strong #{iscritto.cell_phone2}<br>
|
||||
span Tipo di Documento :
|
||||
strong #{iscritto.doctype}<br>
|
||||
span Numero Documento :
|
||||
strong #{iscritto.documentnumber}<br>
|
||||
span Metodo di Pagamento :
|
||||
strong #{iscritto.metodo_pagamento}<br>
|
||||
span Quota scelta da versare :
|
||||
strong #{iscritto.quota_versata}<br>
|
||||
span Scrivi altre eventuali informazioni o comunicazioni:
|
||||
strong #{iscritto.altre_comunicazioni}<br>
|
||||
span Categorie d'Interesse :
|
||||
strong #{iscritto.categorie_interesse}<br>
|
||||
p <br>Saluti
|
||||
|
||||
style(type="text/css").
|
||||
html, body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
p {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.divbtn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.btn-lg {
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
background: #027be3 !important;
|
||||
border-radius: 28px;
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
=`Nuova Iscrizione Arcadei di ${name} ${surname} (${emailto}) su ${nomeapp}`
|
||||
@@ -1,42 +1,185 @@
|
||||
p #{username} (#{name} #{surname}) si è appena Registrato su #{nomeapp}
|
||||
p Con i seguenti dati di accesso:
|
||||
span Username:
|
||||
strong #{username}<br>
|
||||
span Email:
|
||||
strong #{emailto}<br>
|
||||
span Invitante:
|
||||
strong #{aportador_solidario}<br>
|
||||
span Nome:
|
||||
strong #{user.name}<br>
|
||||
span Cognome:
|
||||
strong #{user.surname}<br>
|
||||
span Cellulare:
|
||||
strong #{user.profile.intcode_cell} #{user.profile.cell}<br>
|
||||
span Nazionalità:
|
||||
strong #{user.profile.nationality}<br>
|
||||
span Gruppo:
|
||||
strong #{idMyGroup}<br>
|
||||
p <br>Saluti
|
||||
|
||||
style(type="text/css").
|
||||
html, body {
|
||||
padding: 0;
|
||||
doctype html
|
||||
html(lang="it")
|
||||
head
|
||||
meta(charset="UTF-8")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1.0")
|
||||
style(type="text/css").
|
||||
* {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.divbtn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.btn-lg {
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.email-container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
background: linear-gradient(135deg, #027be3 0%, #0056b3 100%);
|
||||
color: white;
|
||||
background: #027be3 !important;
|
||||
border-radius: 28px;
|
||||
padding: 32px 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
margin: 0;
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.email-header p {
|
||||
margin: 8px 0 0 0;
|
||||
font-size: 14px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 32px 24px;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.info-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-weight: 600;
|
||||
color: #555;
|
||||
min-width: 140px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
color: #1a1a1a;
|
||||
font-size: 14px;
|
||||
flex: 1;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.email-footer {
|
||||
padding: 24px;
|
||||
text-align: center;
|
||||
background: #f8f9fa;
|
||||
color: #777;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
display: inline-block;
|
||||
background: #e3f2fd;
|
||||
color: #027be3;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
body {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
body
|
||||
.email-container
|
||||
.email-header
|
||||
h1 ✓ Nuova Registrazione su #{nomeapp}
|
||||
p #{nomeapp || 'Piattaforma'}
|
||||
|
||||
.email-body
|
||||
p(style="margin-bottom: 20px; font-size: 15px; color: #333;")
|
||||
| L'utente
|
||||
span.highlight #{username || 'N/D'}
|
||||
| si è appena registrato sulla piattaforma #{nomeapp}.
|
||||
|
||||
.user-info
|
||||
if username
|
||||
.info-row
|
||||
.info-label Username:
|
||||
.info-value #{username}
|
||||
|
||||
if emailto
|
||||
.info-row
|
||||
.info-label Email:
|
||||
.info-value #{emailto}
|
||||
|
||||
if user && user.name
|
||||
.info-row
|
||||
.info-label Nome:
|
||||
.info-value #{user.name}
|
||||
|
||||
if user && user.surname
|
||||
.info-row
|
||||
.info-label Cognome:
|
||||
.info-value #{user.surname}
|
||||
|
||||
if user && user.profile && (user.profile.cell || user.profile.intcode_cell)
|
||||
.info-row
|
||||
.info-label Cellulare:
|
||||
.info-value
|
||||
| #{user.profile.intcode_cell || ''} #{user.profile.cell || ''}
|
||||
|
||||
if user && user.profile && (user.profile.resid_str_comune && user.profile.resid_province)
|
||||
.info-row
|
||||
.info-label Comune di Residenza:
|
||||
.info-value
|
||||
| #{user.profile.resid_str_comune || ''} (#{user.profile.resid_province || ''})
|
||||
|
||||
if user && user.profile && user.profile.nationality
|
||||
.info-row
|
||||
.info-label Nazionalità:
|
||||
.info-value #{user.profile.nationality}
|
||||
|
||||
if aportador_solidario
|
||||
.info-row
|
||||
.info-label Invitante:
|
||||
.info-value #{aportador_solidario}
|
||||
|
||||
if idMyGroup
|
||||
.info-row
|
||||
.info-label Gruppo:
|
||||
.info-value #{idMyGroup}
|
||||
|
||||
.email-footer
|
||||
p Questa è una email automatica di notifica
|
||||
p(style="margin-top: 8px; font-size: 12px;")
|
||||
| © #{new Date().getFullYear()} #{nomeapp || ''}.
|
||||
375
emails/defaultSite/reg_chiedi_ammettere_all_invitante/it/html.pug
Executable file
375
emails/defaultSite/reg_chiedi_ammettere_all_invitante/it/html.pug
Executable file
@@ -0,0 +1,375 @@
|
||||
doctype html
|
||||
html(lang="it")
|
||||
head
|
||||
meta(charset="UTF-8")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1.0")
|
||||
style(type="text/css").
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.header-logo {
|
||||
width: 120px;
|
||||
height: auto;
|
||||
margin-bottom: 16px;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.email-container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
background: linear-gradient(135deg, #7cb342 0%, #558b2f 100%);
|
||||
color: white;
|
||||
padding: 40px 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
margin: 0 0 8px 0;
|
||||
font-size: 26px;
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.email-header .subtitle {
|
||||
margin: 8px 0 0 0;
|
||||
font-size: 17px;
|
||||
opacity: 0.95;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.alert-icon {
|
||||
font-size: 56px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 32px 24px;
|
||||
}
|
||||
|
||||
.intro-text {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.request-card {
|
||||
background: linear-gradient(135deg, #fff8dc 0%, #fef9f3 100%);
|
||||
border: 2px solid #f0ad4e;
|
||||
border-radius: 8px;
|
||||
padding: 24px;
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.request-card h3 {
|
||||
font-size: 14px;
|
||||
text-transform: uppercase;
|
||||
color: #f0ad4e;
|
||||
margin-bottom: 12px;
|
||||
letter-spacing: 0.5px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.request-card .member-name {
|
||||
font-size: 28px;
|
||||
color: #1a1a1a;
|
||||
font-weight: 700;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.request-card .member-detail {
|
||||
font-size: 15px;
|
||||
color: #555;
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
.request-card .member-detail strong {
|
||||
color: #f0ad4e;
|
||||
}
|
||||
|
||||
.question-box {
|
||||
background: #fff3cd;
|
||||
border-left: 4px solid #f0ad4e;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 24px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.question-box p {
|
||||
font-size: 20px;
|
||||
color: #1a1a1a;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.cta-section {
|
||||
text-align: center;
|
||||
margin: 32px 0;
|
||||
padding: 24px 0;
|
||||
border-top: 2px solid #e0e0e0;
|
||||
border-bottom: 2px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.cta-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
display: inline-block;
|
||||
padding: 18px 56px;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: white;
|
||||
background: linear-gradient(135deg, #7cb342 0%, #558b2f 100%);
|
||||
border-radius: 50px;
|
||||
text-decoration: none;
|
||||
box-shadow: 0 6px 20px rgba(124, 179, 66, 0.4);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.button-icon {
|
||||
font-size: 20px;
|
||||
margin-right: 10px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.info-box {
|
||||
background: #e8f5e9;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.info-box p {
|
||||
margin: 0 0 8px 0;
|
||||
color: #2e7d32;
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.info-box p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.warning-box {
|
||||
background: #f8d7da;
|
||||
border-left: 4px solid #dc3545;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.warning-box p {
|
||||
margin: 0;
|
||||
color: #721c24;
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.warning-box strong {
|
||||
color: #dc3545;
|
||||
}
|
||||
|
||||
.responsibility-box {
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.responsibility-box h3 {
|
||||
font-size: 17px;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 12px;
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.responsibility-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 10px;
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
.responsibility-icon {
|
||||
font-size: 20px;
|
||||
margin-right: 10px;
|
||||
min-width: 24px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.responsibility-text {
|
||||
font-size: 15px;
|
||||
color: #555;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.email-footer {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
background: #f8f9fa;
|
||||
color: #777;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.email-footer p {
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
background: linear-gradient(to right, transparent, #e0e0e0, transparent);
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
body {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.alert-icon {
|
||||
font-size: 48px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.request-card .member-name {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.question-box p {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
padding: 16px 40px;
|
||||
font-size: 18px;
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.responsibility-item {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
body
|
||||
.email-container
|
||||
//- Header
|
||||
.email-header
|
||||
img.header-logo(src=baseurl+'/images/logo.png' alt=nomeapp)
|
||||
h1 🔔 Richiesta di Ammissione
|
||||
p.subtitle Nuovo membro in attesa
|
||||
|
||||
//- Body
|
||||
.email-body
|
||||
//- Intro
|
||||
.intro-text
|
||||
| Ciao <strong>#{nomeInvitante}</strong>,<br>
|
||||
| hai una nuova richiesta di ammissione da confermare!
|
||||
|
||||
//- Card richiesta
|
||||
.request-card
|
||||
h3 👤 Richiesta di Ingresso
|
||||
.member-name #{usernameInvitato}
|
||||
if nomeInvitato
|
||||
.member-detail
|
||||
strong Nome:
|
||||
| #{nomeInvitato}
|
||||
if emailInvitato
|
||||
.member-detail
|
||||
strong Email:
|
||||
| #{emailInvitato}
|
||||
if userprofile && userprofile.profile.resid_str_comune && userprofile.profile.resid_province
|
||||
.member-detail
|
||||
strong Comune Residenza:
|
||||
| #{userprofile.profile.resid_str_comune} (#{userprofile.profile.resid_province})
|
||||
|
||||
//- Domanda di conferma
|
||||
.question-box
|
||||
p 🤔 Confermi di conoscere #{nomeInvitato}?
|
||||
|
||||
//- CTA principale
|
||||
.cta-section
|
||||
.cta-title Ammetti #{usernameInvitato} su #{nomeapp}
|
||||
a.cta-button(href=linkAmmissione target="_blank")
|
||||
span.button-icon ✓
|
||||
| Sì, Confermo
|
||||
|
||||
//- Responsabilità
|
||||
.responsibility-box
|
||||
h3 📋 La tua responsabilità come invitante
|
||||
.responsibility-item
|
||||
span.responsibility-icon 🤝
|
||||
span.responsibility-text
|
||||
strong Conoscenza diretta:
|
||||
| Dovresti ammettere solo persone che conosci personalmente e di cui ti fidi
|
||||
.responsibility-item
|
||||
span.responsibility-icon 🛡️
|
||||
span.responsibility-text
|
||||
strong Fiducia:
|
||||
| L'ammissione si basa sulla fiducia reciproca nella piattaforma su #{nomeapp}
|
||||
.responsibility-item
|
||||
span.responsibility-icon 👥
|
||||
span.responsibility-text
|
||||
strong Supporto:
|
||||
| Come invitante, aiuterai il nuovo membro a integrarsi nella comunità
|
||||
|
||||
//- Info box
|
||||
.info-box
|
||||
p
|
||||
| ✓ Dopo l'ammissione, #{usernameInvitato} potrà completare il profilo
|
||||
p
|
||||
| ✓ Il facilitatore locale valuterà l'abilitazione all'uso dei RIS
|
||||
|
||||
//- Warning box
|
||||
.warning-box
|
||||
p
|
||||
strong ⚠️ Importante:
|
||||
| Se non conosci questa persona o hai dubbi sull'ammissione, ti consigliamo di non procedere. Puoi contattare il facilitatore locale per ulteriori informazioni o semplicemente non cliccare sul pulsante di conferma.
|
||||
|
||||
//- Footer
|
||||
.email-footer
|
||||
.divider
|
||||
p Hai ricevuto questa email perché #{usernameInvitato} ha indicato te come invitante su #{nomeapp}
|
||||
p(style="margin-top: 12px; font-size: 12px;")
|
||||
| #{new Date().getFullYear()} #{nomeapp} - Rete Italiana Scambi Orizzontali
|
||||
p(style="margin-top: 12px; font-size: 12px;")
|
||||
| 🍚 Comunità · Fiducia · Scambi Solidali · Sostenibilità
|
||||
1
emails/defaultSite/reg_chiedi_ammettere_all_invitante/it/subject.pug
Executable file
1
emails/defaultSite/reg_chiedi_ammettere_all_invitante/it/subject.pug
Executable file
@@ -0,0 +1 @@
|
||||
=`🎉 ${name ? ', ' + name : username} chiede di essere ammesso su ${nomeapp} !`
|
||||
471
emails/defaultSite/reg_email_benvenuto_ammesso/it/html.pug
Executable file
471
emails/defaultSite/reg_email_benvenuto_ammesso/it/html.pug
Executable file
@@ -0,0 +1,471 @@
|
||||
doctype html
|
||||
html(lang="it")
|
||||
head
|
||||
meta(charset="UTF-8")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1.0")
|
||||
style(type="text/css").
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.header-logo {
|
||||
width: 80px;
|
||||
height: auto;
|
||||
margin-bottom: 16px;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.email-container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
background: linear-gradient(135deg, #2E7D32 0%, #1B5E20 100%);
|
||||
color: white;
|
||||
padding: 40px 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
margin: 0 0 8px 0;
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.email-header p {
|
||||
margin: 8px 0 0 0;
|
||||
font-size: 16px;
|
||||
opacity: 0.95;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.welcome-icon {
|
||||
font-size: 48px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 24px 20px;
|
||||
}
|
||||
|
||||
.intro-text {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
line-height: 1.7;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.intro-text strong {
|
||||
color: #2E7D32;
|
||||
}
|
||||
|
||||
.welcome-message {
|
||||
background: linear-gradient(135deg, #E8F5E9 0%, #C8E6C9 100%);
|
||||
border-left: 4px solid #2E7D32;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin-bottom: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.welcome-message h2 {
|
||||
color: #1B5E20;
|
||||
font-size: 20px;
|
||||
margin-bottom: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.welcome-message p {
|
||||
color: #2E7D32;
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.credentials-box {
|
||||
background: #f8f9fa;
|
||||
border-left: 4px solid #2E7D32;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.credentials-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #555;
|
||||
margin-bottom: 12px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.credential-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.credential-row:last-child {
|
||||
border-bottom: none;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.credential-label {
|
||||
font-weight: 600;
|
||||
color: #666;
|
||||
min-width: 120px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.credential-value {
|
||||
color: #1a1a1a;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
flex: 1;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.credential-value a {
|
||||
color: #2E7D32;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.credential-value a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.cta-section {
|
||||
margin: 24px 0;
|
||||
padding: 20px 0;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.cta-title {
|
||||
font-size: 19px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.cta-subtitle {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-bottom: 16px;
|
||||
text-align: center;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.cta-buttons-wrapper {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
justify-content: center;
|
||||
align-items: stretch;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
display: inline-block;
|
||||
padding: 16px 28px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
background: linear-gradient(135deg, #2E7D32 0%, #1B5E20 100%);
|
||||
border-radius: 50px;
|
||||
text-decoration: none;
|
||||
box-shadow: 0 4px 12px rgba(46, 125, 50, 0.3);
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
flex: 1;
|
||||
min-width: 160px;
|
||||
max-width: 200px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.cta-button:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 16px rgba(46, 125, 50, 0.4);
|
||||
}
|
||||
|
||||
.cta-button-secondary {
|
||||
background: linear-gradient(135deg, #388E3C 0%, #2E7D32 100%);
|
||||
box-shadow: 0 4px 12px rgba(56, 142, 60, 0.3);
|
||||
}
|
||||
|
||||
.cta-button-secondary:hover {
|
||||
box-shadow: 0 6px 16px rgba(56, 142, 60, 0.4);
|
||||
}
|
||||
|
||||
.cta-button-tertiary {
|
||||
background: linear-gradient(135deg, #66BB6A 0%, #4CAF50 100%);
|
||||
box-shadow: 0 4px 12px rgba(76, 175, 80, 0.3);
|
||||
}
|
||||
|
||||
.cta-button-tertiary:hover {
|
||||
box-shadow: 0 6px 16px rgba(76, 175, 80, 0.4);
|
||||
}
|
||||
|
||||
.button-icon {
|
||||
font-size: 18px;
|
||||
margin-right: 6px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.next-steps {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 24px 0;
|
||||
}
|
||||
|
||||
.next-steps-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #2E7D32;
|
||||
margin-bottom: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.step-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding: 12px;
|
||||
margin-bottom: 12px;
|
||||
background: #f8fdf9;
|
||||
border-radius: 8px;
|
||||
border-left: 3px solid #4CAF50;
|
||||
}
|
||||
|
||||
.step-number {
|
||||
background: linear-gradient(135deg, #4CAF50 0%, #388E3C 100%);
|
||||
color: white;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
margin-right: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.step-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.step-content h3 {
|
||||
font-size: 16px;
|
||||
color: #1B5E20;
|
||||
margin-bottom: 4px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.step-content p {
|
||||
font-size: 14px;
|
||||
color: #555;
|
||||
line-height: 1.5;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.info-box {
|
||||
background: linear-gradient(135deg, #E8F5E9 0%, #C8E6C9 100%);
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
border: 1px solid #A5D6A7;
|
||||
}
|
||||
|
||||
.info-box p {
|
||||
margin: 0;
|
||||
color: #1B5E20;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.info-box strong {
|
||||
color: #2E7D32;
|
||||
}
|
||||
|
||||
.community-note {
|
||||
background: #fff3e0;
|
||||
border-left: 4px solid #FF9800;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.community-note p {
|
||||
color: #E65100;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.email-footer {
|
||||
padding: 20px 16px;
|
||||
text-align: center;
|
||||
background: #f8f9fa;
|
||||
color: #777;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.email-footer p {
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
background: linear-gradient(to right, transparent, #e0e0e0, transparent);
|
||||
margin: 24px 0;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
body {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.email-header p {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 20px 14px;
|
||||
}
|
||||
|
||||
.welcome-message {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.credentials-box {
|
||||
padding: 16px 12px;
|
||||
}
|
||||
|
||||
.credential-row {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.credential-label {
|
||||
margin-bottom: 4px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.credential-value {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.cta-buttons-wrapper {
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
padding: 14px 24px;
|
||||
font-size: 15px;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.step-item {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.step-number {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.step-content h3 {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.step-content p {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
body
|
||||
.email-container
|
||||
.email-header
|
||||
- var baseimg = baseurl + '/';
|
||||
img.header-logo(src=baseimg+"images/logo.png" alt=nomeapp || 'Logo')
|
||||
h1 💚 #{name || username ? ',' : ''} Benvenuto/a nella piattaforma #{nomeapp} 💚 !
|
||||
|
||||
.email-body
|
||||
.welcome-message
|
||||
if ammessoUtente
|
||||
h2 🎉 Il tuo invitante #{nomeInvitante} ti ha ammesso!
|
||||
p Sei ora un membro attivo della Rete Italiana di Scambio Orizzontale
|
||||
p Inizia subito a scoprire beni, servizi e ospitalità nella tua comunità territoriale
|
||||
|
||||
.credentials-box
|
||||
.credentials-title 📋 I tuoi dati di accesso
|
||||
|
||||
if username
|
||||
.credential-row
|
||||
.credential-label Username:
|
||||
.credential-value #{username}
|
||||
|
||||
if emailto
|
||||
.credential-row
|
||||
.credential-label Email:
|
||||
.credential-value #{emailto}
|
||||
|
||||
if forgetpwd
|
||||
.credential-row
|
||||
.credential-label Password:
|
||||
.credential-value
|
||||
| (la password che hai inserito)
|
||||
br
|
||||
a(href=forgetpwd target="_blank") Hai dimenticato la password?
|
||||
|
||||
.cta-section
|
||||
.cta-title 🚀 Accedi e inizia il tuo viaggio
|
||||
.cta-subtitle Scegli come vuoi accedere alla piattaforma
|
||||
|
||||
if strlinksito
|
||||
.cta-buttons-wrapper
|
||||
a.cta-button(href=strlinksito target="_blank")
|
||||
span.button-icon 🌐
|
||||
| Accedi da Web
|
||||
|
||||
.email-footer
|
||||
.divider
|
||||
p 💚 Benvenuto/a nella famiglia #{nomeapp}!
|
||||
p(style="margin-top: 8px;") Hai ricevuto questa email perché sei stato/a ammesso/a nella community di #{nomeapp}
|
||||
p(style="margin-top: 12px; font-size: 12px;")
|
||||
| © #{new Date().getFullYear()} #{nomeapp}
|
||||
1
emails/defaultSite/reg_email_benvenuto_ammesso/it/subject.pug
Executable file
1
emails/defaultSite/reg_email_benvenuto_ammesso/it/subject.pug
Executable file
@@ -0,0 +1 @@
|
||||
=`Benvenuto in ${nomeapp}`
|
||||
342
emails/defaultSite/reg_notifica_all_invitante/it/html.pug
Executable file
342
emails/defaultSite/reg_notifica_all_invitante/it/html.pug
Executable file
@@ -0,0 +1,342 @@
|
||||
doctype html
|
||||
html(lang="it")
|
||||
head
|
||||
meta(charset="UTF-8")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1.0")
|
||||
style(type="text/css").
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.header-logo {
|
||||
width: 120px;
|
||||
height: auto;
|
||||
margin-bottom: 16px;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.email-container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
background: linear-gradient(135deg, #7cb342 0%, #558b2f 100%);
|
||||
color: white;
|
||||
padding: 40px 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
margin: 0 0 8px 0;
|
||||
font-size: 26px;
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.email-header .subtitle {
|
||||
margin: 8px 0 0 0;
|
||||
font-size: 17px;
|
||||
opacity: 0.95;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.success-icon {
|
||||
font-size: 56px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 32px 24px;
|
||||
}
|
||||
|
||||
.intro-text {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.highlight-box {
|
||||
background: #fff8dc;
|
||||
border-left: 4px solid #7cb342;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.highlight-box p {
|
||||
margin: 0;
|
||||
font-size: 17px;
|
||||
color: #1a1a1a;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.member-card {
|
||||
background: linear-gradient(135deg, #f8fdf8 0%, #e8f5e9 100%);
|
||||
border: 2px solid #7cb342;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.member-card h3 {
|
||||
font-size: 14px;
|
||||
text-transform: uppercase;
|
||||
color: #558b2f;
|
||||
margin-bottom: 12px;
|
||||
letter-spacing: 0.5px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.member-card .member-name {
|
||||
font-size: 24px;
|
||||
color: #1a1a1a;
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.member-card .member-detail {
|
||||
font-size: 15px;
|
||||
color: #555;
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
.member-card .member-detail strong {
|
||||
color: #558b2f;
|
||||
}
|
||||
|
||||
.info-box {
|
||||
background: #e8f5e9;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.info-box p {
|
||||
margin: 0 0 8px 0;
|
||||
color: #2e7d32;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.info-box p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.tips-section {
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.tips-section h3 {
|
||||
font-size: 17px;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 12px;
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.tip-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 10px;
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
.tip-icon {
|
||||
font-size: 20px;
|
||||
margin-right: 10px;
|
||||
min-width: 24px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.tip-text {
|
||||
font-size: 16px;
|
||||
color: #555;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.cta-section {
|
||||
text-align: center;
|
||||
margin: 24px 0;
|
||||
padding: 20px 0;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.cta-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
display: inline-block;
|
||||
padding: 16px 48px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
background: linear-gradient(135deg, #7cb342 0%, #558b2f 100%);
|
||||
border-radius: 50px;
|
||||
text-decoration: none;
|
||||
box-shadow: 0 4px 12px rgba(124, 179, 66, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.thank-you-box {
|
||||
background: linear-gradient(135deg, #fff8dc 0%, #fef9f3 100%);
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.thank-you-box p {
|
||||
font-size: 17px;
|
||||
color: #555;
|
||||
line-height: 1.7;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.thank-you-box strong {
|
||||
color: #558b2f;
|
||||
}
|
||||
|
||||
.email-footer {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
background: #f8f9fa;
|
||||
color: #777;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.email-footer p {
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
background: linear-gradient(to right, transparent, #e0e0e0, transparent);
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
body {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.success-icon {
|
||||
font-size: 48px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
padding: 14px 32px;
|
||||
font-size: 16px;
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.member-card .member-name {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.tip-item {
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
body
|
||||
.email-container
|
||||
//- Header
|
||||
.email-header
|
||||
img.header-logo(src=baseurl+'/images/logo.png' alt=nomeapp+' - Rete Italiana Scambio orizzontale')
|
||||
h1 🎉 Il tuo invito è stato accettato!
|
||||
p.subtitle Un nuovo membro si è unito a #{nomeapp}
|
||||
|
||||
//- Body
|
||||
.email-body
|
||||
//- Intro
|
||||
.intro-text
|
||||
| Ciao <strong>#{nomeInvitante}</strong>,<br>
|
||||
| la persona che hai invitato, o che ha usato il tuo username come invitante, si è appena registrata su #{nomeapp}!
|
||||
|
||||
//- Card nuovo membro
|
||||
.member-card
|
||||
h3 👤 Nuovo Membro Registrato
|
||||
.member-name #{nomeInvitato}
|
||||
if emailInvitato
|
||||
.member-detail
|
||||
strong Email:
|
||||
a(href=`mailto:${emailInvitato}` style="color: #667eea; text-decoration: none;") #{emailInvitato}
|
||||
if usernameInvitato
|
||||
.member-detail
|
||||
strong Username:
|
||||
| #{usernameInvitato}
|
||||
|
||||
//- Ringraziamento
|
||||
.thank-you-box
|
||||
p
|
||||
| 🙏 <strong>Grazie per aver contribuito alla crescita di #{nomeapp}!</strong>
|
||||
p
|
||||
| Ogni nuovo membro rende la nostra comunità più forte e ricca di opportunità.
|
||||
| Il tuo invito ha aiutato #{nomeInvitato} a scoprire un nuovo modo di fare economia,
|
||||
| basato su fiducia, comunità e scambi solidali.
|
||||
|
||||
//- Info box
|
||||
.info-box
|
||||
p
|
||||
| ✓ #{nomeInvitato} ha ricevuto un'email di benvenuto con tutte le istruzioni
|
||||
|
||||
//- CTA
|
||||
.cta-section
|
||||
.cta-title Visita la Piattaforma
|
||||
a.cta-button(href=strlinksito target="_blank") Vai su #{nomeapp}
|
||||
|
||||
//- Highlight box
|
||||
.highlight-box
|
||||
p
|
||||
| 🌱 <strong>Costruiamo insieme un'economia più solidale!</strong><br>
|
||||
| Continua a condividere #{nomeapp} con persone di fiducia della tua comunità.
|
||||
| Più siamo, più scambi possibili ci sono per tutti!
|
||||
|
||||
//- Footer
|
||||
.email-footer
|
||||
.divider
|
||||
p Hai ricevuto questa email perché hai invitato #{nomeInvitato} su #{nomeapp} oppure la persona ha usato il tuo username come invitante
|
||||
p(style="margin-top: 12px; font-size: 12px;")
|
||||
| #{new Date().getFullYear()} #{nomeapp}
|
||||
p(style="margin-top: 12px; font-size: 12px;")
|
||||
| 🍚 Comunità · Fiducia · Scambi Solidali · Sostenibilità
|
||||
1
emails/defaultSite/reg_notifica_all_invitante/it/subject.pug
Executable file
1
emails/defaultSite/reg_notifica_all_invitante/it/subject.pug
Executable file
@@ -0,0 +1 @@
|
||||
=`🎉 Il tuo invito è stato accettato su ${nomeapp} da ${name ? name : username} !`
|
||||
404
emails/defaultSite/reg_resend_email_to_verifiyng/it/html.pug
Executable file
404
emails/defaultSite/reg_resend_email_to_verifiyng/it/html.pug
Executable file
@@ -0,0 +1,404 @@
|
||||
doctype html
|
||||
html(lang="it")
|
||||
head
|
||||
meta(charset="UTF-8")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1.0")
|
||||
style(type="text/css").
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.header-logo {
|
||||
width: 80px;
|
||||
height: auto;
|
||||
margin-bottom: 16px;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.email-container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
background: linear-gradient(135deg, #1976D2 0%, #1565C0 100%);
|
||||
color: white;
|
||||
padding: 40px 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
margin: 0 0 8px 0;
|
||||
font-size: 26px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.email-header p {
|
||||
margin: 8px 0 0 0;
|
||||
font-size: 16px;
|
||||
opacity: 0.95;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.verification-icon {
|
||||
font-size: 56px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 24px 20px;
|
||||
}
|
||||
|
||||
.intro-text {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
line-height: 1.7;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.intro-text strong {
|
||||
color: #1976D2;
|
||||
}
|
||||
|
||||
.info-message {
|
||||
background: linear-gradient(135deg, #E3F2FD 0%, #BBDEFB 100%);
|
||||
border-left: 4px solid #1976D2;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin-bottom: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.info-message h2 {
|
||||
color: #1565C0;
|
||||
font-size: 18px;
|
||||
margin-bottom: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.info-message p {
|
||||
color: #1976D2;
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.warning-box {
|
||||
background: #FFF8E1;
|
||||
border-left: 4px solid #FFA000;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.warning-box p {
|
||||
color: #E65100;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.warning-box strong {
|
||||
color: #BF360C;
|
||||
}
|
||||
|
||||
.email-info-box {
|
||||
background: #f8f9fa;
|
||||
border-left: 4px solid #1976D2;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin-bottom: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.email-info-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #555;
|
||||
margin-bottom: 8px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.email-address {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1976D2;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.cta-section {
|
||||
margin: 24px 0;
|
||||
padding: 24px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.cta-title {
|
||||
font-size: 19px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.cta-subtitle {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-bottom: 20px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
display: inline-block;
|
||||
padding: 18px 40px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
background: linear-gradient(135deg, #1976D2 0%, #1565C0 100%);
|
||||
border-radius: 50px;
|
||||
text-decoration: none;
|
||||
box-shadow: 0 4px 12px rgba(25, 118, 210, 0.35);
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.cta-button:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 16px rgba(25, 118, 210, 0.45);
|
||||
}
|
||||
|
||||
.button-icon {
|
||||
font-size: 20px;
|
||||
margin-right: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.link-fallback {
|
||||
margin-top: 20px;
|
||||
padding: 16px;
|
||||
background: #f5f5f5;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.link-fallback p {
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.link-fallback a {
|
||||
font-size: 12px;
|
||||
color: #1976D2;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.expiry-notice {
|
||||
background: linear-gradient(135deg, #FFEBEE 0%, #FFCDD2 100%);
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin: 24px 0;
|
||||
text-align: center;
|
||||
border: 1px solid #EF9A9A;
|
||||
}
|
||||
|
||||
.expiry-notice p {
|
||||
margin: 0;
|
||||
color: #C62828;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.expiry-notice strong {
|
||||
color: #B71C1C;
|
||||
}
|
||||
|
||||
.help-section {
|
||||
background: #FAFAFA;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 24px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.help-section h3 {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
margin-bottom: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.help-section p {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin: 8px 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.help-section a {
|
||||
color: #1976D2;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.help-section a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.security-note {
|
||||
background: #E8F5E9;
|
||||
border-left: 4px solid #4CAF50;
|
||||
border-radius: 8px;
|
||||
padding: 14px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.security-note p {
|
||||
font-size: 13px;
|
||||
color: #2E7D32;
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.email-footer {
|
||||
padding: 20px 16px;
|
||||
text-align: center;
|
||||
background: #f8f9fa;
|
||||
color: #777;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.email-footer p {
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
background: linear-gradient(to right, transparent, #e0e0e0, transparent);
|
||||
margin: 24px 0;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
body {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.email-header p {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 20px 14px;
|
||||
}
|
||||
|
||||
.info-message {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.email-address {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
padding: 16px 32px;
|
||||
font-size: 15px;
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.link-fallback a {
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
body
|
||||
.email-container
|
||||
.email-header
|
||||
- var baseimg = baseurl + '/';
|
||||
h1 ✉️ Verifica il tuo indirizzo email
|
||||
p Conferma la tua email per continuare a usare #{nomeapp}
|
||||
|
||||
.email-body
|
||||
.intro-text
|
||||
| Ciao
|
||||
strong #{name || username}
|
||||
| ! 👋
|
||||
br
|
||||
| Abbiamo ricevuto una richiesta per verificare nuovamente il tuo indirizzo email.
|
||||
|
||||
.info-message
|
||||
h2 📧 Perché devo verificare di nuovo?
|
||||
p Potrebbe essere perché hai cambiato email, per motivi di sicurezza, o perché la verifica precedente è scaduta.
|
||||
p Questa procedura ci aiuta a mantenere sicuro il tuo account.
|
||||
|
||||
if emailto
|
||||
.email-info-box
|
||||
.email-info-title Email da verificare
|
||||
.email-address #{emailto}
|
||||
|
||||
.cta-section
|
||||
.cta-title Conferma il tuo indirizzo email
|
||||
.cta-subtitle Clicca il bottone qui sotto per completare la verifica
|
||||
|
||||
if verifyLink
|
||||
a.cta-button(href=verifyLink target="_blank")
|
||||
span.button-icon ✓
|
||||
| Verifica Email
|
||||
|
||||
.link-fallback
|
||||
p Se il bottone non funziona, copia e incolla questo link nel browser:
|
||||
a(href=verifyLink) #{verifyLink}
|
||||
|
||||
.expiry-notice
|
||||
p ⏰ Questo link scadrà tra
|
||||
strong 24 ore
|
||||
| .
|
||||
p Se non completi la verifica in tempo, dovrai richiedere un nuovo link.
|
||||
|
||||
.warning-box
|
||||
p ⚠️
|
||||
strong Non hai richiesto questa verifica?
|
||||
| Ignora questa email. Il tuo account resterà al sicuro.
|
||||
|
||||
.security-note
|
||||
p 🔒 Per la tua sicurezza: non condividere mai questo link con nessuno. Il team di #{nomeapp} non ti chiederà mai la password via email.
|
||||
|
||||
.help-section
|
||||
h3 Hai bisogno di aiuto?
|
||||
p Non riesci a verificare la tua email?
|
||||
if supportEmail
|
||||
p Contattaci a
|
||||
a(href="mailto:" + supportEmail) #{supportEmail}
|
||||
if strlinksito
|
||||
p Oppure visita la nostra
|
||||
a(href=strlinksito + '/supporto' target="_blank") pagina di supporto
|
||||
|
||||
.email-footer
|
||||
.divider
|
||||
p Hai ricevuto questa email perché è stata richiesta una verifica per il tuo account su #{nomeapp}
|
||||
p(style="margin-top: 8px; font-size: 12px; color: #999;")
|
||||
| Se non hai fatto tu questa richiesta, puoi ignorare questa email.
|
||||
p(style="margin-top: 12px; font-size: 12px;")
|
||||
| © #{new Date().getFullYear()} #{nomeapp}
|
||||
1
emails/defaultSite/reg_resend_email_to_verifiyng/it/subject.pug
Executable file
1
emails/defaultSite/reg_resend_email_to_verifiyng/it/subject.pug
Executable file
@@ -0,0 +1 @@
|
||||
Verifica la tua Email - ${nomeapp}`
|
||||
@@ -55,8 +55,7 @@ html
|
||||
|
||||
|
||||
tr
|
||||
td(class="whitespace", height="10")
|
||||
p
|
||||
td
|
||||
|
||||
- var totalPrice = orders.totalPrice
|
||||
- var note = orders.note
|
||||
@@ -64,6 +63,7 @@ html
|
||||
|
||||
each rec in orders.items
|
||||
- var descr = rec.order.product.productInfo.name
|
||||
- var code = rec.order.product.productInfo.code
|
||||
- var img = dirimg + rec.order.product.productInfo.imagefile
|
||||
- var price = rec.order.price
|
||||
- var after_price = rec.order.after_price
|
||||
@@ -104,6 +104,9 @@ html
|
||||
tr
|
||||
td(class="sectionContentTitle boldhigh", valign="top")
|
||||
p #{descr}
|
||||
tr
|
||||
td(class="sectionContent", valign="top")
|
||||
p Codice: #{code}
|
||||
tr
|
||||
td(class="sectionContent", valign="top")
|
||||
p Prezzo: #{price} € #{after_price}
|
||||
|
||||
@@ -19,7 +19,6 @@ html
|
||||
}
|
||||
|
||||
body(yahoofix, style="background: #ffffff")
|
||||
- var baseimg = baseurl + '/statics/'
|
||||
span(id='body_style', style='display:block')
|
||||
table(cellpadding="10", cellspacing="0", width="600", align="center")
|
||||
tr
|
||||
|
||||
@@ -52,7 +52,7 @@ html
|
||||
if (miordconfirmed)
|
||||
p!= miordconfirmed
|
||||
else
|
||||
p Puoi pertanto venire a ritirarli direttamente in sede, negli orari che ti sono stati indicati.
|
||||
p Puoi venire a ritirarli direttamente in sede, negli orari che ti sono stati indicati.
|
||||
|
||||
p
|
||||
|
||||
@@ -62,6 +62,7 @@ html
|
||||
|
||||
each rec in orders.items
|
||||
- var descr = rec.order.product.productInfo.name
|
||||
- var code = rec.order.product.productInfo.code
|
||||
- var img = dirimg + rec.order.product.productInfo.imagefile
|
||||
- var price = rec.order.product.price
|
||||
- var after_price = rec.order.product.after_price
|
||||
@@ -101,6 +102,9 @@ html
|
||||
tr
|
||||
td(class="sectionContentTitle boldhigh", valign="top")
|
||||
p #{descr}
|
||||
tr
|
||||
td(class="sectionContent", valign="top")
|
||||
p Codice: #{code}
|
||||
tr
|
||||
td(class="sectionContent", valign="top")
|
||||
p Prezzo: #{price} € #{after_price}
|
||||
|
||||
422
emails/invitaamico/it/html.pug
Normal file
422
emails/invitaamico/it/html.pug
Normal file
@@ -0,0 +1,422 @@
|
||||
doctype html
|
||||
html(lang="it")
|
||||
head
|
||||
meta(charset="UTF-8")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1.0")
|
||||
style(type="text/css").
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.header-logo {
|
||||
width: 120px;
|
||||
height: auto;
|
||||
margin-bottom: 16px;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.email-container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
background: linear-gradient(135deg, #7cb342 0%, #558b2f 100%);
|
||||
color: white;
|
||||
padding: 40px 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
margin: 0 0 8px 0;
|
||||
font-size: 26px;
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.email-header .subtitle {
|
||||
margin: 8px 0 0 0;
|
||||
font-size: 17px;
|
||||
opacity: 0.95;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.welcome-icon {
|
||||
font-size: 48px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 32px 24px;
|
||||
}
|
||||
|
||||
.intro-text {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.highlight-box {
|
||||
background: #fff8dc;
|
||||
border-left: 4px solid #7cb342;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.highlight-box p {
|
||||
margin: 0;
|
||||
font-size: 17px;
|
||||
color: #1a1a1a;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.riso-info {
|
||||
background: #fef9f3;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin: 20px 0;
|
||||
border: 1px solid #7cb342;
|
||||
}
|
||||
|
||||
.riso-info h3 {
|
||||
font-size: 16px;
|
||||
color: #558b2f;
|
||||
margin-bottom: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.riso-info p {
|
||||
font-size: 16px;
|
||||
color: #555;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.benefits-list {
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.benefits-list h3 {
|
||||
font-size: 17px;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 12px;
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.benefit-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 8px;
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
.benefit-icon {
|
||||
font-size: 20px;
|
||||
margin-right: 10px;
|
||||
min-width: 24px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.benefit-text {
|
||||
font-size: 16px;
|
||||
color: #555;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.values-section {
|
||||
background: linear-gradient(135deg, #fff8dc 0%, #fef9f3 100%);
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.values-section h3 {
|
||||
font-size: 16px;
|
||||
color: #558b2f;
|
||||
margin-bottom: 12px;
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.value-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
font-size: 16px;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.value-item strong {
|
||||
color: #558b2f;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.cta-section {
|
||||
text-align: center;
|
||||
margin: 24px 0;
|
||||
padding: 20px 0;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.cta-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
display: inline-block;
|
||||
padding: 16px 48px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
background: linear-gradient(135deg, #7cb342 0%, #558b2f 100%);
|
||||
border-radius: 50px;
|
||||
text-decoration: none;
|
||||
box-shadow: 0 4px 12px rgba(210, 105, 30, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.info-box {
|
||||
background: #e8f5e9;
|
||||
border-radius: 8px;
|
||||
padding: 14px;
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.info-box p {
|
||||
margin: 0;
|
||||
color: #2e7d32;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.telegram-box {
|
||||
background: #e3f2fd;
|
||||
border-radius: 8px;
|
||||
padding: 14px;
|
||||
margin: 16px 0;
|
||||
text-align: center;
|
||||
border: 1px solid #64b5f6;
|
||||
}
|
||||
|
||||
.telegram-box p {
|
||||
margin: 0;
|
||||
color: #1976d2;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.telegram-box strong {
|
||||
color: #0d47a1;
|
||||
}
|
||||
|
||||
.link-box {
|
||||
background: #fff3e0;
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
margin: 16px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.link-box a {
|
||||
color: #558b2f;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.email-footer {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
background: #f8f9fa;
|
||||
color: #777;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.email-footer p {
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
background: linear-gradient(to right, transparent, #e0e0e0, transparent);
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
body {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
padding: 14px 32px;
|
||||
font-size: 16px;
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.benefit-item, .value-item {
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
body
|
||||
.email-container
|
||||
//- Header
|
||||
.email-header
|
||||
img.header-logo(src=baseurl+'/images/logo.png' alt='RISO - Rete Italiana Scambio orizzontale')
|
||||
h1 Sei stato invitato ad unirti a #{nomeapp}!
|
||||
p.subtitle Rete Italiana Scambio orizzontale
|
||||
|
||||
//- Body
|
||||
.email-body
|
||||
//- Intro
|
||||
.intro-text
|
||||
if usernameInvitante
|
||||
| <strong>#{usernameInvitante}</strong> ti ha invitato a far parte della comunità RISO, una rete di persone che credono in un'economia basata su fiducia, comunità e scambi solidali.
|
||||
else
|
||||
| Hai ricevuto un invito speciale per unirti alla comunità RISO, una rete di persone che credono in un'economia basata su fiducia, comunità e scambi solidali.
|
||||
|
||||
|
||||
.cta-section
|
||||
.cta-title Unisciti alla Comunità RISO 🍚💚☀️
|
||||
a.cta-button(href=linkRegistrazione target="_blank") Registrati Ora
|
||||
|
||||
//- Messaggio personalizzato
|
||||
if messaggioPersonalizzato
|
||||
.highlight-box
|
||||
p
|
||||
| 💌 <strong>Messaggio da #{usernameInvitante}:</strong><br>
|
||||
| "#{messaggioPersonalizzato}"
|
||||
|
||||
//- Cos'è RISO
|
||||
.riso-info
|
||||
h3 🍚 Cos'è il Progetto RISO?
|
||||
p
|
||||
| RISO è una <strong>rete di comunità territoriali</strong> in tutta Italia dove puoi scambiare beni, servizi e ospitalità con altre persone, usando il <strong>baratto, il dono</strong>, oppure in <strong>RIS</strong>.
|
||||
p
|
||||
| Non è un marketplace commerciale: è una <strong>comunità basata su fiducia e relazioni</strong> reali tra persone che si conoscono e si incontrano.
|
||||
|
||||
//- Benefici
|
||||
.benefits-list
|
||||
h3 ✨ Cosa puoi fare con RISO
|
||||
.benefit-item
|
||||
span.benefit-icon 🔄
|
||||
span.benefit-text Scambiare beni, servizi e ospitalità con baratto, dono, RIS o Euro
|
||||
.benefit-item
|
||||
span.benefit-icon 🤝
|
||||
span.benefit-text Connetterti con la tua comunità territoriale locale (circuito provinciale)
|
||||
.benefit-item
|
||||
span.benefit-icon 💰
|
||||
span.benefit-text Usare i RIS, uno strumento di scambio che parte da zero (nessun debito iniziale!)
|
||||
.benefit-item
|
||||
span.benefit-icon 🌱
|
||||
span.benefit-text Ridurre la dipendenza dall'economia tradizionale e vivere in modo più sostenibile
|
||||
.benefit-item
|
||||
span.benefit-icon 📱
|
||||
span.benefit-text Creare annunci di ciò che offri o cerchi direttamente dall'app
|
||||
.benefit-item
|
||||
span.benefit-icon 🎯
|
||||
span.benefit-text Partecipare a mercatini ed eventi locali organizzati dalla tua comunità
|
||||
|
||||
//- Valori
|
||||
.values-section
|
||||
h3 ⭐ I Valori della Comunità RISO
|
||||
.value-item
|
||||
span.benefit-icon 🤝
|
||||
| <strong>Comunità:</strong> Creiamo legami autentici tra persone
|
||||
.value-item
|
||||
span.benefit-icon ✅
|
||||
| <strong>Fiducia:</strong> Base del nostro sistema di scambio
|
||||
.value-item
|
||||
span.benefit-icon 🚫
|
||||
| <strong>Non speculativo:</strong> il RIS non è una moneta complementare, è un Sistema di Credito Naturale. Non serve a 'comprare' cose, ma a <strong>misurare e scambiare l'energia umana</strong>.
|
||||
.value-item
|
||||
span.benefit-icon 🌍
|
||||
| <strong>Sostenibilità:</strong> Promuoviamo stili di vita sani e naturali
|
||||
.value-item
|
||||
span.benefit-icon 👁️
|
||||
| <strong>Trasparenza:</strong> Tutte le transazioni in RIS sono visibili alla comunità
|
||||
|
||||
//- Info RIS
|
||||
.riso-info
|
||||
h3 💡 Come funzionano i RIS?
|
||||
p
|
||||
| • Non esiste una banca centrale che li crea<br>
|
||||
| • Ogni utente parte da <strong>0 RIS</strong><br>
|
||||
| • Quando ricevi vai in positivo (+), quando spendi vai in negativo (-)<br>
|
||||
| • I facilitatori locali ti abilitano all'uso in base a conoscenza e fiducia<br>
|
||||
| • I circuiti provinciali hanno bilancio sempre a zero (sostenibilità garantita!)
|
||||
|
||||
//- CTA
|
||||
.cta-section
|
||||
.cta-title Unisciti alla Comunità RISO 🍚💚☀️
|
||||
a.cta-button(href=linkRegistrazione target="_blank") Registrati Ora
|
||||
|
||||
//- Info pratica
|
||||
.info-box
|
||||
p
|
||||
| ✓ <strong>Piattaforma Libera e Gratuita</strong><br>
|
||||
| ✓ <strong>Registrazione ad invito</strong> · Necessario username Telegram<br>
|
||||
| ✓ <strong>App web installabile</strong> · Non serve store, installa da browser
|
||||
|
||||
//- Telegram
|
||||
.telegram-box
|
||||
p
|
||||
| 📲 <strong>Unisciti al gruppo Telegram della tua provincia!</strong><br>
|
||||
| Cerca "<strong>Progetto RISO</strong>" su Telegram e trova il gruppo nel messaggio fissato.<br>
|
||||
| Qui organizziamo incontri reali e mercatini. 🍚
|
||||
|
||||
//- Link utile
|
||||
.link-box
|
||||
p 📚 Vuoi saperne di più sul sistema RIS?
|
||||
a(href="https://sicrenacc.info/" target="_blank") Leggi il libro Si.cre.na.C.C →
|
||||
|
||||
//- Footer
|
||||
.email-footer
|
||||
.divider
|
||||
p Hai ricevuto questa email perché #{usernameInvitante || 'un membro della comunità'} ti ha invitato su #{nomeapp}
|
||||
p(style="margin-top: 12px; font-size: 12px;")
|
||||
| #{new Date().getFullYear()} #{nomeapp} - Rete Italiana Scambio orizzontale
|
||||
p(style="margin-top: 8px; font-size: 11px; color: #999;")
|
||||
| Se non sei interessato, puoi semplicemente ignorare questa email.
|
||||
p(style="margin-top: 12px; font-size: 12px;")
|
||||
| 🍚 Comunità · Fiducia · Scambi Solidali · Sostenibilità
|
||||
1
emails/invitaamico/it/subject.pug
Executable file
1
emails/invitaamico/it/subject.pug
Executable file
@@ -0,0 +1 @@
|
||||
=`${usernameInvitante} ti ha invitato su ${nomeapp}`
|
||||
@@ -1,29 +0,0 @@
|
||||
p Ciao #{name},<br>Grazie per aver inviato la tua richiesta di adesione come Sostenitore di Arcadei !
|
||||
p Cordiali Saluti<br>Arcadei
|
||||
|
||||
style(type="text/css").
|
||||
html, body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.divbtn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.btn-lg {
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
background: #027be3 !important;
|
||||
border-radius: 28px;
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
=`Richiesta di Adesione ad Arcadei (${name} ${surname})`
|
||||
@@ -18,232 +18,267 @@
|
||||
- var baseimg = baseurl + '/'
|
||||
doctype html
|
||||
html
|
||||
- if (dataemail.title)
|
||||
head
|
||||
title dataemail.subject
|
||||
head
|
||||
meta(charset="utf-8")
|
||||
meta(name="viewport", content="width=device-width, initial-scale=1")
|
||||
title= dataemail.title || "Email"
|
||||
style.
|
||||
/* embedded CSS */
|
||||
body { margin:0; padding:0; background:#E9F2F9; font-family:Tahoma, Geneva, sans-serif; color:#5b656e; }
|
||||
a { color:#09c; text-decoration:none; }
|
||||
table, td { border-collapse:collapse; }
|
||||
h1,h2,h3,p { margin:0; padding:0; }
|
||||
|
||||
//- import css/scss stylesheets
|
||||
//- these file names will be replace by gulp with proper css file paths
|
||||
link(rel="stylesheet", href="../sass/basic.scss")
|
||||
link(rel="stylesheet", href="../sass/one/styles.scss")
|
||||
.logoContainer { text-align:center; padding:20px 0; }
|
||||
.logoContainer img { max-width:200px; }
|
||||
|
||||
//- embdedded css allowed, but not sass
|
||||
style.
|
||||
.red {
|
||||
background-color: #E84C50;
|
||||
}
|
||||
.testomail { padding:10px; font-size:0.75rem; line-height:1.4; }
|
||||
|
||||
.full-width {
|
||||
width: 100%;
|
||||
}
|
||||
.clpromo {
|
||||
background-color:orange;
|
||||
text-align:center;
|
||||
font-size:1rem;
|
||||
padding:10px;
|
||||
color:#fff;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
.emailContainer {
|
||||
background:#fff;
|
||||
border-radius:10px;
|
||||
padding:20px;
|
||||
margin:20px auto;
|
||||
}
|
||||
|
||||
.sectionArticleImage img {
|
||||
max-width:150px;
|
||||
border:1px solid #ccc;
|
||||
display:block;
|
||||
margin-bottom:10px;
|
||||
}
|
||||
|
||||
.teacher {
|
||||
font-style:italic;
|
||||
font-size:0.75rem;
|
||||
color:#555;
|
||||
}
|
||||
|
||||
.contrib {
|
||||
font-size:0.75rem;
|
||||
font-weight:bold;
|
||||
color:#333;
|
||||
}
|
||||
|
||||
.button a {
|
||||
display:inline-block;
|
||||
padding:10px 20px;
|
||||
background:#f75666;
|
||||
color:#fff !important;
|
||||
text-decoration:none;
|
||||
border-radius:10px;
|
||||
font-size:13px;
|
||||
}
|
||||
|
||||
.button2 a {
|
||||
display:block;
|
||||
padding:12px 20px;
|
||||
background:#0000ff;
|
||||
color:#fff !important;
|
||||
text-decoration:none;
|
||||
border-radius:10px;
|
||||
font-size:1.15rem;
|
||||
}
|
||||
|
||||
.center_img img {
|
||||
display:block;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
.discContainer {
|
||||
background:#fff;
|
||||
border-radius:10px;
|
||||
padding:20px;
|
||||
margin:20px auto;
|
||||
}
|
||||
|
||||
.LinkDisc a {
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
.pDisc:hover {
|
||||
background:#5c8ef4 !important;
|
||||
color:#fff !important;
|
||||
}
|
||||
|
||||
.pDisc {
|
||||
padding:5px 10px;
|
||||
border-radius:10px;
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
.socialMedia {
|
||||
background:#8bafcb;
|
||||
text-align:center;
|
||||
padding:10px 0;
|
||||
}
|
||||
|
||||
.socialMedia img {
|
||||
width:29px;
|
||||
height:auto;
|
||||
border:0;
|
||||
}
|
||||
|
||||
.firma-container {
|
||||
background:#ffffff;
|
||||
padding:15px;
|
||||
text-align:center;
|
||||
border-top:1px solid #e0e0e0;
|
||||
font-size:0.85rem;
|
||||
color:#313a42;
|
||||
}
|
||||
|
||||
.disclaimer-container {
|
||||
background:#f9f9f9;
|
||||
padding:15px;
|
||||
text-align:center;
|
||||
font-size:0.75rem;
|
||||
color:#666;
|
||||
border-top:1px solid #eee;
|
||||
border-bottom:1px solid #eee;
|
||||
}
|
||||
|
||||
.bottom-container {
|
||||
background:#e9f2f9;
|
||||
padding:15px;
|
||||
text-align:center;
|
||||
font-size:0.7rem;
|
||||
color:#999;
|
||||
}
|
||||
|
||||
.whitespace {
|
||||
}
|
||||
|
||||
@media only screen and (max-width:480px) {
|
||||
.button a, .button2 a {
|
||||
font-size:1rem !important;
|
||||
width:100%;
|
||||
}
|
||||
.sectionArticleImage,
|
||||
.column {
|
||||
width:100% !important;
|
||||
display:block !important;
|
||||
}
|
||||
}
|
||||
body(yahoofix)
|
||||
span(id='body_style', style='display:block')
|
||||
table(class="topHeader", cellpadding="0", cellspacing="0", width="100%")
|
||||
- if (dataemail.height_logo)
|
||||
tr
|
||||
td
|
||||
table(cellpadding="0", cellspacing="0", align="center", summary="")
|
||||
tr
|
||||
td.logoContainer
|
||||
a(href=baseurl, title='logo')
|
||||
img.logo(src=baseurl+"/images/logo.png", height=dataemail.height_logo)
|
||||
|
||||
span#body_style(style='display:block')
|
||||
// Header
|
||||
table(width="100%", cellpadding="0", cellspacing="0", align="center")
|
||||
tr
|
||||
td.testomail
|
||||
p!= dataemail.templ.testoheadermail_out
|
||||
td.logoContainer
|
||||
a(href=baseurl)
|
||||
img.logo(src=baseurl+"/images/logo.png", alt="Logo")
|
||||
|
||||
- if (dataemail.templ.options.includes('SHOW_PROMO'))
|
||||
if dataemail.templ.testoheadermail_out
|
||||
tr
|
||||
td.testomail
|
||||
p!= dataemail.templ.testoheadermail_out
|
||||
|
||||
if dataemail.templ.options.includes('SHOW_PROMO')
|
||||
tr
|
||||
td.clpromo
|
||||
p!= dataemail.textpromo
|
||||
|
||||
- if (dataemail.templ.content)
|
||||
table(cellpadding="0", cellspacing="0", width="95%", align="center")
|
||||
// Main Content
|
||||
if dataemail.templ.content
|
||||
tr
|
||||
td.emailContainer
|
||||
p!=dataemail.templ.content
|
||||
if dataemail.templ.img
|
||||
img(src=baseimg + dataemail.templ.img, class="center_img")
|
||||
if dataemail.templ.content2
|
||||
p!=dataemail.templ.content2
|
||||
if dataemail.templ.img2
|
||||
img(src=baseimg + dataemail.templ.img2, class="center_img")
|
||||
|
||||
// Events
|
||||
if dataemail.templ.options.includes('SHOW_EVENTS')
|
||||
each event in arrevents
|
||||
tr
|
||||
td(class="textIniContainer", valign="top")
|
||||
p!=dataemail.templ.content
|
||||
- if (dataemail.templ.img)
|
||||
img(src=baseimg + dataemail.templ.img, alt="", class="myimg")
|
||||
- if (dataemail.templ.content2)
|
||||
p!=dataemail.templ.content2
|
||||
- if (dataemail.templ.img2)
|
||||
img(src=baseimg + dataemail.templ.img2, alt="", class="myimg")
|
||||
|
||||
table(cellpadding="0", cellspacing="0", width="640", align="center")
|
||||
- if (dataemail.templ.options.includes('SHOW_EVENTS'))
|
||||
tr
|
||||
td(class="whitespace", height="10")
|
||||
p
|
||||
tr
|
||||
td(class="emailContainer", valign="top")
|
||||
|
||||
each event in arrevents
|
||||
- var urlevent = baseurl + '/event/' + event.typol + '?eventid=' + event._id
|
||||
- var imgev = event.img_small
|
||||
- var mydate = prettyDate(event.dateTimeStart)
|
||||
unless (imgev)
|
||||
- imgev = event.img
|
||||
- var teacher1 = ''
|
||||
- var teacher2 = ''
|
||||
- var teacher3 = ''
|
||||
- var teacher4 = ''
|
||||
- var contrib = ''
|
||||
- var myclteach = 'q-chip'
|
||||
- if (event.op1[0] && event.op1[0].username !== 'nessuno')
|
||||
- teacher1 = event.op1[0].name + ' ' + event.op1[0].surname
|
||||
- if ((event.op2[0] && event.op2[0].username !== 'nessuno'))
|
||||
- teacher2 = event.op2[0].name + ' ' + event.op2[0].surname
|
||||
- myclteach = 'q-chip2'
|
||||
- if (event.op3[0] && event.op3[0].username !== 'nessuno')
|
||||
- teacher3 = "<br>" . event.op3[0].name + ' ' + event.op3[0].surname
|
||||
- if (event.op4[0] && event.op4[0].username !== 'nessuno')
|
||||
- teacher4 = "<br>" . event.op4[0].name + ' ' + event.op4[0].surname
|
||||
|
||||
- if (event.contrib[0])
|
||||
- contrib = event.contrib[0].label
|
||||
- if (event.contrib[0].showprice)
|
||||
- contrib += ' ' + event.price + ' €'
|
||||
|
||||
|
||||
table(cellpadding="0", cellspacing="0", width="100%", summary="", border="0", align="center")
|
||||
td.emailContainer
|
||||
table(width="100%", cellpadding="0", cellspacing="0")
|
||||
tr
|
||||
td(class="column sectionArticleImage", valign="top")
|
||||
table(cellpadding="0", cellspacing="0", summary="", border="0")
|
||||
- if (event.news)
|
||||
tr
|
||||
td
|
||||
p(class="q-chip row inline no-wrap items-center cltexth5 chipnews shadow-5 glossy text-right bg-red text-white") Novità
|
||||
td.column.sectionArticleImage(width="150")
|
||||
if event.news
|
||||
p.q-chip.bg-red.text-white Novità
|
||||
img(src=baseimg + (event.img_small || event.img), alt=event.title)
|
||||
p.teacher= event.op1[0].name + ' ' + event.op1[0].surname
|
||||
td.column
|
||||
h2.sectionContentTitle= event.title
|
||||
p.sectionContentSubTitle= prettyDate(event.dateTimeStart)
|
||||
p.sectionContent!= event.details
|
||||
if event.contrib.length
|
||||
p.contrib= event.contrib[0].label + (event.contrib[0].showprice ? ' ' + event.price + ' €' : '')
|
||||
table.buttonContainer
|
||||
tr
|
||||
td
|
||||
img(src=baseimg + imgev, alt="", width="150")
|
||||
p(class="teacher") #{teacher1} <br> #{teacher2} #{teacher3} #{teacher4}
|
||||
td(class="column", valign="top")
|
||||
td.button
|
||||
a(href=baseurl + '/event/' + event.typol + '?eventid=' + event._id, target="_blank") Apri l'Evento
|
||||
|
||||
table(cellpadding="0", cellspacing="0", summary="", border="0")
|
||||
tr
|
||||
td(class="sectionContentTitle boldhigh", valign="top")
|
||||
p #{event.title}
|
||||
tr
|
||||
td(class="sectionContentSubTitle", valign="top")
|
||||
p(class="q-chip row inline no-wrap items-center cltexth5 chipnews shadow-5 glossy text-right bg-blue text-white") #{mydate}
|
||||
tr
|
||||
td(class="sectionContent", valign="top")
|
||||
p!= event.details
|
||||
p.contrib= contrib
|
||||
tr
|
||||
td(class="buttonContainer")
|
||||
table(width="50%", cellpadding="0", cellspacing="0", summary="", border="0")
|
||||
tr
|
||||
td(class="button hoverLink")
|
||||
a(href=urlevent, title='Evento', target='_blank') Apri l'Evento
|
||||
tr
|
||||
td.center_img
|
||||
a.button2(href=urlcal, target="_blank") Calendario Eventi
|
||||
|
||||
// Disciplines
|
||||
if dataemail.templ.options.includes('SHOW_DISC')
|
||||
tr
|
||||
td.center
|
||||
h2.cltitle_disc= dataemail.disc_title
|
||||
each disc in dataemail.arrdiscipline
|
||||
tr
|
||||
table(cellpadding="0", cellspacing="0", summary="", border="0", align="center", class="")
|
||||
tr
|
||||
td(class="whitespace", height="10")
|
||||
p
|
||||
tr
|
||||
td.center_img(class="button2 hoverLink")
|
||||
a(href=urlcal, title='Calendario Eventi', target='_blank') Calendario Eventi
|
||||
tr
|
||||
td(class="whitespace", height="10")
|
||||
p
|
||||
|
||||
- if (dataemail.templ.options.includes('SHOW_DISC'))
|
||||
tr
|
||||
td(class="whitespace bg-white", height="20")
|
||||
p(class="bg-white")
|
||||
tr
|
||||
td(class="center")
|
||||
p(class="cltitle_disc") #{dataemail.disc_title}
|
||||
tr
|
||||
td(class="discContainer", valign="top")
|
||||
|
||||
each disc in dataemail.arrdiscipline
|
||||
- var urldisc = baseurl + disc.linkpage
|
||||
- var imgdisc = disc.img_small
|
||||
unless (imgdisc)
|
||||
- imgdisc = disc.img
|
||||
|
||||
table(cellpadding="0", cellspacing="0", width="100%", summary="", border="0", align="center")
|
||||
td.discContainer
|
||||
table(width="100%", cellpadding="0", cellspacing="0")
|
||||
tr
|
||||
td(class="column sectionArticleImage", valign="top")
|
||||
table(cellpadding="0", cellspacing="0", summary="", border="0")
|
||||
tr
|
||||
td
|
||||
img(src=baseimg + imgdisc, alt="", width="150")
|
||||
td(class="column", valign="top")
|
||||
td.column.sectionArticleImage(width="150")
|
||||
img(src=baseimg + (disc.img_small || disc.img), alt=disc.label)
|
||||
td.column
|
||||
p.LinkDisc
|
||||
a(href=baseurl + disc.linkpage, target="_blank")
|
||||
span.pDisc(style=`background-color:`+disc.color)= disc.label
|
||||
p.sectionContent!= disc.description
|
||||
|
||||
table(cellpadding="0", cellspacing="0", summary="", border="0")
|
||||
tr
|
||||
td(class="sectionContentTitle boldhigh center LinkDisc", valign="top")
|
||||
a(href=urldisc, title='Disciplina', target='_blank')
|
||||
p(class="q-chip row inline no-wrap items-center cltexth4 chipnews shadow-5 glossy text-right text-white pDisc", style=`background-color: `+disc.color) #{disc.label}
|
||||
tr
|
||||
td(class="sectionContent", valign="top")
|
||||
p!= disc.description
|
||||
|
||||
tr
|
||||
td(class="whitespace", height="20")
|
||||
p
|
||||
|
||||
- if (dataemail.content_after_events)
|
||||
// Additional Content
|
||||
if dataemail.content_after_events
|
||||
tr
|
||||
table(cellpadding="0", cellspacing="0", summary="", border="0")
|
||||
tr
|
||||
td.testomail
|
||||
p!=dataemail.content_after_events
|
||||
tr
|
||||
td(class="whitespace", height="20")
|
||||
p
|
||||
td.testomail
|
||||
p!=dataemail.content_after_events
|
||||
|
||||
// Social Media
|
||||
table.socialMedia(cellpadding="0", cellspacing="0", width="100%", summary="", border="0", align="center")
|
||||
tr
|
||||
td(class="whitespace", height="5")
|
||||
p
|
||||
tr
|
||||
td
|
||||
table(width="120", cellpadding="0", cellspacing="0", summary="", border="0", align="center")
|
||||
tr
|
||||
- if (dataemail.urlinstagram)
|
||||
td(width="32", align="center")
|
||||
a(href=dataemail.urlinstagram, title='Instagram')
|
||||
img(src=imginstagram, alt="Instagram", width="29")
|
||||
- if (dataemail.urltwitter)
|
||||
td(width="32", align="center")
|
||||
a(href=dataemail.urltwitter, title='Twitter')
|
||||
img(src=imgtwitter, alt="Twitter", width="29")
|
||||
- if (dataemail.urlfb)
|
||||
td(width="32", align="center")
|
||||
a(href=dataemail.urlfb, title='Facebook')
|
||||
img(src=imgfb, alt="Facebook", width="29")
|
||||
- if (dataemail.urlyoutube)
|
||||
td(width="32", align="center")
|
||||
a(href=dataemail.urlyoutube, title='YouTube')
|
||||
img(src=imgyoutube, alt="YouTube", width="29")
|
||||
|
||||
tr
|
||||
td(class="whitespace", height="5")
|
||||
p
|
||||
tr
|
||||
td.socialMedia
|
||||
table(width="120", align="center", cellpadding="0", cellspacing="0")
|
||||
if dataemail.urlinstagram
|
||||
td
|
||||
a(href=dataemail.urlinstagram)
|
||||
img(src=imginstagram, alt="Instagram")
|
||||
if dataemail.urltwitter
|
||||
td
|
||||
a(href=dataemail.urltwitter)
|
||||
img(src=imgtwitter, alt="Twitter")
|
||||
if dataemail.urlfb
|
||||
td
|
||||
a(href=dataemail.urlfb)
|
||||
img(src=imgfb, alt="Facebook")
|
||||
if dataemail.urlyoutube
|
||||
td
|
||||
a(href=dataemail.urlyoutube)
|
||||
img(src=imgyoutube, alt="YouTube")
|
||||
|
||||
// Footer
|
||||
table.footer(cellpadding="0", cellspacing="0", width="100%", summary="", border="0", align="center")
|
||||
tr
|
||||
td(class="whitespace", height="10")
|
||||
p
|
||||
tr
|
||||
td.firma
|
||||
p!= dataemail.firma
|
||||
|
||||
tr
|
||||
td.disclaimer
|
||||
p!= dataemail.disclaimer_out
|
||||
|
||||
tr
|
||||
td.bottom
|
||||
p!= dataemail.disc_bottom_out
|
||||
|
||||
tr
|
||||
td(class="whitespace", height="10")
|
||||
p
|
||||
tr
|
||||
td.firma-container
|
||||
p!= dataemail.firma
|
||||
tr
|
||||
td.disclaimer-container
|
||||
p!= dataemail.disclaimer_out
|
||||
tr
|
||||
td.bottom-container
|
||||
p!= dataemail.disc_bottom_out
|
||||
@@ -1,37 +1,363 @@
|
||||
p Benvenuto #{name} nel portale di #{nomeapp}!
|
||||
p I tuoi dati di accesso da ricordare sono:
|
||||
span Username:
|
||||
strong #{username}<br>
|
||||
span hai dimenticato la Password? :
|
||||
strong <a href=#{forgetpwd} target="_blank">Trovala qui</a><br>
|
||||
span Email:
|
||||
strong #{emailto}<br>
|
||||
p Per confermare la registrazione clicca sul bottone, oppure su questo link: #{strlinkreg}
|
||||
div.divbtn <a href=#{strlinkreg} target="_blank">
|
||||
button.btn.btn-lg Verifica Registrazione</a>
|
||||
|
||||
p Potrai cosi' accedere al sito digitando i tuoi dati di accesso.
|
||||
|
||||
|
||||
style(type="text/css").
|
||||
html, body {
|
||||
padding: 0;
|
||||
doctype html
|
||||
html(lang="it")
|
||||
head
|
||||
meta(charset="UTF-8")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1.0")
|
||||
style(type="text/css").
|
||||
* {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.divbtn {
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.header-logo {
|
||||
width: 120px;
|
||||
height: auto;
|
||||
margin-bottom: 16px;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.email-container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
background: linear-gradient(135deg, #7cb342 0%, #558b2f 100%);
|
||||
color: white;
|
||||
padding: 40px 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
margin: 0 0 8px 0;
|
||||
font-size: 26px;
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.email-header .subtitle {
|
||||
margin: 8px 0 0 0;
|
||||
font-size: 17px;
|
||||
opacity: 0.95;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.welcome-icon {
|
||||
font-size: 56px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 32px 24px;
|
||||
}
|
||||
|
||||
.intro-text {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.cta-section {
|
||||
text-align: center;
|
||||
margin: 24px 0;
|
||||
padding: 20px 0;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.cta-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
display: inline-block;
|
||||
padding: 16px 48px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
background: linear-gradient(135deg, #7cb342 0%, #558b2f 100%);
|
||||
border-radius: 50px;
|
||||
text-decoration: none;
|
||||
box-shadow: 0 4px 12px rgba(124, 179, 66, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.button-icon {
|
||||
font-size: 18px;
|
||||
margin-right: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.alternative-link {
|
||||
margin-top: 16px;
|
||||
font-size: 13px;
|
||||
color: #777;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.alternative-link a {
|
||||
color: #558b2f;
|
||||
text-decoration: none;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.verification-process {
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
padding: 24px 20px;
|
||||
margin: 24px 0;
|
||||
}
|
||||
|
||||
.process-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.process-title .icon {
|
||||
font-size: 24px;
|
||||
margin-right: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.process-steps {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.process-step {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 20px;
|
||||
padding: 16px;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
border-left: 4px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.process-step.active {
|
||||
border-left-color: #7cb342;
|
||||
background: linear-gradient(135deg, #f8fdf8 0%, #e8f5e9 100%);
|
||||
}
|
||||
|
||||
.step-badge {
|
||||
min-width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
background: #e0e0e0;
|
||||
color: #666;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.btn-lg {
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
font-weight: 700;
|
||||
font-size: 18px;
|
||||
margin-right: 16px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.process-step.active .step-badge {
|
||||
background: linear-gradient(135deg, #7cb342 0%, #558b2f 100%);
|
||||
color: white;
|
||||
background: #027be3 !important;
|
||||
border-radius: 28px;
|
||||
}
|
||||
|
||||
.step-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.step-content h4 {
|
||||
font-size: 16px;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 6px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.step-content p {
|
||||
font-size: 15px;
|
||||
color: #555;
|
||||
line-height: 1.5;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.info-note {
|
||||
background: #fff8dc;
|
||||
border-left: 4px solid #7cb342;
|
||||
border-radius: 8px;
|
||||
padding: 14px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.info-note p {
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
color: #1a1a1a;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.info-note strong {
|
||||
color: #558b2f;
|
||||
}
|
||||
|
||||
.email-footer {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
background: #f8f9fa;
|
||||
color: #777;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.email-footer p {
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
background: linear-gradient(to right, transparent, #e0e0e0, transparent);
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
body {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.welcome-icon {
|
||||
font-size: 48px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
padding: 14px 32px;
|
||||
font-size: 16px;
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.verification-process {
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.process-step {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.step-badge {
|
||||
min-width: 36px;
|
||||
height: 36px;
|
||||
font-size: 16px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.step-content h4 {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.step-content p {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
body
|
||||
.email-container
|
||||
//- Header
|
||||
.email-header
|
||||
- var baseimg = baseurl + '/';
|
||||
img.header-logo(src=baseimg+"images/logo.png" alt=nomeapp || 'RISO')
|
||||
h1 Benvenuto/a #{name ? name : username} su #{nomeapp}!
|
||||
p.subtitle Rete Italiana Scambio Orizzontale
|
||||
|
||||
//- Body
|
||||
.email-body
|
||||
if !verified_email
|
||||
.intro-text
|
||||
| Per iniziare il tuo percorso in RISO, verifica il tuo indirizzo email cliccando sul pulsante qui sotto.
|
||||
|
||||
.cta-section
|
||||
.cta-title 🔐 Verifica il tuo account
|
||||
|
||||
if strlinkreg
|
||||
a.cta-button(href=strlinkreg target="_blank")
|
||||
span.button-icon ✓
|
||||
| Verifica Email
|
||||
|
||||
.alternative-link
|
||||
| Oppure copia e incolla questo link nel tuo browser:
|
||||
br
|
||||
a(href=strlinkreg target="_blank") #{strlinkreg}
|
||||
|
||||
//- Processo di verifica
|
||||
.verification-process
|
||||
.process-title
|
||||
span.icon 🌱
|
||||
| Il tuo percorso di ingresso in RISO
|
||||
|
||||
.process-steps
|
||||
.process-step
|
||||
.step-badge 1
|
||||
.step-content
|
||||
h4 ✓ Verifica la tua email
|
||||
p Clicca sul pulsante sopra per confermare il tuo indirizzo email.
|
||||
|
||||
.process-step.active
|
||||
.step-badge 2
|
||||
.step-content
|
||||
h4 ⏳ In attesa di ammissione
|
||||
p Il tuo invitante vedrà la tua richiesta. Riceverai un'email appena sarai ammesso!
|
||||
|
||||
.process-step
|
||||
.step-badge 3
|
||||
.step-content
|
||||
h4 🎯 Completa il tuo profilo
|
||||
p Una volta ammesso, potrai completare il tuo profilo e iniziare a fare parte della comunità RISO.
|
||||
|
||||
.process-step
|
||||
.step-badge 4
|
||||
.step-content
|
||||
h4 🍚 Inizia a scambiare
|
||||
p Crea annunci, scambia beni e servizi, e partecipa agli eventi della tua comunità locale!
|
||||
|
||||
.info-note
|
||||
p
|
||||
strong 💡 Suggerimento:
|
||||
| Se dovessero passare più di 24 ore senza ammissione, contatta il tuo invitante per ricordargli di approvarti.
|
||||
|
||||
//- Footer
|
||||
.email-footer
|
||||
.divider
|
||||
p Hai ricevuto questa email perché ti sei registrato su #{nomeapp || 'RISO'}
|
||||
p(style="margin-top: 12px; font-size: 12px;")
|
||||
| #{new Date().getFullYear()} #{nomeapp || 'RISO'} - Rete Italiana Scambi Orizzontali
|
||||
p(style="margin-top: 8px; font-size: 11px; color: #999;")
|
||||
| Se non hai richiesto questa registrazione, puoi semplicemente ignorare questa email.
|
||||
p(style="margin-top: 12px; font-size: 12px;")
|
||||
| 🍚 Comunità · Fiducia · Scambi Solidali · Sostenibilità
|
||||
@@ -1,39 +0,0 @@
|
||||
p Welcome #{name} to the portal #{nomeapp}!
|
||||
p Your access data to remember are:
|
||||
span Username:
|
||||
strong #{username}<br>
|
||||
span Forgot your Password? :
|
||||
strong <a href=#{forgetpwd} target="_blank">Find it here</a><br>
|
||||
span Email:
|
||||
strong #{emailto}<br>
|
||||
p To confirm the registration click on the button:
|
||||
div.divbtn <a href=#{strlinkreg} target="_blank">
|
||||
button.btn.btn-lg Verify Registration</a>
|
||||
|
||||
|
||||
p You can then access your personal area by clicking on LOGIN and filling in all the STEPS required by :
|
||||
strong "Step by Step Guide" !<br>
|
||||
|
||||
|
||||
style(type="text/css").
|
||||
html, body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.divbtn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.btn-lg {
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
background: #027be3 !important;
|
||||
border-radius: 28px;
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
=`Confirm Registration to ${nomeapp}`
|
||||
@@ -1,38 +0,0 @@
|
||||
p ¡Bienvenido #{name} al portal #{nomeapp}!
|
||||
p Sus datos de acceso a recordar son:
|
||||
Nombre Usuario:
|
||||
strong #{username}<br>
|
||||
span ¿Olvidaste tu contraseña? :
|
||||
strong <a href=#{forgetpwd} target="_blank">Encuéntrelo aquí</a><br>
|
||||
span Email:
|
||||
strong #{emailto}<br>
|
||||
p Para confirmar el registro haz clic en el botón, o aquì #{strlinkreg}:
|
||||
div.divbtn <a href=#{strlinkreg} target="_blank">
|
||||
button.btn.btn-lg Verificar registro</a>
|
||||
|
||||
p A continuación, puede acceder a su área personal haciendo clic en INICIAR SESIÓN y rellenando todos los PASOS requeridos por :
|
||||
strong "Guía paso a paso"!<br>
|
||||
|
||||
|
||||
style(type="text/css").
|
||||
html, body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.divbtn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.btn-lg {
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
background: #027be3 !important;
|
||||
border-radius: 28px;
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
=`Confirmar registro a ${nomeapp}`
|
||||
@@ -1,43 +0,0 @@
|
||||
p Bienvenue #{name} sur le portail de #{nomeapp} !
|
||||
p Vos identifiants de connexion à retenir sont :
|
||||
span Username:
|
||||
strong #{username}<br>
|
||||
span avez-vous oublié votre mot de passe ? :
|
||||
strong <a href=#{forgetpwd} target="_blank">Essayez ici</a><br>
|
||||
span Email:
|
||||
strong #{emailto}<br>
|
||||
p Cliquez sur le bouton pour confirmer votre inscription ou cliquez ici #{strlinkreg}:
|
||||
div.divbtn <a href=#{strlinkreg} target="_blank">
|
||||
button.btn.btn-lg Vérifier l'enregistrement</a>
|
||||
|
||||
p Vous pouvez ensuite accéder à votre espace personnel en entrant votre nom d'utilisateur et votre mot de passe et en cliquant sur
|
||||
strong ENTREZ<br>
|
||||
|
||||
p Donc, une fois que vous avez vérifié votre inscription, connectez-vous au site et
|
||||
strong COMPLÉTER TOUTES LES ÉTAPES
|
||||
de la portée du "Guide pas-à-pas" via ce lien:<br>
|
||||
span <a href=#{strlinksito} target="_blank">#{strlinksito}</a>
|
||||
|
||||
|
||||
style(type="text/css").
|
||||
html, body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.divbtn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.btn-lg {
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
background: #027be3 !important;
|
||||
border-radius: 28px;
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
=`Confirmer l'inscription à ${nomeapp}`
|
||||
@@ -1,43 +0,0 @@
|
||||
p Benvenuto #{name} nel portale di #{nomeapp}!
|
||||
p I tuoi dati di accesso da ricordare sono:
|
||||
span Username:
|
||||
strong #{username}<br>
|
||||
span hai dimenticato la Password? :
|
||||
strong <a href=#{forgetpwd} target="_blank">Trovala qui</a><br>
|
||||
span Email:
|
||||
strong #{emailto}<br>
|
||||
p Per confermare la registrazione clicca sul bottone, oppure <a href=#{strlinkreg} target="_blank">CLICCA QUI</a>
|
||||
div.divbtn <a href=#{strlinkreg} target="_blank">
|
||||
button.btn.btn-lg Verifica Registrazione</a>
|
||||
|
||||
p Potrai cosi' accedere alla tua area personale inserendo lo username e la password e cliccando su
|
||||
strong ACCEDI <br>
|
||||
|
||||
p Pertanto una volta Verificata la Registrazione, accedi al sito e
|
||||
strong COMPLETA TUTTI I PASSI
|
||||
span della "Guida Passo Passo" tramite questo Link:<br>
|
||||
span <a href=#{strlinksito} target="_blank">#{strlinksito}</a>
|
||||
|
||||
|
||||
style(type="text/css").
|
||||
html, body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.divbtn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.btn-lg {
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
background: #027be3 !important;
|
||||
border-radius: 28px;
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
=`Confermare la Registrazione a ${nomeapp}`
|
||||
@@ -1,43 +0,0 @@
|
||||
p Bem-vindo #{name} ao portal de #{nomeapp}!
|
||||
p Os seus dados de login a lembrar são:
|
||||
span Username:
|
||||
strong #{username}<br>
|
||||
span você esqueceu sua senha? :
|
||||
strong <a href=##{forgetpwd} target="_blank">Encontre-o aqui</a>>br>
|
||||
span Email:
|
||||
strong #{emailto}<br>
|
||||
p Clique no botão para confirmar o seu registo ou clique aqui #{strlinkreg}:
|
||||
div.divbtn <a href=#{strlinkreg} target="_blank">
|
||||
button.btn.btn-lg Verificação de registro</a>
|
||||
|
||||
p Você pode então acessar sua área pessoal digitando seu nome de usuário e senha e clicando em
|
||||
strong ENTRAR <br>
|
||||
|
||||
p Então, uma vez verificada a sua inscrição, inicie a sessão no site e
|
||||
strong COMPLETA TODOS OS PASSOS
|
||||
span do "Guia Passo a Passo" através deste link:<br>
|
||||
span <a href=#{strlinksito} target="_blank">#{strlinksito}</a>
|
||||
|
||||
|
||||
style(type="text/css").
|
||||
html, body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.divbtn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.btn-lg {
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
background: #027be3 !important;
|
||||
border-radius: 28px;
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
=`Confirme o registo em ${nomeapp}`
|
||||
@@ -1,44 +0,0 @@
|
||||
p Dobrodošli #{name} na portalu #{nomeapp}!
|
||||
p Vaši podatki za dostop so:
|
||||
span Username:
|
||||
strong #{username}<br>
|
||||
span ste pozabili geslo? :
|
||||
strong <a href=#{forgetpwd} target="_blank">Poiščite tukaj</a><br>
|
||||
span Email:
|
||||
strong #{emailto}<br>
|
||||
p Za potrditev registracije kliknite na gumb ali kliknite tukaj: #{strlinkreg}
|
||||
div.divbtn <a href=#{strlinkreg} target="_blank">
|
||||
button.btn.btn-lg Preveri registracijo</a>
|
||||
|
||||
p Tako boste lahko dostopali do svojega osebnega območja, tako da vnesete uporabniško ime in geslo in kliknete
|
||||
strong PRIJAVA <br>
|
||||
|
||||
|
||||
p Potem ko je registracija preverjena, obiščite spletno mesto in
|
||||
strong IZPOLNITE VSE KORAKE
|
||||
span "Vodnika po korakih" prek te povezave:<br>
|
||||
span <a href=#{strlinksito} target="_blank">#{strlinksito}</a>
|
||||
|
||||
|
||||
style(type="text/css").
|
||||
html, body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.divbtn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.btn-lg {
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
background: #027be3 !important;
|
||||
border-radius: 28px;
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
=`Potrdi registracijo za ${nomeapp}`
|
||||
@@ -1,26 +1,128 @@
|
||||
p Ciao #{name},
|
||||
p #{nomeapp} recentemente ha ricevuto una richiesta per una password dimenticata.
|
||||
|
||||
p Per cambiare la tua password di #{nomeapp}
|
||||
p <a href=#{strlinksetpassword} target="_blank">Clicca QUI</a>
|
||||
span Oppure inserisci il codice
|
||||
span.grande #{tokenforgot_code}
|
||||
span sulla APP
|
||||
p
|
||||
p P.S: Se non sei stato tu a richiedere questo cambiamento, non hai bisogno di fare niente.
|
||||
p Questo link scadrà tra 4 ore.<br>
|
||||
|
||||
p Cordiali Saluti
|
||||
p Supporto #{nomeapp}
|
||||
|
||||
style(type="text/css").
|
||||
html, body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.grande {
|
||||
font-size: 1.25rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
doctype html
|
||||
html(lang="it")
|
||||
head
|
||||
meta(charset="UTF-8")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1.0")
|
||||
title Recupera Password - #{nomeapp}
|
||||
|
||||
body(style="margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); background-color: #f5f7fa;")
|
||||
|
||||
// Container Principale
|
||||
table(role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 40px 20px;")
|
||||
tr
|
||||
td(align="center")
|
||||
|
||||
// Card Email
|
||||
table(role="presentation" cellspacing="0" cellpadding="0" border="0" width="600" style="max-width: 600px; background: #ffffff; border-radius: 24px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.16); overflow: hidden;")
|
||||
|
||||
// Header con Icona
|
||||
tr
|
||||
td(style="background: linear-gradient(to bottom, rgba(103, 126, 234, 0.08), transparent); padding: 40px 32px 32px; text-align: center; border-bottom: 1px solid rgba(0, 0, 0, 0.06);")
|
||||
table(role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%")
|
||||
tr
|
||||
td(align="center")
|
||||
// Icona
|
||||
div(style="width: 100px; height: 100px; margin: 0 auto 20px; background: linear-gradient(135deg, rgba(25, 118, 210, 0.15), rgba(38, 166, 154, 0.15)); border-radius: 50%; display: flex; align-items: center; justify-content: center;")
|
||||
span(style="font-size: 48px; color: #1976d2;") 🔐
|
||||
|
||||
// Titolo
|
||||
h1(style="margin: 0 0 12px; font-size: 28px; font-weight: 600; color: #1a1a1a; line-height: 1.3;") Recupera la tua Password
|
||||
p(style="margin: 0; font-size: 16px; color: #666; line-height: 1.5;")
|
||||
| Ciao
|
||||
strong(style="color: #333;") #{name}
|
||||
| , abbiamo ricevuto una richiesta per reimpostare la tua password
|
||||
|
||||
// Contenuto Principale
|
||||
tr
|
||||
td(style="padding: 32px;")
|
||||
|
||||
// Messaggio
|
||||
p(style="margin: 0 0 24px; font-size: 16px; color: #333; line-height: 1.6;")
|
||||
| Per cambiare la tua password di
|
||||
strong #{nomeapp}
|
||||
| , puoi utilizzare uno dei seguenti metodi:
|
||||
|
||||
// Metodo 1: Bottone Link
|
||||
table(role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="margin-bottom: 32px;")
|
||||
tr
|
||||
td(style="background: linear-gradient(to right, rgba(25, 118, 210, 0.08), transparent); padding: 24px; border-radius: 16px; border: 1px solid rgba(25, 118, 210, 0.15);")
|
||||
p(style="margin: 0 0 16px; font-size: 14px; font-weight: 600; color: #1976d2; text-transform: uppercase; letter-spacing: 0.5px;") ✨ Metodo 1: Link Diretto
|
||||
|
||||
// Bottone CTA
|
||||
table(role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%")
|
||||
tr
|
||||
td(align="center" style="padding: 8px 0;")
|
||||
a(href=strlinksetpassword target="_blank" style="display: inline-block; padding: 16px 48px; background: linear-gradient(135deg, #1976d2, #42a5f5); color: #ffffff; text-decoration: none; border-radius: 12px; font-size: 16px; font-weight: 600; box-shadow: 0 4px 16px rgba(25, 118, 210, 0.3);")
|
||||
| 🔓 Reimposta Password
|
||||
|
||||
p(style="margin: 16px 0 0; font-size: 13px; color: #666; text-align: center;")
|
||||
| Il link è valido per
|
||||
strong(style="color: #f2c037;") 4 ore
|
||||
|
||||
// Divisore
|
||||
table(role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="margin: 24px 0;")
|
||||
tr
|
||||
td(style="position: relative; text-align: center;")
|
||||
div(style="position: relative; height: 1px; background: linear-gradient(to right, transparent, rgba(0, 0, 0, 0.12), transparent);")
|
||||
span(style="position: relative; top: -12px; display: inline-block; padding: 4px 16px; background: #ffffff; color: #666; font-size: 14px; font-weight: 500; border-radius: 12px; border: 1px solid rgba(0, 0, 0, 0.08);") oppure
|
||||
|
||||
// Metodo 2: Codice
|
||||
table(role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="margin-bottom: 24px;")
|
||||
tr
|
||||
td(style="background: linear-gradient(to right, rgba(33, 186, 69, 0.08), transparent); padding: 24px; border-radius: 16px; border: 1px solid rgba(33, 186, 69, 0.15);")
|
||||
p(style="margin: 0 0 16px; font-size: 14px; font-weight: 600; color: #21ba45; text-transform: uppercase; letter-spacing: 0.5px;") 🔢 Metodo 2: Codice di Verifica
|
||||
|
||||
p(style="margin: 0 0 12px; font-size: 15px; color: #333;") Inserisci questo codice nell'app:
|
||||
|
||||
// Codice Box
|
||||
div(style="background: #ffffff; border: 2px dashed #21ba45; border-radius: 12px; padding: 20px; text-align: center; margin: 16px 0;")
|
||||
div(style="font-size: 36px; font-weight: 700; color: #1976d2; letter-spacing: 8px; font-family: 'Courier New', monospace;") #{tokenforgot_code}
|
||||
|
||||
p(style="margin: 12px 0 0; font-size: 13px; color: #666; text-align: center;")
|
||||
| Copia e incolla il codice nell'app per confermare
|
||||
|
||||
// Warning Box
|
||||
table(role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%")
|
||||
tr
|
||||
td(style="background: rgba(242, 192, 55, 0.1); padding: 16px; border-radius: 12px; border-left: 4px solid #f2c037;")
|
||||
p(style="margin: 0; font-size: 14px; color: #666; line-height: 1.6;")
|
||||
strong(style="color: #333;") ⚠️ Importante:
|
||||
br
|
||||
| Se non sei stato tu a richiedere questo cambiamento, ignora questa email. La tua password rimarrà invariata.
|
||||
|
||||
// Footer
|
||||
tr
|
||||
td(style="background: linear-gradient(to top, rgba(0, 0, 0, 0.02), transparent); padding: 32px; text-align: center; border-top: 1px solid rgba(0, 0, 0, 0.06);")
|
||||
p(style="margin: 0 0 8px; font-size: 15px; color: #333; font-weight: 600;") Cordiali Saluti
|
||||
p(style="margin: 0 0 20px; font-size: 15px; color: #1976d2; font-weight: 600;")
|
||||
| Supporto #{nomeapp}
|
||||
|
||||
// Info Footer
|
||||
p(style="margin: 0; font-size: 13px; color: #999; line-height: 1.6;")
|
||||
| Questa è una email automatica, per favore non rispondere.
|
||||
br
|
||||
| © #{new Date().getFullYear()} #{nomeapp}. Tutti i diritti riservati.
|
||||
|
||||
// Versione Mobile (per client email che non supportano media queries)
|
||||
table(role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="max-width: 600px; margin: 0 auto; display: none;")
|
||||
tr
|
||||
td
|
||||
style(type="text/css").
|
||||
@media only screen and (max-width: 600px) {
|
||||
table[class="mobile-responsive"] {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
td[class="mobile-padding"] {
|
||||
padding: 20px 16px !important;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 24px !important;
|
||||
}
|
||||
|
||||
.code-box {
|
||||
font-size: 28px !important;
|
||||
letter-spacing: 4px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,307 @@
|
||||
p Ciao #{name},
|
||||
p Hai ricevuto
|
||||
strong #{qty} #{symbol}
|
||||
if groupDestoContoCom
|
||||
| sul conto
|
||||
strong #{groupDestoContoCom}
|
||||
span da parte di #{mittente} in data #{transactionDate} sul
|
||||
strong #{nomecircuito} !
|
||||
if causalDest
|
||||
p <br>
|
||||
p Descrizione: #{causalDest}
|
||||
if causale
|
||||
p <br>
|
||||
p Commento di #{mittente}: #{causale}
|
||||
p <br>
|
||||
p Apri
|
||||
strong <a href=#{strlinksito} target="_blank">#{nomeapp}</a>
|
||||
span per vedere il tuo nuovo saldo.
|
||||
p <br>
|
||||
p Cordiali Saluti
|
||||
p Supporto #{nomeapp}
|
||||
|
||||
style(type="text/css").
|
||||
html, body {
|
||||
padding: 0;
|
||||
doctype html
|
||||
html(lang="it")
|
||||
head
|
||||
meta(charset="UTF-8")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1.0")
|
||||
style(type="text/css").
|
||||
* {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 4px; /* Imposta il margine a 0 per i paragrafi */
|
||||
}
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.header-logo {
|
||||
width: 120px;
|
||||
height: auto;
|
||||
margin-bottom: 16px;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.email-container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
background: linear-gradient(135deg, #7cb342 0%, #558b2f 100%);
|
||||
color: white;
|
||||
padding: 40px 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
margin: 0 0 8px 0;
|
||||
font-size: 26px;
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.email-header .subtitle {
|
||||
margin: 8px 0 0 0;
|
||||
font-size: 17px;
|
||||
opacity: 0.95;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.money-icon {
|
||||
font-size: 56px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 32px 24px;
|
||||
}
|
||||
|
||||
.intro-text {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.transaction-card {
|
||||
background: linear-gradient(135deg, #f8fdf8 0%, #e8f5e9 100%);
|
||||
border: 2px solid #7cb342;
|
||||
border-radius: 8px;
|
||||
padding: 24px;
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.transaction-amount {
|
||||
font-size: 42px;
|
||||
color: #558b2f;
|
||||
font-weight: 700;
|
||||
margin-bottom: 12px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.transaction-label {
|
||||
font-size: 14px;
|
||||
text-transform: uppercase;
|
||||
color: #558b2f;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.5px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.transaction-detail {
|
||||
font-size: 15px;
|
||||
color: #555;
|
||||
margin: 8px 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.transaction-detail strong {
|
||||
color: #558b2f;
|
||||
}
|
||||
|
||||
.divider-line {
|
||||
height: 1px;
|
||||
background: #c8e6c9;
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
.highlight-box {
|
||||
background: #fff8dc;
|
||||
border-left: 4px solid #7cb342;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.highlight-box p {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
color: #1a1a1a;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.highlight-box .label {
|
||||
font-size: 13px;
|
||||
text-transform: uppercase;
|
||||
color: #558b2f;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.5px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.cta-section {
|
||||
text-align: center;
|
||||
margin: 24px 0;
|
||||
padding: 20px 0;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.cta-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
display: inline-block;
|
||||
padding: 16px 48px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
background: linear-gradient(135deg, #7cb342 0%, #558b2f 100%);
|
||||
border-radius: 50px;
|
||||
text-decoration: none;
|
||||
box-shadow: 0 4px 12px rgba(124, 179, 66, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.info-box {
|
||||
background: #e8f5e9;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.info-box p {
|
||||
margin: 0;
|
||||
color: #2e7d32;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.email-footer {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
background: #f8f9fa;
|
||||
color: #777;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.email-footer p {
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
background: linear-gradient(to right, transparent, #e0e0e0, transparent);
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
body {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.email-header {
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
||||
.email-header h1 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.money-icon {
|
||||
font-size: 48px;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.transaction-amount {
|
||||
font-size: 36px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
padding: 14px 32px;
|
||||
font-size: 16px;
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
.grande {
|
||||
font-size: 1.25rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
body
|
||||
.email-container
|
||||
//- Header
|
||||
.email-header
|
||||
img.header-logo(src=baseurl+'/images/logo.png' alt='RISO - Rete Italiana Scambio Orizzontale')
|
||||
h1 Ciao <strong>#{username}</strong>, Hai ricevuto dei #{symbol}!
|
||||
p.subtitle Nuova transazione sul #{nomecircuito}
|
||||
|
||||
//- Body
|
||||
.email-body
|
||||
//- Intro
|
||||
|
||||
//- Transaction card
|
||||
.transaction-card
|
||||
.transaction-label Importo Ricevuto
|
||||
.transaction-amount +#{qty} #{symbol}
|
||||
|
||||
.divider-line
|
||||
|
||||
.transaction-detail(style="font-size: 18px; margin-top: 12px;")
|
||||
strong Nuovo Saldo:
|
||||
span(style="color: #558b2f; font-weight: 700; font-size: 20px;") #{saldoAttuale} #{symbol}
|
||||
|
||||
.transaction-detail
|
||||
strong Da:
|
||||
| #{mittente}
|
||||
|
||||
.transaction-detail
|
||||
strong Data:
|
||||
| #{transactionDate}
|
||||
|
||||
if groupDestoContoCom
|
||||
.transaction-detail
|
||||
strong Conto:
|
||||
| #{groupDestoContoCom}
|
||||
|
||||
.transaction-detail
|
||||
strong Circuito:
|
||||
| #{nomecircuito}
|
||||
|
||||
//- Descrizione
|
||||
if causalDest
|
||||
.highlight-box
|
||||
.label 📝 Descrizione
|
||||
p #{causalDest}
|
||||
|
||||
//- Commento mittente
|
||||
if causale
|
||||
.highlight-box
|
||||
.label 💬 Commento di #{mittente}
|
||||
p "#{causale}"
|
||||
|
||||
//- Info box
|
||||
.info-box
|
||||
p
|
||||
| ✓ La transazione è stata registrata con successo<br>
|
||||
| ✓ Il tuo saldo è stato aggiornato
|
||||
|
||||
//- CTA
|
||||
.cta-section
|
||||
.cta-title Accedi alla App
|
||||
a.cta-button(href=strlinksito target="_blank") Apri #{nomeapp}
|
||||
|
||||
//- Footer
|
||||
.email-footer
|
||||
.divider
|
||||
p Hai ricevuto questa email perché hai ricevuto una transazione su #{nomeapp}
|
||||
p(style="margin-top: 12px; font-size: 12px;")
|
||||
| #{new Date().getFullYear()} #{nomeapp} - Rete Italiana Scambi Orizzontali
|
||||
p(style="margin-top: 12px; font-size: 12px;")
|
||||
| 🍚 Comunità · Fiducia · Scambi Solidali · Sostenibilità
|
||||
78
filelog.txt
78
filelog.txt
@@ -4,3 +4,81 @@ Dom 02/03 ORE 16:32: USER [surya1977]: ciao
|
||||
Lun 10/03 ORE 15:52: USER [surya1977]: ciao
|
||||
|
||||
Lun 10/03 ORE 15:56: USER [surya1977]: ciao
|
||||
|
||||
Lun 07/07 ORE 10:45: USER [surya1977]: ciao
|
||||
|
||||
Gio 09/10 ORE 20:42: USER [surya1977]: ciao
|
||||
|
||||
Sab 11/10 ORE 16:11: USER [surya1977]: ciao
|
||||
|
||||
Sab 11/10 ORE 16:32: USER [surya1977]: ciao
|
||||
|
||||
Sab 11/10 ORE 16:36: USER [surya1977]: ciao
|
||||
|
||||
Sab 11/10 ORE 16:43: USER [surya1977]: ciao
|
||||
|
||||
Sab 11/10 ORE 16:53: USER [surya1977]: ciao
|
||||
|
||||
Sab 11/10 ORE 17:29: USER [surya1977]: ciao
|
||||
|
||||
Sab 11/10 ORE 17:30: USER [surya1977]: ciao
|
||||
|
||||
Sab 11/10 ORE 17:30: USER [surya1977]: ciao
|
||||
|
||||
Sab 11/10 ORE 18:01: USER [surya1977]: ciao
|
||||
|
||||
Sab 11/10 ORE 18:15: USER [surya1977]: ciao
|
||||
|
||||
Sab 11/10 ORE 19:05: USER [surya1977]: ciao
|
||||
|
||||
Sab 11/10 ORE 19:36: USER [surya1977]: ciao
|
||||
|
||||
Sab 11/10 ORE 19:38: USER [surya1977]: ciao
|
||||
|
||||
Lun 27/10 ORE 13:35: USER [surya1977]: ciao
|
||||
|
||||
Gio 06/11 ORE 11:46: USER [SuryaSecondo]: ciao
|
||||
|
||||
Gio 06/11 ORE 11:46: USER [SuryaSecondo]: chi sono
|
||||
|
||||
Gio 06/11 ORE 11:47: USER [SuryaSecondo]: exitontelegram
|
||||
|
||||
Sab 08/11 ORE 20:24: USER [SuryaSecondo]: ciao
|
||||
|
||||
Sab 08/11 ORE 20:24: USER [surya1977]: /start 4b989bfb3d9af38551a8459ddf4a902c82e12017600c29bc050cc56fb835a881
|
||||
|
||||
Sab 08/11 ORE 20:24: USER [SuryaSecondo]: /start 4b989bfb3d9af38551a8459ddf4a902c82e12017600c29bc050cc56fb835a881
|
||||
|
||||
Sab 08/11 ORE 20:24: USER [SuryaSecondo]: /start 4b989bfb3d9af38551a8459ddf4a902c82e12017600c29bc050cc56fb835a881
|
||||
|
||||
Sab 08/11 ORE 21:42: USER [surya4]: ciao
|
||||
|
||||
Dom 09/11 ORE 17:57: USER [surya4]: ciao
|
||||
|
||||
Dom 09/11 ORE 18:36: USER [surya4]: ciao
|
||||
|
||||
Dom 09/11 ORE 18:43: USER [surya4]: ciao
|
||||
|
||||
Gio 20/11 ORE 19:12: USER [surya4]: ciao
|
||||
|
||||
Gio 20/11 ORE 19:15: USER [surya4]: ok
|
||||
|
||||
Gio 20/11 ORE 19:41: USER [surya4]: ok
|
||||
|
||||
Gio 20/11 ORE 19:52: USER [surya4]: ciao
|
||||
|
||||
Gio 20/11 ORE 20:55: USER [surya1977]: ciao
|
||||
|
||||
Gio 20/11 ORE 21:15: USER [surya1977]: ciao
|
||||
|
||||
Gio 20/11 ORE 21:24: USER [surya5]: ciao
|
||||
|
||||
Sab 22/11 ORE 23:30: USER [surya1977]: ciao
|
||||
|
||||
Dom 23/11 ORE 00:02: USER [perseo5]: ciao
|
||||
|
||||
Dom 23/11 ORE 00:22: USER [perseo7]: ciao
|
||||
|
||||
Lun 24/11 ORE 13:56: USER [perseo7]: ciao
|
||||
|
||||
Lun 24/11 ORE 13:57: USER [perseo7]: chi sono
|
||||
|
||||
1
localhost-key.pem
Symbolic link
1
localhost-key.pem
Symbolic link
@@ -0,0 +1 @@
|
||||
/Users/suryapaolo/certs/localhost-key.pem
|
||||
1
localhost.pem
Symbolic link
1
localhost.pem
Symbolic link
@@ -0,0 +1 @@
|
||||
/Users/suryapaolo/certs/localhost.pem
|
||||
@@ -835,4 +835,30 @@ https://t.me/riso_canale/739
|
||||
In attesa di riscontri, salutiamo! 🍚💚
|
||||
Il gruppo dei Facilitatori Territoriali RISO
|
||||
Mer 24/04 ORE 22:02: 🤖: Da Sùrya (Paolo) (paoloar77):
|
||||
✅ la regolarizzazione può avv
|
||||
✅ la regolarizzazione può avv
|
||||
Lun 07/07 ORE 10:50: 🤖: Da Sùrya undefined (surya1977):
|
||||
✅ provatest7 è stato Ammesso correttamente (da surya1977)!
|
||||
Gio 09/10 ORE 20:45: 🤖: Da Sùrya undefined (surya1977):
|
||||
✅ prova123 è stato Ammesso correttamente (da surya1977)!
|
||||
Gio 06/11 ORE 11:47: 🤖: Da Surya Ar (SuryaSecondo):
|
||||
exitontelegram
|
||||
Gio 06/11 ORE 11:51: 🤖: Da Sùrya undefined (surya1977):
|
||||
✅ SuryaArena è stato Ammesso correttamente (da surya1977)!
|
||||
Gio 06/11 ORE 20:38: 🤖: Da Sùrya undefined (surya1977):
|
||||
✅ surya3 è stato Ammesso correttamente (da surya1977)!
|
||||
Gio 06/11 ORE 22:50: 🤖: Da Sùrya undefined (surya1977):
|
||||
✅ surya4 è stato Ammesso correttamente (da surya1977)!
|
||||
Sab 08/11 ORE 20:24: 🤖: Da Sùrya (surya1977):
|
||||
/start 4b989bfb3d9af38551a8459ddf4a902c82e12017600c29bc050cc56fb835a881
|
||||
Sab 08/11 ORE 20:24: 🤖: Da Surya Ar (SuryaSecondo):
|
||||
/start 4b989bfb3d9af38551a8459ddf4a902c82e12017600c29bc050cc56fb835a881
|
||||
Sab 08/11 ORE 20:24: 🤖: Da Surya Ar (SuryaSecondo):
|
||||
/start 4b989bfb3d9af38551a8459ddf4a902c82e12017600c29bc050cc56fb835a881
|
||||
Dom 09/11 ORE 18:36: 🤖: Da Sùrya undefined (surya1977):
|
||||
✅ surya4 è stato Ammesso correttamente (da surya1977)!
|
||||
Mar 18/11 ORE 22:31: 🤖: Da Sùrya undefined (surya1977):
|
||||
✅ surya8 è stato Ammesso correttamente (da surya1977)!
|
||||
Gio 27/11 ORE 00:43: 🤖: Da Sùrya undefined (surya1977):
|
||||
✅ test123 è stato Ammesso correttamente (da surya1977)!
|
||||
Gio 27/11 ORE 00:53: 🤖: Da Sùrya undefined (surya1977):
|
||||
✅ test123 è stato Ammesso correttamente (da surya1977)!
|
||||
98
logtrans.txt
98
logtrans.txt
@@ -438,4 +438,100 @@ Lun 03/03 ORE 01:06: [<b>Circuito RIS Arezzo</b>]: Inviate Monete da surya1977 a
|
||||
|
||||
Saldi:
|
||||
surya1977: -1.10 RIS]
|
||||
Andro: 1.00 RIS]
|
||||
Andro: 1.00 RIS]
|
||||
Mer 12/03 ORE 21:30: [<b>Circuito RIS Italia</b>]: Inviate Monete da surya1977 a Giovannifruttadisicilia 60 RIS [causale: prova]
|
||||
|
||||
Saldi:
|
||||
surya1977: 34.20 RIS]
|
||||
Giovannifruttadisicilia: 458.50 RIS]
|
||||
Gio 13/03 ORE 17:44: [<b>Circuito RIS Italia</b>]: Inviate Monete da surya1977 a PiuCheBuono(GaseBottega) 1 RIS [causale: AAA]
|
||||
|
||||
Saldi:
|
||||
surya1977: 33.20 RIS]
|
||||
PiuCheBuono(GaseBottega): -65.50 RIS]
|
||||
Gio 13/03 ORE 17:45: [<b>Circuito RIS Italia</b>]: Inviate Monete da surya1977 a PiuCheBuono(GaseBottega) 3.2 RIS [causale: GGG]
|
||||
|
||||
Saldi:
|
||||
surya1977: 30.00 RIS]
|
||||
PiuCheBuono(GaseBottega): -62.30 RIS]
|
||||
Gio 13/03 ORE 18:17: [<b>Circuito RIS Italia</b>]: Inviate Monete da surya1977 a pontiUmani 2 RIS [causale: bbb]
|
||||
|
||||
Saldi:
|
||||
surya1977: 28.00 RIS]
|
||||
pontiUmani: 2.00 RIS]
|
||||
Gio 13/03 ORE 18:18: [<b>Circuito RIS Italia</b>]: Inviate Monete da surya1977 a GruppoYurta 2 RIS [causale: ggg]
|
||||
|
||||
Saldi:
|
||||
surya1977: 26.00 RIS]
|
||||
GruppoYurta: 2.00 RIS]
|
||||
Gio 13/03 ORE 18:48: [<b>Circuito RIS Italia</b>]: Inviate Monete da surya1977 a GruppoYurta 11 RIS [causale: ]
|
||||
|
||||
Saldi:
|
||||
surya1977: 15.00 RIS]
|
||||
GruppoYurta: 13.00 RIS]
|
||||
Gio 13/03 ORE 18:53: [<b>Circuito RIS Italia</b>]: Inviate Monete da surya1977 a GruppoYurta 3 RIS [causale: ]
|
||||
|
||||
Saldi:
|
||||
surya1977: 12.00 RIS]
|
||||
GruppoYurta: 16.00 RIS]
|
||||
Gio 13/03 ORE 18:57: [<b>Circuito RIS Italia</b>]: Inviate Monete da surya1977 a GruppoYurta 1 RIS [causale: ]
|
||||
|
||||
Saldi:
|
||||
surya1977: 11.00 RIS]
|
||||
GruppoYurta: 17.00 RIS]
|
||||
Dom 23/03 ORE 22:24: [<b>Circuito RIS Italia</b>]: Inviate Monete da surya1977 a GruppoYurta 1 RIS [causale: ]
|
||||
|
||||
Saldi:
|
||||
surya1977: 88.20 RIS]
|
||||
GruppoYurta: 6.00 RIS]
|
||||
Ven 03/10 ORE 15:03: [<b>Euro</b>]: Inviate Monete da paoloar77 a piuchebuono 6 € [causale: Pagato Ordine n.442]
|
||||
|
||||
Saldi:
|
||||
paoloar77: -312.80 €]
|
||||
piuchebuono: 10552.82 €]
|
||||
Dom 23/11 ORE 00:52: [<b>Circuito RIS Italia</b>]: Inviate Monete da perseo9 a surya1977 1 RIS [causale: prova 1 Ciaoooooooo]
|
||||
|
||||
Saldi:
|
||||
perseo9: -1.00 RIS]
|
||||
surya1977: 123.95 RIS]
|
||||
Dom 23/11 ORE 00:56: [<b>Circuito RIS Italia</b>]: Inviate Monete da perseo9 a surya1977 2 RIS [causale: Eccolo!
|
||||
]
|
||||
|
||||
Saldi:
|
||||
perseo9: -3.00 RIS]
|
||||
surya1977: 125.95 RIS]
|
||||
Dom 23/11 ORE 01:00: [<b>Circuito RIS Italia</b>]: Inviate Monete da perseo9 a surya1977 3 RIS [causale: aaaaa]
|
||||
|
||||
Saldi:
|
||||
perseo9: -6.00 RIS]
|
||||
surya1977: 128.95 RIS]
|
||||
Dom 23/11 ORE 01:03: [<b>Circuito RIS Italia</b>]: Inviate Monete da perseo9 a surya1977 4 RIS [causale: BBB]
|
||||
|
||||
Saldi:
|
||||
perseo9: -14.00 RIS]
|
||||
surya1977: 136.95 RIS]
|
||||
Dom 23/11 ORE 01:10: [<b>Circuito RIS Italia</b>]: Inviate Monete da perseo9 a surya1977 5 RIS [causale: sdasdas]
|
||||
|
||||
Saldi:
|
||||
perseo9: -19.00 RIS]
|
||||
surya1977: 141.95 RIS]
|
||||
Gio 04/12 ORE 18:55: [<b>Circuito RIS Bologna</b>]: Inviate Monete da SurTest a ElenaEspx 0.1 RIS [causale: ]
|
||||
|
||||
Saldi:
|
||||
SurTest: 0.00 RIS]
|
||||
ElenaEspx: 38.05 RIS]
|
||||
Mar 09/12 ORE 21:36: [<b>Circuito RIS Venezia</b>]: Inviate Monete da surya1977 a amandadi 11 RIS [causale: ssss]
|
||||
|
||||
Saldi:
|
||||
surya1977: 63.00 RIS]
|
||||
amandadi: 12.00 RIS]
|
||||
Mer 10/12 ORE 16:18: [<b>Circuito RIS Venezia</b>]: Inviate Monete da surya1977 a amandadi 12 RIS [causale: Ciaoo]
|
||||
|
||||
Saldi:
|
||||
surya1977: 51.00 RIS]
|
||||
amandadi: 24.00 RIS]
|
||||
Mer 10/12 ORE 17:02: [<b>Circuito RIS Venezia</b>]: Inviate Monete da surya1977 a amandadi 52 RIS [causale: Ancora test]
|
||||
|
||||
Saldi:
|
||||
surya1977: -1.00 RIS]
|
||||
amandadi: 76.00 RIS]
|
||||
30
package.json
30
package.json
@@ -2,24 +2,29 @@
|
||||
"name": "freeplanet-serverside",
|
||||
"version": "1.0.2",
|
||||
"description": "freeplanet serverside",
|
||||
"main": "server/server.js",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"start": "node src/server/server.js",
|
||||
"dev": "NODE_ENV=development nodemon src/server/server.js",
|
||||
"start": "node src/server.js",
|
||||
"dev": "NODE_ENV=development nodemon src/server.js",
|
||||
"build": "gulp build",
|
||||
"watch": "gulp watch",
|
||||
"test": "export NODE_ENV=development || SET NODE_ENV=development && mocha src/server/**/*.test.js",
|
||||
"start:prod": "NODE_ENV=production node src/server/server.js",
|
||||
"starttest": "NODE_ENV=test node src/server/server.js",
|
||||
"start:prod": "NODE_ENV=production node src/server.js",
|
||||
"starttest": "NODE_ENV=test node src/server.js",
|
||||
"test-watch": "nodemon --exec 'npm test'"
|
||||
},
|
||||
"author": "Surya",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fal-ai/client": "^1.7.2",
|
||||
"axios": "^1.13.0",
|
||||
"basic-ftp": "^5.0.5",
|
||||
"bcryptjs": "^3.0.2",
|
||||
"bluebird": "^3.7.2",
|
||||
"body-parser": "^1.20.3",
|
||||
"canvas": "^3.2.0",
|
||||
"cheerio": "^1.0.0",
|
||||
"compress-pdf": "^0.5.3",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"cors": "^2.8.5",
|
||||
"country-codes-list": "^2.0.0",
|
||||
@@ -28,9 +33,15 @@
|
||||
"dotenv": "^16.4.7",
|
||||
"ejs": "^3.1.10",
|
||||
"email-templates": "^12.0.2",
|
||||
"entities": "^7.0.0",
|
||||
"express": "^4.21.2",
|
||||
"express-rate-limit": "^7.1.5",
|
||||
"fast-csv": "^5.0.5",
|
||||
"formidable": "^3.5.2",
|
||||
"fs-extra": "^11.3.2",
|
||||
"ghostscript4js": "^3.2.3",
|
||||
"groq-sdk": "^0.37.0",
|
||||
"helmet": "^8.1.0",
|
||||
"i18n": "^0.15.1",
|
||||
"image-downloader": "^4.3.0",
|
||||
"internet-available": "^1.0.0",
|
||||
@@ -40,7 +51,8 @@
|
||||
"lodash": "^4.17.21",
|
||||
"mongodb": "^6.14.2",
|
||||
"mongoose": "^8.12.1",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
"morgan": "^1.10.1",
|
||||
"multer": "^1.4.5-lts.2",
|
||||
"mysql": "^2.18.1",
|
||||
"node-cron": "^3.0.3",
|
||||
"node-emoji": "^2.2.0",
|
||||
@@ -50,13 +62,15 @@
|
||||
"node-telegram-bot-api": "^0.66.0",
|
||||
"nodemailer": "^6.10.0",
|
||||
"npm-check-updates": "^17.1.15",
|
||||
"openai": "^4.86.2",
|
||||
"openai": "^4.104.0",
|
||||
"pdf-lib": "^1.17.1",
|
||||
"pdf-parse": "^1.1.1",
|
||||
"pem": "^1.14.8",
|
||||
"preview-email": "^3.1.0",
|
||||
"pug": "^3.0.3",
|
||||
"puppeteer": "^24.9.0",
|
||||
"rate-limiter-flexible": "^5.0.5",
|
||||
"replicate": "^1.4.0",
|
||||
"request": "^2.88",
|
||||
"sanitize-html": "^2.14.0",
|
||||
"save": "^2.9.0",
|
||||
@@ -67,6 +81,8 @@
|
||||
"validator": "^13.12.0",
|
||||
"vhost": "^3.0.2",
|
||||
"web-push": "^3.6.7",
|
||||
"ws": "^8.18.3",
|
||||
"xlsx": "^0.18.5",
|
||||
"xml2js": "^0.6.2",
|
||||
"xoauth2": "^1.2.0"
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const fs = require('fs');
|
||||
const fs = require('fs');
|
||||
const readline = require('readline');
|
||||
const {google} = require('googleapis');
|
||||
var FILE = require('./file');
|
||||
|
||||
@@ -25,11 +25,11 @@ var file = `.env.${node_env}`;
|
||||
|
||||
// GLOBALI (Uguali per TUTTI)
|
||||
process.env.LINKVERIF_REG = '/vreg';
|
||||
process.env.CHECKREVERIF_EMAIL = '/reverif_email';
|
||||
process.env.LINK_REQUEST_NEWPASSWORD = '/requestnewpwd';
|
||||
process.env.ADD_NEW_SITE = '/addNewSite';
|
||||
process.env.LINK_UPDATE_PASSWORD = '/updatepassword';
|
||||
process.env.LINK_UPDATE_PWD = '/updatepwd';
|
||||
process.env.LINK_CHECK_UPDATES = '/checkupdates';
|
||||
process.env.KEY_APP_ID = 'KKPPAA5KJK435J3KSS9F9D8S9F8SD98F9SDF';
|
||||
|
||||
console.log("Starting Node with: " + file);
|
||||
@@ -46,8 +46,10 @@ const database = process.env.DATABASE || "test"; // Nome del database, default a
|
||||
if (process.env.AUTH_DB_PASSING === "1") {
|
||||
// replace username and password in the process.env.DOMAIN
|
||||
process.env.MONGODB_URI = process.env.DOMAIN_AUTH.replace('{username}', username).replace('{password}', password) + database;
|
||||
process.env.MONGODB_URI_NOPWD = process.env.DOMAIN_AUTH.replace('{username}', username) + database;
|
||||
} else {
|
||||
process.env.MONGODB_URI = domain + database;
|
||||
process.env.MONGODB_URI_NOPWD = domain + database;
|
||||
}
|
||||
|
||||
console.log('process.env.MONGODB_URI:', process.env.MONGODB_URI);
|
||||
console.log('process.env.MONGODB_URI:', process.env.MONGODB_URI_NOPWD);
|
||||
492
src/controllers/UserController.js
Normal file
492
src/controllers/UserController.js
Normal file
@@ -0,0 +1,492 @@
|
||||
const UserService = require('../services/UserService');
|
||||
const AuthService = require('../services/AuthService');
|
||||
const RegistrationService = require('../services/RegistrationService');
|
||||
const { validateRegistration, validateLogin } = require('../validators/userValidators');
|
||||
const telegrambot = require('../telegram/telegrambot');
|
||||
const tools = require('../tools/general');
|
||||
const server_constants = require('../tools/server_constants');
|
||||
const shared_consts = require('../tools/shared_nodejs');
|
||||
|
||||
class UserController {
|
||||
constructor() {
|
||||
this.userService = new UserService();
|
||||
this.authService = new AuthService();
|
||||
this.registrationService = new RegistrationService();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register new user
|
||||
* POST /users
|
||||
*/
|
||||
async register(req, res) {
|
||||
try {
|
||||
tools.mylog('POST /users - Registration');
|
||||
|
||||
// Validate input
|
||||
const validationError = validateRegistration(req.body);
|
||||
if (validationError) {
|
||||
await tools.snooze(5000);
|
||||
return res.status(400).send({
|
||||
code: validationError.code,
|
||||
msg: validationError.message,
|
||||
});
|
||||
}
|
||||
|
||||
const userData = this._extractUserData(req.body);
|
||||
userData.ipaddr = tools.getiPAddressUser(req);
|
||||
|
||||
// Check security (IP bans, block words, etc.)
|
||||
const securityCheck = await this._performSecurityChecks(userData, req);
|
||||
if (securityCheck.blocked) {
|
||||
return res.status(securityCheck.status).send({
|
||||
code: securityCheck.code,
|
||||
msg: securityCheck.message,
|
||||
});
|
||||
}
|
||||
|
||||
// Process registration
|
||||
const result = await this.registrationService.registerUser(userData, req);
|
||||
|
||||
if (result.error) {
|
||||
return res.status(400).send({
|
||||
code: result.code,
|
||||
msg: result.message,
|
||||
});
|
||||
}
|
||||
|
||||
// Send response with tokens
|
||||
res.header('x-auth', result.token).header('x-refrtok', result.refreshToken).header('x-browser-random', result.browser_random).send(result.user);
|
||||
} catch (error) {
|
||||
console.error('Error in registration:', error.message);
|
||||
res.status(400).send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
msg: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* User login
|
||||
* POST /users/login
|
||||
*/
|
||||
async login(req, res) {
|
||||
try {
|
||||
console.log('LOGIN');
|
||||
const { username, password, idapp, keyappid, br } = req.body;
|
||||
|
||||
const browser_random = br;
|
||||
|
||||
// Validate API key
|
||||
if (keyappid !== process.env.KEY_APP_ID) {
|
||||
return res.status(400).send({ code: server_constants.RIS_CODE_ERR });
|
||||
}
|
||||
|
||||
// Validate input
|
||||
const validationError = validateLogin(req.body);
|
||||
if (validationError) {
|
||||
return res.status(400).send({
|
||||
code: validationError.code,
|
||||
msg: validationError.message,
|
||||
});
|
||||
}
|
||||
|
||||
// Attempt login
|
||||
const result = await this.authService.authenticate(idapp, username, password, req, browser_random);
|
||||
|
||||
console.log('attempt...', result);
|
||||
|
||||
if (result.error) {
|
||||
return res.status(result.status).send({
|
||||
code: result.code,
|
||||
msg: result.message,
|
||||
});
|
||||
}
|
||||
|
||||
// Send response with tokens
|
||||
res.header('x-auth', result.token).header('x-refrtok', result.refreshToken).header('x-browser-random', result.browser_random).send({
|
||||
usertosend: result.user,
|
||||
code: server_constants.RIS_CODE_OK,
|
||||
subsExistonDb: result.subsExistonDb,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error in login:', error.message);
|
||||
res.status(400).send({
|
||||
code: server_constants.RIS_CODE_LOGIN_ERR_GENERIC,
|
||||
msgerr: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user profile
|
||||
* POST /users/profile
|
||||
*/
|
||||
async getProfile(req, res) {
|
||||
try {
|
||||
const usernameOrig = req.user?.username || '';
|
||||
const perm = req.user?.perm || tools.Perm.PERM_NONE;
|
||||
const { username, idapp, idnotif } = req.body;
|
||||
|
||||
// Mark notification as read if present
|
||||
if (idnotif) {
|
||||
await this.userService.markNotificationAsRead(idapp, usernameOrig, idnotif);
|
||||
}
|
||||
|
||||
// Get user profile
|
||||
const profile = await this.userService.getUserProfile(idapp, username, usernameOrig, perm);
|
||||
|
||||
res.send(profile);
|
||||
} catch (error) {
|
||||
console.error('Error in getProfile:', error.message);
|
||||
res.status(400).send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
msg: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user saldo (balance)
|
||||
* POST /users/updatesaldo
|
||||
*/
|
||||
async updateSaldo(req, res) {
|
||||
try {
|
||||
const username = req.user.username;
|
||||
const { idapp, circuitId, groupname, lastdr } = req.body;
|
||||
|
||||
const result = await this.userService.updateUserBalance(idapp, username, circuitId, groupname, lastdr);
|
||||
|
||||
res.send({ ris: result });
|
||||
} catch (error) {
|
||||
console.error('Error in updateSaldo:', error.message);
|
||||
res.status(400).send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
msg: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user's friends
|
||||
* POST /users/friends
|
||||
*/
|
||||
async getFriends(req, res) {
|
||||
try {
|
||||
const username = req.user.username;
|
||||
const { idapp } = req.body;
|
||||
|
||||
const friends = await this.userService.getUserFriends(idapp, username);
|
||||
|
||||
res.send(friends);
|
||||
} catch (error) {
|
||||
console.error('Error in getFriends:', error.message);
|
||||
res.status(400).send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
msg: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute friend command (add, remove, etc.)
|
||||
* POST /users/friends/cmd
|
||||
*/
|
||||
async executeFriendCommand(req, res) {
|
||||
try {
|
||||
const usernameLogged = req.user.username;
|
||||
const { idapp, usernameOrig, usernameDest, cmd, value } = req.body;
|
||||
|
||||
// Security check
|
||||
if (!this._canExecuteFriendCommand(req.user, usernameOrig, usernameDest, cmd)) {
|
||||
return res.status(server_constants.RIS_CODE_ERR_UNAUTHORIZED).send({
|
||||
code: server_constants.RIS_CODE_ERR_UNAUTHORIZED,
|
||||
msg: '',
|
||||
});
|
||||
}
|
||||
|
||||
const result = await this.userService.executeFriendCommand(req, idapp, usernameOrig, usernameDest, cmd, value);
|
||||
|
||||
res.send(result);
|
||||
} catch (error) {
|
||||
console.error('Error in executeFriendCommand:', error.message);
|
||||
res.status(400).send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
msg: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user's groups
|
||||
* POST /users/groups
|
||||
*/
|
||||
async getGroups(req, res) {
|
||||
try {
|
||||
const username = req.user.username;
|
||||
const { idapp } = req.body;
|
||||
|
||||
const groups = await this.userService.getUserGroups(idapp, username, req);
|
||||
|
||||
res.send(groups);
|
||||
} catch (error) {
|
||||
console.error('Error in getGroups:', error.message);
|
||||
res.status(400).send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
msg: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user's circuits
|
||||
* POST /users/circuits
|
||||
*/
|
||||
async getCircuits(req, res) {
|
||||
try {
|
||||
const username = req.user.username;
|
||||
const { idapp, nummovTodownload } = req.body;
|
||||
|
||||
const circuits = await this.userService.getUserCircuits(idapp, username, req.user, nummovTodownload);
|
||||
|
||||
res.send(circuits);
|
||||
} catch (error) {
|
||||
console.error('Error in getCircuits:', error.message);
|
||||
res.status(400).send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
msg: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh authentication token
|
||||
* POST /users/newtok
|
||||
*/
|
||||
async refreshToken(req, res) {
|
||||
try {
|
||||
const { refreshToken, br } = req.body;
|
||||
|
||||
const browser_random = br;
|
||||
|
||||
if (!refreshToken) {
|
||||
return res.status(400).send({ error: 'Refresh token mancante' });
|
||||
}
|
||||
|
||||
const result = await this.authService.refreshToken(refreshToken, req);
|
||||
|
||||
if (result.error) {
|
||||
return res.status(result.status).send({ error: result.message });
|
||||
}
|
||||
|
||||
res.status(200).send({
|
||||
token: result.token,
|
||||
refreshToken: result.refreshToken,
|
||||
browser_random,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error in refreshToken:', error.message);
|
||||
res.status(500).send({ error: 'Errore interno del server' });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout user (remove token)
|
||||
* DELETE /users/me/token
|
||||
*/
|
||||
async logout(req, res) {
|
||||
try {
|
||||
await this.authService.removeToken(req.user, req.token);
|
||||
res.status(200).send();
|
||||
} catch (error) {
|
||||
console.error('Error in logout:', error.message);
|
||||
res.status(400).send();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if username exists
|
||||
* GET /users/:idapp/:username
|
||||
*/
|
||||
async checkUsername(req, res) {
|
||||
try {
|
||||
const { username, idapp } = req.params;
|
||||
|
||||
const exists = await this.userService.checkUsernameExists(idapp, username);
|
||||
|
||||
if (!exists) {
|
||||
return res.status(404).send();
|
||||
}
|
||||
|
||||
res.status(200).send();
|
||||
} catch (error) {
|
||||
console.error('Error in checkUsername:', error.message);
|
||||
res.status(400).send();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user permissions
|
||||
* POST /users/setperm
|
||||
*/
|
||||
async setPermissions(req, res) {
|
||||
try {
|
||||
const { idapp, username, perm } = req.body;
|
||||
|
||||
await this.userService.setUserPermissions(req.user._id, {
|
||||
idapp,
|
||||
username,
|
||||
perm,
|
||||
});
|
||||
|
||||
res.status(200).send();
|
||||
} catch (error) {
|
||||
console.error('Error in setPermissions:', error.message);
|
||||
res.status(400).send();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Database operations (admin only)
|
||||
* POST /users/dbop
|
||||
*/
|
||||
async executeDbOperation(req, res) {
|
||||
try {
|
||||
const { mydata, idapp } = req.body;
|
||||
|
||||
// Check permissions
|
||||
if (!this._hasAdminPermissions(req.user)) {
|
||||
return res.status(404).send({
|
||||
code: server_constants.RIS_CODE_ERR_UNAUTHORIZED,
|
||||
});
|
||||
}
|
||||
|
||||
const result = await this.userService.executeDbOperation(idapp, mydata, req, res);
|
||||
|
||||
res.send({
|
||||
code: server_constants.RIS_CODE_OK,
|
||||
data: result,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error in executeDbOperation:', error.message);
|
||||
res.status(400).send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
msg: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get map information
|
||||
* POST /users/infomap
|
||||
*/
|
||||
async getMapInfo(req, res) {
|
||||
try {
|
||||
const { idapp } = req.body;
|
||||
|
||||
const mapData = await this.userService.getMapInformation(idapp);
|
||||
|
||||
res.send({
|
||||
code: server_constants.RIS_CODE_OK,
|
||||
ris: mapData,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error in getMapInfo:', error.message);
|
||||
res.status(400).send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
msg: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// ===== PRIVATE HELPER METHODS =====
|
||||
|
||||
_extractUserData(body) {
|
||||
const fields = [
|
||||
'email',
|
||||
'password',
|
||||
'username',
|
||||
'group',
|
||||
'name',
|
||||
'surname',
|
||||
'idapp',
|
||||
'keyappid',
|
||||
'lang',
|
||||
'profile',
|
||||
'aportador_solidario',
|
||||
];
|
||||
|
||||
const userData = {};
|
||||
fields.forEach((field) => {
|
||||
if (body[field] !== undefined) {
|
||||
userData[field] = body[field];
|
||||
}
|
||||
});
|
||||
|
||||
// Normalize data
|
||||
if (userData.email) userData.email = userData.email.toLowerCase().trim();
|
||||
if (userData.username) userData.username = userData.username.trim();
|
||||
if (userData.name) userData.name = userData.name.trim();
|
||||
if (userData.surname) userData.surname = userData.surname.trim();
|
||||
|
||||
return userData;
|
||||
}
|
||||
|
||||
async _performSecurityChecks(userData, req) {
|
||||
const { User } = require('../models/user');
|
||||
|
||||
// Check for blocked words
|
||||
if (tools.blockwords(userData.username) || tools.blockwords(userData.name) || tools.blockwords(userData.surname)) {
|
||||
await tools.snooze(5000);
|
||||
return {
|
||||
blocked: true,
|
||||
status: 404,
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
};
|
||||
}
|
||||
|
||||
// Check IP ban
|
||||
const lastRecord = await User.getLastRec(userData.idapp);
|
||||
if (lastRecord && process.env.LOCALE !== '1') {
|
||||
if (lastRecord.ipaddr === userData.ipaddr && lastRecord.date_reg) {
|
||||
const isTooRecent = tools.isdiffSecDateLess(lastRecord.date_reg, 3);
|
||||
if (isTooRecent) {
|
||||
const msg = `${userData.ipaddr}: [${userData.username}] ${userData.name} ${userData.surname}`;
|
||||
tools.writeIPToBan(msg);
|
||||
await telegrambot.sendMsgTelegramToTheAdmin(userData.idapp, '‼️ BAN: ' + msg, true);
|
||||
await tools.snooze(5000);
|
||||
|
||||
return {
|
||||
blocked: true,
|
||||
status: 400,
|
||||
code: server_constants.RIS_CODE_BANIP,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { blocked: false };
|
||||
}
|
||||
|
||||
_canExecuteFriendCommand(user, usernameOrig, usernameDest, cmd) {
|
||||
const { User } = require('../models/user');
|
||||
|
||||
if (User.isAdmin(user.perm) || User.isManager(user.perm)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const allowedCommands = [shared_consts.FRIENDSCMD.SETFRIEND, shared_consts.FRIENDSCMD.SETHANDSHAKE];
|
||||
|
||||
if (allowedCommands.includes(cmd)) {
|
||||
return usernameOrig === user.username || usernameDest === user.username;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
_hasAdminPermissions(user) {
|
||||
const { User } = require('../models/user');
|
||||
return User.isCollaboratore(user.perm);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = UserController;
|
||||
1020
src/controllers/articleController.js
Normal file
1020
src/controllers/articleController.js
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user