Build Your Own Secret Santa App

CT Solutions
5 min readDec 24, 2020

It is that time of the year when we tend to spend our day with our loved ones spreading happiness. At CT solutions, we celebrate this festival with the same enthusiasm, Secret Santa being our main activity of the day.

But due to the pandemic that took a toll all over the globe in 2019, we had to deviate from the usual celebration ways everyone is canceling Christmas this year. And as I told you already, we love Christmas (Secret Santa😉 )

We had to deviate from the usual celebration ways and come with something else. So instead of canceling Christmas, we are taking it online, Yay!! But, there’s a catch, we are building our own application to randomly assign secret Santas and you are building this application with us.

At first, we will be building a login page to verify the email id. This page is specifically for the host, manager, or HR who will be organizing the Secret Santa activity

Login Page

We have used firebase passwordless sign in, which sends the sign-in link to users on their email id.

const getUserEmailAddress = (e) => {
setUserEmailAddress(e.target.value);
};
const submitEmailAddress = () => {
var actionCodeSettings = {
url: "https://secret-santa-celebration.web.app/",
handleCodeInApp: true,
};
auth
.sendSignInLinkToEmail(userEmailAddress, actionCodeSettings)
.then(() => {
window.localStorage.setItem("emailForSignIn", userEmailAddress);
setUserEmailAddress("");
alert("Please check your email to sign in!");
})
.catch((error) => {
console.log(error);
});
};

We have used authListener to check if the user is accessing the link through the link provided in the mail.

const authListener = () => {
if (auth.isSignInWithEmailLink(window.location.href)) {
var email = window.localStorage.getItem("emailForSignIn");
if (email !== null) {
auth
.signInWithEmailLink(email, window.location.href)
.then(function (result) {
window.localStorage.removeItem("emailForSignIn");
setCurrentUser(result.user);
})
.catch(function (error) {
setCurrentUser(null);
console.log(error);
});
}
}
};

Now we are going to build a page where we will be adding all the names with their respective email ids.

The second page, where we will add name and email id.

In this section, we are taking input from users and storing it in our database.

const getMembersArray = () => {
if ($("#members-name").val() !== "") {
let docId = uuidv4();
var pushOnlyArray = $("#members-name").val().split(", ");
let membersData = [];
let memberNames = [];
let memberEmails = [];
let totalMembers = pushOnlyArray.length / 2;
for (let i = 0; i < pushOnlyArray.length; i++) {
if (i % 2 === 0) {
memberNames.push(pushOnlyArray[i]);
} else {
memberEmails.push(pushOnlyArray[i]);
}
}
for (let j = 0; j < totalMembers; j++) {
let memberData = {
name: memberNames[j],
email: memberEmails[j],
assigned: false,
partner: "",
};
membersData.push(memberData);
}
}
setMembers(membersData);
var docRef = db.collection("secret_santa_draws").doc(docId);
// console.log("user email");
// console.log(auth.currentUser.email);
docRef.set({
user_email: auth.currentUser.email,
secret_santa_id: docId,
members: membersData,
});
generateRandomName(docRef);
// updateNames(docRef);
$("#members-name").val("");
alert("Mails have been sent!");
} else {
alert("Please Add Some members names");
}
};
}

In the above code, the getMembersArray function is used to get the values from the user side.

To separate the names and emails from the text string provided by the user we are dividing the length of the array from 2. We have first separated all the values and stored them in an array and then stored the names in a different array and email in a different array.

let totalMembers = pushOnlyArray.length / 2;
for (let i = 0; i < pushOnlyArray.length; i++) {
if (i % 2 === 0) {
memberNames.push(pushOnlyArray[i]);
} else {
memberEmails.push(pushOnlyArray[i]);
}
}

In this, we have created an array of objects, in each object we are storing 4 properties. We have separated the name and email given by the user in the above function getMembersArray and we have taken the property assign to check whether the member is assigned or not. The value stored in the “partner” is the Secret Santa Child of the member.

{
name: memberNames[j],
email: memberEmails[j],
assigned: false,
partner: "",
}

Now to assign random names to every member in the list.

const generateRandomName = (docRef) => {
docRef.get().then((doc) => {
if (doc.exists) {
const data = doc.data();
data["members"].forEach((selectedMember) => {
let namesToChooseFrom = [];
if (selectedMember["partner"] === "") {
memberRef.current.forEach((member) => {
if (member["name"] !== selectedMember["name"]) {
if (!member["assigned"]) {
namesToChooseFrom.push(member);
}
}
});
}

In generateRandomName, we will be assigning partners to every selected member.

if (selectedMember["partner"] === "")

If the above condition is true then we will use mapping to choose the possible partner.

if (member["name"] !== selectedMember["name"])

In this section, we are checking if the member name and the name of the assigned partner are not the same.

In the last part, we will be assigning the partners to every member and will be updating the backend data.

docRef
.update({
members: memberRef.current,
})
.then(() => {
console.log("member set to assigned");
})
.catch((error) => {
console.log("Error updating document: ", error);
});

In generateRandomName function, we are assigning the value (partner) to each member and also checking if the value has already been assigned or not.

memberRef.current.forEach((member) => {
if (member["name"] !== selectedMember["name"]) {
if (!member["assigned"]) {
namesToChooseFrom.push(member);
}
}
});

In this function, we are generating a random number between two integers to select a partner out of possible choices.

function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min) + min);
}

For the front end section, we only have to keep one thing in mind is how we are getting the input from the user. In our case, we have created only one input box from where we are getting all the names and email ids.

In this name and email is separated by “, “ (comma and space)

When the user will click on “Get Secret Santa” after adding all the names and email ids, the popup modal will be shown to the user.

browser alert box ( background image used from freepik)

And the mail will be sent to each and every user with the name of their Secret Santa Child.

Here’s my secret Santa child (this is not true 😉 )

You can check out this application here.

Now you can create your own secret Santa application. If not secret Santa, you can use the same functionality to create something else. Let us know how you are using this functionality and modifying it to use in some different applications. 😊

Reach out to us via Instagram Twitter LinkedIn

Or send us an email ✉️ at admin@catalyst.sh.

--

--

CT Solutions

Driven by the zeal to bring in a change in the digital world, Catalyst Technology Solutions will evolve your brand globally.