Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hotfix #243

Merged
merged 27 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
431f554
deploy
Sajistreo3 Oct 18, 2023
29a848a
real time fix
Sajistreo3 Oct 23, 2023
f399cbc
Schedule post
Sajistreo3 Oct 23, 2023
f2c63cb
Update banner & avatar backend ready, Bio Update Done
Sajistreo3 Oct 23, 2023
e9d3234
BIG UPDATE: Utility Claim or Disclaim
Sajistreo3 Oct 23, 2023
a6de3b0
Timestamp fix post feed
Sajistreo3 Oct 23, 2023
2d99d63
fix modal utility claim modal
JW-Rami Oct 25, 2023
cc03984
Update Avatar & Banner Upload
Sajistreo3 Oct 25, 2023
f76b1f6
Fix Update Banner & Avatar
Sajistreo3 Oct 25, 2023
9cfcaf8
Utility Update
Sajistreo3 Oct 25, 2023
be8bbe4
fix minor bug
JWMatheo Oct 29, 2023
ba3241b
click on media to display the fullpage post
JW-Rami Nov 8, 2023
ff1486d
email fix unfinished
Sajistreo3 Nov 24, 2023
eff4bd1
input font + some clean up
JW-Rami Nov 24, 2023
28513c8
single nft utility uodate
Sajistreo3 Dec 11, 2023
e4acd3e
Claimed Utility Doc Created
Sajistreo3 Jan 7, 2024
c06626a
send mail utilisateur
Sajistreo3 Jan 7, 2024
16d4be4
Athlete Confirmation Email.
Sajistreo3 Jan 7, 2024
8aae65a
fix bug cloud functions + mail sending
JW-Rami Jan 15, 2024
6a63200
Message pour MAtheo
Sajistreo3 Jan 15, 2024
652a64c
hotfix
JW-Rami Jan 15, 2024
0dab410
comment for poll shajeed task
JW-Rami Jan 15, 2024
5aa1c91
style: fix banner athlete profile
JW-Rami Jan 15, 2024
c1c9a78
update poll post try
Sajistreo3 Jan 19, 2024
82491bc
New Staging
Sajistreo3 Mar 18, 2024
1beb7f1
useless usestate
Sajistreo3 Mar 18, 2024
69cddcd
chore: fix merge from master into staging
JW-Rami Mar 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified .DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions client/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ yarn-error.log*
# firebase
**/.firebase
/.firebaserc
/firebase.json
2 changes: 1 addition & 1 deletion client/firebase.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"hosting": {
"site": "sofan-app",
"site": "staging-sofan-app",
"public": "build",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [
Expand Down
49 changes: 49 additions & 0 deletions client/functions/generateAthleteClaimUtilityEmailHTML.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
const generateAthleteClaimUtilityEmailHTML = ({
athleteName,
userName,
nftId,
collectionName,
title,
description,
claimed_date,
}) => {
return `
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<title>Notification de Réclamation NFT</title>
</head>
<body style="background-color: white; color: #333; font-family: Arial, sans-serif; padding: 20px;">
<div style="max-width: 500px; margin: 0 auto; padding: 20px; background-color: #f6f6f6; border-radius: 5px;">
<div style="text-align: center; margin-bottom: 20px;">
<img src="https://firebasestorage.googleapis.com/v0/b/sofan-app.appspot.com/o/sofanlogo.svg?alt=media&token=00ba642b-8d9e-4010-b831-19413e0a2dea" alt="Sofan Logo" style="width: 150px;"/>
</div>
<div style="margin: 20px 0; font-size: 18px;">
Bonjour ${athleteName},
<br><br>
Nous tenons à vous informer qu'un utilisateur a récemment réclamé une utilité de votre collection NFT. Voici les détails :
<ul>
<li>Utilisateur: ${userName}</li>
<li>ID de NFT: ${nftId}</li>
<li>Collection NFT: ${collectionName}</li>
<li>Date de réclamation: ${claimed_date}</li>
</ul>
</div>
<div style="margin-top: 20px; padding: 10px; border: 1px solid #ddd; border-radius: 8px; background-color: #f9f9f9;">
<h3 style="color: #333;">Détails de l'Utilité</h3>
<p><strong>Titre:</strong> ${title}</p>
<p><strong>Description:</strong> ${description}</p>
</div>
<div style="text-align: center; color: #888; font-size: 14px; margin-top: 20px;">
Si vous avez des questions ou besoin d'assistance, n'hésitez pas à nous contacter à <a href="mailto:[email protected]" style="color: blue;">[email protected]</a>.
</div>
</div>
</body>
</html>
`;
};

module.exports = generateAthleteClaimUtilityEmailHTML;

54 changes: 54 additions & 0 deletions client/functions/generateUserClaimUtilityEmailHTML.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
const generateUserClaimUtilityEmailHTML = ({
display_name,
nftId,
athleteName,
claimed_date,
collectionName,
title,
description,
utility_date,
}) => {

return `
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<title>Confirmation de Réclamation NFT</title>
</head>
<body style="background-color: white; color: #333; font-family: Arial, sans-serif; padding: 20px;">
<div style="max-width: 500px; margin: 0 auto; padding: 20px; background-color: #f6f6f6; border-radius: 5px;">
<div style="text-align: center; margin-bottom: 20px;">
<img src="https://firebasestorage.googleapis.com/v0/b/sofan-app.appspot.com/o/sofanlogo.svg?alt=media&token=00ba642b-8d9e-4010-b831-19413e0a2dea" alt="Sofan Logo" style="width: 150px;"/>
</div>
<div style="margin: 20px 0; font-size: 18px;">
Bonjour ${display_name},
<br><br>
Nous sommes heureux de vous confirmer que vous avez réussi à réclamer une utilité NFT pour ${collectionName}.
<br><br>
Détails de l'utilité réclamée:
<ul>
<li>ID de NFT: ${nftId}</li>
<li>Nom de l'athlète: ${athleteName}</li>
<li>Date de réclamation: ${claimed_date}</li>
</ul>
<div style="margin-top: 20px; padding: 10px; border: 1px solid #ddd; border-radius: 8px; background-color: #f9f9f9;">
<h3 style="color: #333;">Détails de l'Utilité</h3>
<p><strong>Titre:</strong> ${title}</p>
<p><strong>Description:</strong> ${description}</p>
<p><strong>Date de l'Utilité:</strong> ${utility_date}</p>
</div>
Vous pouvez vérifier l'état de votre utilité NFT à tout moment dans votre tableau de bord utilisateur.
</div>
<a href="https://sofan.app" style="display: block; width: 200px; margin: 20px auto; padding: 10px; background-color: #f6d463; color: white; text-align: center; border-radius: 5px; text-decoration: none; font-weight: bold;">Voir Mon Profile</a>
<div style="text-align: center; color: #888; font-size: 14px; margin-top: 20px;">
Si vous avez des questions ou besoin d'assistance, n'hésitez pas à nous contacter à <a href="mailto:[email protected]" style="color: blue;">[email protected]</a>.
</div>
</div>
</body>
</html>
`;
};

module.exports = generateUserClaimUtilityEmailHTML;
2 changes: 1 addition & 1 deletion client/functions/generateVerificationCodeEmailHTML.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const generateVerificationCodeEmailHTML = ({ code }) => {
<p>Préparez-vous à vivre une expérience unique.</p>
</div>
<div style="${footerStyle}">
<p>Si vous avez besoin d'aide, n'hésitez pas à contacter notre équipe de support dédiée à <a href="mailto:support@sofan.com">support@sofan.app</a>.</p>
<p>Si vous avez besoin d'aide, n'hésitez pas à contacter notre équipe de support dédiée à <a href="mailto:contact@sofan.app">contact@sofan.app</a>.</p>
<p>Merci d'avoir choisi Sofan! Nous sommes impatients de vous servir.</p>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions client/functions/generateWelcomeEmailHTML.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ const generateWelcomeEmailHTML = () => {
</a>
<div style="text-align: center; color: #888; font-size: 14px; margin-top: 20px;">
Si vous avez des questions sur les sports, les athlètes ou les NFTs, n'hésitez pas à nous contacter à
<a href="mailto:support@sofan.com" style="color: blue;">
support@sofan.com
<a href="mailto:contact@sofan.app" style="color: blue;">
contact@sofan.app
</a>
</div>
</div>
Expand Down
160 changes: 129 additions & 31 deletions client/functions/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
const functions = require("firebase-functions/v1");
const cors = require('cors')({ origin: ['http://localhost:3000', 'https://www.sofan.app', 'https://staging.sofan.app'] });
//.const cors = require('cors')({ origin: true });
//const cors = require('cors')({ origin: ['http://localhost:3000', 'https://www.sofan.app', 'https://staging.sofan.app'] });
const cors = require("cors")({ origin: true });

// // Create and deploy your first functions
// // https://firebase.google.com/docs/functions/get-started

const nodemailer = require("nodemailer");
const generateVerificationCodeEmailHTML = require("./generateVerificationCodeEmailHTML");
const generateWelcomeEmailHTML = require("./generateWelcomeEmailHTML");
const generateUserClaimUtilityEmailHTML = require("./generateUserClaimUtilityEmailHTML");
const generateAthleteClaimUtilityEmailHTML = require("./generateAthleteClaimUtilityEmailHTML");

const transporter = nodemailer.createTransport({
host: "mail.gandi.net",
Expand All @@ -22,6 +24,8 @@ const transporter = nodemailer.createTransport({
// functions.logger.log(functions.config().email.user);

exports.sendVerificationEmail = functions.https.onRequest((req, res) => {
// Return 204 for OPTIONS method (preflight request)

cors(req, res, async () => {
if (req.method !== "POST") {
return res.status(405).send("Method Not Allowed");
Expand All @@ -38,19 +42,19 @@ exports.sendVerificationEmail = functions.https.onRequest((req, res) => {
subject: "Sign Up Verification Code",
html: htmlContent,
};

console.log("console.log mail Option -->", mailOptions);
functions.logger.log("functions logger mail Option -->",mailOptions);
try {
await transporter.sendMail(mailOptions);
functions.logger.log("Email sent successfully");
res.send({ success: "Email sent successfully" }); // Send success response
res.status(200).send({ success: "Email sent successfully" }); // Send success response
} catch (err) {
functions.logger.error("Error sending email:", err);
res.status(500).send({ error: "Error sending email", details: err }); // Send error details
}
});
});


exports.sendWelcomeEmail = functions.https.onRequest((req, res) => {
cors(req, res, async () => {
if (req.method !== "POST") {
Expand All @@ -77,41 +81,135 @@ exports.sendWelcomeEmail = functions.https.onRequest((req, res) => {
});
});

exports.sendUserClaimUtilityEmail = functions.https.onRequest((req, res) => {
cors(req, res, async () => {
if (req.method !== "POST") {
return res.status(405).send("Method Not Allowed");
}

const {
email,
display_name,
nftId,
athleteName,
claimed_date,
collectionName,
title,
description,
utility_date,
} = req.body;
const htmlContent = generateUserClaimUtilityEmailHTML({
display_name,
nftId,
athleteName,
claimed_date,
collectionName,
title,
description,
utility_date,
});

const mailOptions = {
from: `"Sofan" <${functions.config().email.user}>`, // Make sure the sender address is verified in your email service provider
to: email,
subject: "Confirmation de votre réclamation Utilité d'NFT - Sofan",
html: htmlContent,
};

try {
await transporter.sendMail(mailOptions);
functions.logger.log("Email sent successfully");
res.send({ success: "Email sent successfully" }); // Send success response
} catch (err) {
functions.logger.error("Error sending email:", err);
res.status(500).send({ error: "Error sending email", details: err }); // Send error details
}
});
});

exports.sendAthleteClaimUtilityEmail = functions.https.onRequest((req, res) => {
cors(req, res, async () => {
if (req.method !== "POST") {
return res.status(405).send("Method Not Allowed");
}

const {
athleteEmail, // Ensure to include the athlete's email in the request
athleteName,
userName,
nftId,
collectionName,
title,
description,
claimed_date,
} = req.body;

const htmlContent = generateAthleteClaimUtilityEmailHTML({
athleteName,
userName,
nftId,
collectionName,
title,
description,
claimed_date,
});

const mailOptions = {
from: `"Sofan" <${functions.config().email.user}>`,
to: athleteEmail, // Send to the athlete's email
subject:
"Notification: Un utilisateur a réclamé une utilité de votre collection NFT - Sofan",
html: htmlContent,
};

try {
await transporter.sendMail(mailOptions);
functions.logger.log("Email sent to athlete successfully");
res.send({ success: "Email sent to athlete successfully" });
} catch (err) {
functions.logger.error("Error sending email to athlete:", err);
res
.status(500)
.send({ error: "Error sending email to athlete", details: err });
}
});
});

const admin = require('firebase-admin');
const admin = require("firebase-admin");
//const functions = require('firebase-functions');
admin.initializeApp();

exports.scheduledPublish = functions.pubsub.schedule('every 60 minutes').onRun(async (context) => {
const now = admin.firestore.Timestamp.now();
const scheduledPostsRef = admin.firestore().collection('scheduled_posts');
const feedPostsRef = admin.firestore().collection('feed_post');
exports.scheduledPublish = functions.pubsub
.schedule("every 60 minutes")
.onRun(async (context) => {
const now = admin.firestore.Timestamp.now();
const scheduledPostsRef = admin.firestore().collection("scheduled_posts");
const feedPostsRef = admin.firestore().collection("feed_post");

console.log('Checking for scheduled posts to publish...');
console.log("Checking for scheduled posts to publish...");

const snapshot = await scheduledPostsRef.where('publish_timestamp', '<=', now).get();
const snapshot = await scheduledPostsRef
.where("publish_timestamp", "<=", now)
.get();

if (snapshot.empty) {
console.log('No posts to publish.');
return null;
}
if (snapshot.empty) {
console.log("No posts to publish.");
return null;
}

const batch = admin.firestore().batch();
const batch = admin.firestore().batch();

snapshot.docs.forEach((doc) => {
const postData = doc.data();
postData.createdAt = now; // Update the createdAt value to the current timestamp
const newPostRef = feedPostsRef.doc();

batch.set(newPostRef, postData);
batch.delete(doc.ref);
});

return batch.commit().then(() => {
console.log('Posts published successfully!');
return null;
});
});
snapshot.docs.forEach((doc) => {
const postData = doc.data();
postData.createdAt = now; // Update the createdAt value to the current timestamp
const newPostRef = feedPostsRef.doc();

batch.set(newPostRef, postData);
batch.delete(doc.ref);
});

return batch.commit().then(() => {
console.log("Posts published successfully!");
return null;
});
});
8 changes: 4 additions & 4 deletions client/functions/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion client/functions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"dotenv": "^16.3.1",
"firebase-admin": "^11.5.0",
"firebase-functions": "^4.2.0",
"nodemailer": "^6.9.4"
"nodemailer": "^6.9.12"
},
"devDependencies": {
"firebase-functions-test": "^3.0.0"
Expand Down
Loading
Loading