Skip to content

Commit

Permalink
Merge pull request #243 from So-Fan/staging
Browse files Browse the repository at this point in the history
Hotfix
  • Loading branch information
JW-Rami authored Mar 18, 2024
2 parents 1c4c0ca + 69cddcd commit 19a7e11
Show file tree
Hide file tree
Showing 45 changed files with 2,721 additions and 474 deletions.
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:support@sofan.com" style="color: blue;">support@sofan.com</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:contact@sofan.app" style="color: blue;">contact@sofan.app</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

0 comments on commit 19a7e11

Please sign in to comment.