diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 00000000..e69de29b
diff --git a/package.json b/package.json
index d9827e5c..7b444865 100644
--- a/package.json
+++ b/package.json
@@ -52,6 +52,7 @@
"react-loading-skeleton": "^3.2.0",
"react-markdown": "^8.0.7",
"react-router-dom": "^6.9.0",
+ "react-select-country-list": "^2.2.3",
"react-simplemde-editor": "^5.2.0",
"react-text-loop": "^2.3.0",
"react-text-transition": "^3.1.0",
diff --git a/src/components/Header.jsx b/src/components/Header.jsx
index 47ed4dcd..94c77e89 100644
--- a/src/components/Header.jsx
+++ b/src/components/Header.jsx
@@ -112,4 +112,4 @@ export function Header() {
);
-}
+}
\ No newline at end of file
diff --git a/src/components/settingComponents/generalPage.jsx b/src/components/settingComponents/generalPage.jsx
new file mode 100644
index 00000000..879e2759
--- /dev/null
+++ b/src/components/settingComponents/generalPage.jsx
@@ -0,0 +1,497 @@
+
+import React from 'react'
+import { useState } from 'react';
+import { Transition, Dialog } from '@headlessui/react';
+import { Fragment } from 'react';
+import { Locations } from '@/components/settingComponents/locations';
+import { useRouter } from 'next/router';
+import { getStorage, ref, uploadBytesResumable, getDownloadURL } from 'firebase/storage';
+import { getCookie } from '@/utils/request';
+import { useEffect } from 'react';
+
+export default function General() {
+ const router = useRouter();
+
+ const [isPopupOpen, setIsPopupOpen] = useState(false);
+ const [selectedImage, setSelectedImage] = useState(null);
+
+ const [inputText, setInputText] = useState('');
+
+ const handleInputChange = (event) => {
+ setInputText(event.target.value);
+ };
+ const [pfp, setPfp] = useState(`https://robohash.org/KshitijIsCool.png?set=set1&size=150x150`);
+ const [open, setOpen] = useState(true);
+
+
+ function pfpChange() {
+ pfpChanged = true;
+ }
+
+ const handlePopupOpen = () => {
+ setIsPopupOpen(true);
+ }
+
+ useEffect(() => {
+ const fileInput = document.getElementById('fileInput');
+
+ // set username
+ var xhr = new XMLHttpRequest();
+
+ xhr.addEventListener('readystatechange', function () {
+ if (this.readyState === 4) {
+ console.log(this.responseText);
+ try {
+ if (document.getElementById('first-name')) {
+
+ setUsername(JSON.parse(this.responseText).username);
+ }
+
+ } catch (e) {
+ console.log(e);
+ }
+ }
+ });
+
+ xhr.open('GET', `${process.env.NEXT_PUBLIC_API_URL}/account`);
+ let token = getCookie();
+ xhr.setRequestHeader('Authorization', 'Bearer ' + token);
+ xhr.withCredentials = true;
+ xhr.send();
+ }, []);
+
+ const handlePopupClose = () => {
+ setIsPopupOpen(false);
+ }
+
+ const handleImageChange = (event) => {
+ const file = event.target.files[0];
+ setSelectedImage(file);
+ }
+
+ const handleSaveChanges = async () => {
+ if (!selectedImage) {
+ console.log("No image selected");
+ setIsPopupOpen(false)
+ return;
+ }
+
+
+ // upload to firebase storage
+ try {
+ const storage = getStorage();
+ const metadata = {
+ contentType: 'image/jpeg',
+ };
+
+ const storageRef = ref(storage, `${email}/pictures/pfp`);
+ const uploadTask = uploadBytesResumable(storageRef, selectedImage, metadata)
+
+ uploadTask.on('state_changed',
+ (snapshot) => {
+ // progress function
+ const progress = Math.round((snapshot.bytesTransferred / snapshot.totalBytes) * 100);
+ console.log('Upload is ' + progress + '% done');
+ switch (snapshot.state) {
+ case 'paused':
+ console.log('Upload is paused');
+ break;
+ case 'running':
+ console.log('Upload is running');
+ break;
+ }
+ },
+ (error) => {
+ switch (error.code) {
+ case 'storage/unauthorized':
+ console.log('User does not have permission to access the object');
+ break;
+ case 'storage/canceled':
+ console.log('User canceled the upload');
+ break;
+ case 'storage/unknown':
+ console.log('Unknown error occurred, inspect error.serverResponse');
+ break;
+ }
+ },
+ async () => {
+ const imageUrl = await getDownloadURL(uploadTask.snapshot.ref)
+ console.log(imageUrl)
+ console.log(user);
+ const endPoint = process.env.NEXT_PUBLIC_API_URL + '/users/' + username + '/updatePfp';
+ const body = { imageUrl }
+ const response = await request(endPoint, "POST", body);
+ console.log("Here is the result: ", response)
+ if (response.success) {
+ console.log("profile picture uploaded successfully");
+ } else {
+ console.log("Failed to upload profile picture");
+ }
+ window.location.reload();
+
+ }
+ );
+ setIsPopupOpen(false);
+
+
+ } catch (err) {
+ console.log(err);
+ console.log("An error occured while uploading profile picture");
+ }
+ }
+
+ const handleClick = () => { }
+
+ function saveGeneral() {
+ document.getElementById('save').innerHTML = 'Saving...';
+
+ var firstName = document.getElementById('first-name').value;
+ var lastName = document.getElementById('last-name').value;
+ var bio = document.getElementById('bio').value;
+ var github = document.getElementById('url').value;
+ var location = document.getElementById('location').value;
+
+ var data = JSON.stringify({
+ bio: bio,
+ githubUrl: github,
+ firstName: firstName,
+ lastName: lastName,
+ location: location,
+ });
+
+ var xhr = new XMLHttpRequest();
+
+ xhr.addEventListener('readystatechange', function () {
+ if (this.readyState === 4) {
+ console.log(this.responseText);
+ document.getElementById('save').innerHTML = 'Save';
+ }
+ });
+
+ xhr.open('PUT', `${process.env.NEXT_PUBLIC_API_URL}/account`);
+ xhr.setRequestHeader('Content-Type', 'application/json');
+ let token = getCookie();
+ xhr.setRequestHeader('Authorization', 'Bearer ' + token);
+ xhr.withCredentials = true;
+ xhr.send(data);
+
+ }
+
+ return (
+
+
+
+ General
+
+
+
+
+
+
+ Profile
+
+
+ This information will be displayed publicly so be
+ careful what you share.
+
+
+
+
+
+ First name
+
+
+
+
+
+
+ Last name
+
+
+
+
+
+
+
+
+ Profile Picture
+
+
+
+
+
+
handlePopupOpen()} className="ml-4 bg-neutral cursor:pointer block rounded-md px-3 py-2 text-sm font-semibold text-white shadow-sm ring-1 ring-inset ring-slate-300 hover:bg-neutral-800 peer-focus:ring-2 peer-focus:ring-blue-600">
+ Change
+
+
+
+
+
+
+
+ Bio
+
+
+
+
+
+ Brief description for your profile. URLs are
+ hyperlinked.
+
+
+
+
+
+ Github Username
+
+
+
+ Your GitHub link: github.com/{inputText}
+
+
+
+
+
+
+
+ Personal Information
+
+
+ This information will be displayed publicly so be
+ careful what you share.
+
+
+
+
+
+ Email address
+
+
+
+
+ {/* LOCATION OPTIONS */}
+
+
+ Location
+
+
+
+
+
+ {/* PROFILE PICTURE POP-UP */}
+
+
+ handlePopupClose()}>
+
+
+
+ {
+ handlePopupClose()
+ localStorage.setItem("22-18-update", false)
+ }}
+ className="fixed inset-0 bg-gray-900 bg-opacity-75 transition-opacity" />
+
+
+
+
+
+
+
Change Profile Picture
+
+
+
+
+
+ Current Profile Picture
+
+
+
+ {/* INPUT BOX */}
+
+
+ {selectedImage ? (
+
+
+
+ New Profile Picture
+
+
+ ) : (
+
+
+
+
+
Click here or Drag an Image!
+
+ )}
+
+
+
+
+
+
+ handlePopupClose()}>Close
+
+
+
+ handleSaveChanges()}>Save
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Save
+
+
+
+
+
+ );
+}
diff --git a/src/components/settingComponents/locations.jsx b/src/components/settingComponents/locations.jsx
new file mode 100644
index 00000000..be0f9a57
--- /dev/null
+++ b/src/components/settingComponents/locations.jsx
@@ -0,0 +1,348 @@
+import countryList from "react-select-country-list";
+
+export function Locations() {
+ return (
+
+
+
+ Afghanistan
+ Åland Islands
+ Albania
+ Algeria
+ American Samoa
+ Andorra
+ Angola
+ Anguilla
+ Antarctica
+
+ Antigua and Barbuda
+
+ Argentina
+ Armenia
+ Aruba
+ Australia
+ Austria
+ Azerbaijan
+ Bahamas
+ Bahrain
+ Bangladesh
+ Barbados
+ Belarus
+ Belgium
+ Belize
+ Benin
+ Bermuda
+ Bhutan
+ Bolivia
+
+ Bosnia and Herzegovina
+
+ Botswana
+ Bouvet Island
+ Brazil
+
+ British Indian Ocean Territory
+
+
+ Brunei Darussalam
+
+ Bulgaria
+ Burkina Faso
+ Burundi
+ Cambodia
+ Cameroon
+ Canada
+ Cape Verde
+ Cayman Islands
+
+ Central African Republic
+
+ Chad
+ Chile
+ China
+
+ Christmas Island
+
+
+ Cocos (Keeling) Islands
+
+ Colombia
+ Comoros
+ Congo
+
+ Congo, The Democratic Republic of The
+
+ Cook Islands
+ Costa Rica
+ Cote D'ivoire
+ Croatia
+ Cuba
+ Cyprus
+ Czech Republic
+ Denmark
+ Djibouti
+ Dominica
+
+ Dominican Republic
+
+ Ecuador
+ Egypt
+ El Salvador
+
+ Equatorial Guinea
+
+ Eritrea
+ Estonia
+ Ethiopia
+
+ Falkland Islands (Malvinas)
+
+ Faroe Islands
+ Fiji
+ Finland
+ France
+ French Guiana
+
+ French Polynesia
+
+
+ French Southern Territories
+
+ Gabon
+ Gambia
+ Georgia
+ Germany
+ Ghana
+ Gibraltar
+ Greece
+ Greenland
+ Grenada
+ Guadeloupe
+ Guam
+ Guatemala
+ Guernsey
+ Guinea
+ Guinea-bissau
+ Guyana
+ Haiti
+
+ Heard Island and Mcdonald Islands
+
+
+ Holy See (Vatican City State)
+
+ Honduras
+ Hong Kong
+ Hungary
+ Iceland
+ India
+ Indonesia
+
+ Iran, Islamic Republic of
+
+ Iraq
+ Ireland
+ Isle of Man
+ Israel
+ Italy
+ Jamaica
+ Japan
+ Jersey
+ Jordan
+ Kazakhstan
+ Kenya
+ Kiribati
+
+ Korea, Democratic People's Republic of
+
+
+ Korea, Republic of
+
+ Kuwait
+ Kyrgyzstan
+
+ Lao People's Democratic Republic
+
+ Latvia
+ Lebanon
+ Lesotho
+ Liberia
+
+ Libyan Arab Jamahiriya
+
+ Liechtenstein
+ Lithuania
+ Luxembourg
+ Macao
+
+ Macedonia, The Former Yugoslav Republic of
+
+ Madagascar
+ Malawi
+ Malaysia
+ Maldives
+ Mali
+ Malta
+
+ Marshall Islands
+
+ Martinique
+ Mauritania
+ Mauritius
+ Mayotte
+ Mexico
+
+ Micronesia, Federated States of
+
+
+ Moldova, Republic of
+
+ Monaco
+ Mongolia
+ Montenegro
+ Montserrat
+ Morocco
+ Mozambique
+ Myanmar
+ Namibia
+ Nauru
+ Nepal
+ Netherlands
+
+ Netherlands Antilles
+
+ New Caledonia
+ New Zealand
+ Nicaragua
+ Niger
+ Nigeria
+ Niue
+ Norfolk Island
+
+ Northern Mariana Islands
+
+ Norway
+ Oman
+ Pakistan
+ Palau
+
+ Palestinian Territory, Occupied
+
+ Panama
+
+ Papua New Guinea
+
+ Paraguay
+ Peru
+ Philippines
+ Pitcairn
+ Poland
+ Portugal
+ Puerto Rico
+ Qatar
+ Reunion
+ Romania
+
+ Russian Federation
+
+ Rwanda
+ Saint Helena
+
+ Saint Kitts and Nevis
+
+ Saint Lucia
+
+ Saint Pierre and Miquelon
+
+
+ Saint Vincent and The Grenadines
+
+ Samoa
+ San Marino
+
+ Sao Tome and Principe
+
+ Saudi Arabia
+ Senegal
+ Serbia
+ Seychelles
+ Sierra Leone
+ Singapore
+ Slovakia
+ Slovenia
+ Solomon Islands
+ Somalia
+ South Africa
+
+ South Georgia and The South Sandwich Islands
+
+ Spain
+ Sri Lanka
+ Sudan
+ Suriname
+
+ Svalbard and Jan Mayen
+
+ Swaziland
+ Sweden
+ Switzerland
+
+ Syrian Arab Republic
+
+ Taiwan
+ Tajikistan
+
+ Tanzania, United Republic of
+
+ Thailand
+ Timor-leste
+ Togo
+ Tokelau
+ Tonga
+
+ Trinidad and Tobago
+
+ Tunisia
+ Turkey
+ Turkmenistan
+
+ Turks and Caicos Islands
+
+ Tuvalu
+ Uganda
+ Ukraine
+
+ United Arab Emirates
+
+ United Kingdom
+ United States
+
+ United States Minor Outlying Islands
+
+ Uruguay
+ Uzbekistan
+ Vanuatu
+ Venezuela
+ Viet Nam
+
+ Virgin Islands, British
+
+
+ Virgin Islands, U.S.
+
+
+ Wallis and Futuna
+
+ Western Sahara
+ Yemen
+ Zambia
+ Zimbabwe
+
+ );
+
+}
diff --git a/src/components/settingComponents/sidebar.jsx b/src/components/settingComponents/sidebar.jsx
new file mode 100644
index 00000000..b6195ce2
--- /dev/null
+++ b/src/components/settingComponents/sidebar.jsx
@@ -0,0 +1,41 @@
+import Link from 'next/link';
+import { useRouter } from 'next/router'
+
+export default function Sidebar() {
+ const router = useRouter()
+ return (
+
+
+
+ router.push('../settings', null, { shallow: true })}>
+ General
+
+
+
+
+ router.push('../settings/security', null, { shallow: true })}>
+ Security
+
+
+
+ router.push('../settings/preferences', null, { shallow: true })}>
+ Email Preferences
+
+
+
+
+ router.push('../settings/billing', null, { shallow: true })}>
+ Billing
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/pages/settings.jsx b/src/pages/settings.jsx
index ab6d273d..7ba5f67f 100644
--- a/src/pages/settings.jsx
+++ b/src/pages/settings.jsx
@@ -3,11 +3,9 @@ import { Footer } from '@/components/Footer';
import { StandardNav } from '@/components/StandardNav';
import { useEffect } from 'react';
import { useState } from 'react';
-import { getStorage, ref, uploadBytesResumable, getDownloadURL } from 'firebase/storage';
import { getCookie } from '@/utils/request';
-import { Transition, Dialog } from '@headlessui/react';
-import { Fragment } from 'react';
-import request from "@/utils/request";
+import General from '@/components/settingComponents/generalPage';
+import Sidebar from '@/components/settingComponents/sidebar';
import {
updatePassword,
@@ -38,111 +36,14 @@ export default function Dashboard() {
const [billing, setbilling] = useState(false);
const [username, setUsername] = useState('');
-
- const [selectedImage, setSelectedImage] = useState(null);
- const [isPopupOpen, setIsPopupOpen] = useState(false);
- const [pfp, setPfp] = useState(`https://robohash.org/KshitijIsCool.png?set=set1&size=150x150`);
-
-
-
var pfpString = '';
var pfpChanged = false;
const auth = getAuth();
const user = auth.currentUser;
- const handlePopupOpen = () => {
- setIsPopupOpen(true);
- }
-
-
- const handlePopupClose = () => {
- setIsPopupOpen(false);
- }
- const handleImageChange = (event) => {
- const file = event.target.files[0];
- setSelectedImage(file);
- }
-
-
- const handleSaveChanges = async () => {
- if (!selectedImage) {
- console.log("No image selected");
- setIsPopupOpen(false)
- return;
- }
-
-
- // upload to firebase storage
- try {
- const storage = getStorage();
- const metadata = {
- contentType: 'image/jpeg',
- };
-
-
- const storageRef = ref(storage, `${email}/pictures/pfp`);
- const uploadTask = uploadBytesResumable(storageRef, selectedImage, metadata)
-
-
- uploadTask.on('state_changed',
- (snapshot) => {
- // progress function
- const progress = Math.round((snapshot.bytesTransferred / snapshot.totalBytes) * 100);
- console.log('Upload is ' + progress + '% done');
- switch (snapshot.state) {
- case 'paused':
- console.log('Upload is paused');
- break;
- case 'running':
- console.log('Upload is running');
- break;
- }
- },
- (error) => {
- switch (error.code) {
- case 'storage/unauthorized':
- console.log('User does not have permission to access the object');
- break;
- case 'storage/canceled':
- console.log('User canceled the upload');
- break;
- case 'storage/unknown':
- console.log('Unknown error occurred, inspect error.serverResponse');
- break;
- }
- },
- async () => {
- const imageUrl = await getDownloadURL(uploadTask.snapshot.ref)
- console.log(imageUrl)
- console.log(user);
- const endPoint = process.env.NEXT_PUBLIC_API_URL + '/users/' + username + '/updatePfp';
- const body = { imageUrl }
- const response = await request(endPoint, "POST", body);
- console.log("Here is the result: ", response)
- if (response.success) {
- console.log("profile picture uploaded successfully");
- } else {
- console.log("Failed to upload profile picture");
- }
- window.location.reload();
-
- }
- );
- setIsPopupOpen(false);
-
-
- } catch (err) {
- console.log(err);
- console.log("An error occured while uploading profile picture");
- }
- }
-
- const handleClick = () => {
-
- }
-
+ const handleClick = () => {}
useEffect(() => {
const fileInput = document.getElementById('fileInput');
@@ -158,9 +59,6 @@ export default function Dashboard() {
setUsername(JSON.parse(this.responseText).username);
}
-
-
-
} catch (e) {
console.log(e);
}
@@ -260,158 +158,7 @@ export default function Dashboard() {
}
}
- const redirectToCheckout = async (event) => {
- try {
- const stripe = await loadStripe(STRIPE_KEY);
- const subscriptionType = document.getElementById('paymentType').value;
- console.log(subscriptionType);
-
- const response = await fetch(
- `${process.env.NEXT_PUBLIC_API_URL}/payments/stripe/create-checkout-session`,
- {
- method: 'POST',
- body: JSON.stringify({
- subType: subscriptionType,
- quantity: 1,
- operation: 'subscription',
- data: {},
- }),
- headers: {
- 'Content-Type': 'application/json',
- },
- credentials: 'include'
- }
- );
-
- const session = await response.json();
- if (session.error) {
- console.log('Creating the stripe session failed');
- return;
- }
-
- const result = await stripe.redirectToCheckout({
- sessionId: session.sessionId,
- });
-
- if (result.error) {
- console.log(result.error.message);
- }
- } catch (error) {
- console.log(error);
- }
- };
-
- const updateCardInfo = async () => {
- try {
- const stripe = await loadStripe(STRIPE_KEY);
- const subscriptionType = document.getElementById('paymentType').value;
-
- const response = await fetch(
- `${process.env.NEXT_PUBLIC_API_URL}/payments/stripe/update-card`,
- {
- method: 'POST',
- credentials: 'include',
- body: JSON.stringify({
- subType: subscriptionType,
- }),
- headers: {
- 'Content-Type': 'application/json',
- },
- }
- );
-
- const session = await response.json();
-
- await stripe.redirectToCheckout({
- sessionId: session.sessionId,
- });
- } catch (error) {
- console.log(error);
- }
- };
-
- const cancelSubscription = async () => {
- try {
- const subscriptionType = document.getElementById('paymentType').value;
- const url = `${process.env.NEXT_PUBLIC_API_URL}/payments/stripe/cancel`;
- const response = await fetch(url, {
- method: 'PUT',
- credentials: 'include',
- body: JSON.stringify({
- subType: subscriptionType,
- }),
- headers: {
- 'Content-Type': 'application/json',
- },
- });
- const data = await response.json();
- console.log(data.message);
- } catch (err) {
- console.log(err);
- }
- };
-
- function saveGeneral() {
- document.getElementById('save').innerHTML = 'Saving...';
-
- var firstName = document.getElementById('first-name').value;
- var lastName = document.getElementById('last-name').value;
- var bio = document.getElementById('bio').value;
- var github = document.getElementById('url').value;
- var location = document.getElementById('location').value;
-
- var data = JSON.stringify({
- bio: bio,
- githubUrl: github,
- firstName: firstName,
- lastName: lastName,
- location: location,
- });
-
- var xhr = new XMLHttpRequest();
-
- xhr.addEventListener('readystatechange', function() {
- if (this.readyState === 4) {
- console.log(this.responseText);
- document.getElementById('save').innerHTML = 'Save';
- }
- });
-
- xhr.open('PUT', `${process.env.NEXT_PUBLIC_API_URL}/account`);
- xhr.setRequestHeader('Content-Type', 'application/json');
- let token = getCookie();
- xhr.setRequestHeader('Authorization', 'Bearer ' + token);
- xhr.withCredentials = true;
- xhr.send(data);
-
- }
-
- function savePreferences() {
- document.getElementById('savePreferences').innerHTML = 'Saving...';
-
- var data = JSON.stringify({
- FRIEND_ACCEPT: document.getElementById('friend-notif').checked,
- CHALLENGE_VERIFY: document.getElementById('challenge-notif').checked,
- });
-
- var xhr = new XMLHttpRequest();
-
- xhr.addEventListener('readystatechange', function() {
- if (this.readyState === 4) {
- document.getElementById('savePreferences').innerHTML = 'Save';
- }
- });
-
- xhr.open('PUT', `${process.env.NEXT_PUBLIC_API_URL}/account/preferences`);
-
- xhr.setRequestHeader('Content-Type', 'application/json');
- let token = getCookie();
- xhr.setRequestHeader('Authorization', 'Bearer ' + token);
- xhr.withCredentials = true;
-
- xhr.send(data);
- }
-
+
function loadPreferences() {
// WARNING: For GET requests, body is set to null by browsers.
@@ -442,40 +189,8 @@ export default function Dashboard() {
xhr.send();
}
- function saveSecurity() {
- document.getElementById('saveSecurity').innerText = 'Saving...';
- var oldPassword = document.getElementById('oldPassword').value;
-
- reauthenticateWithCredential(
- user,
- EmailAuthProvider.credential(user.email, oldPassword)
- )
- .then(() => {
- var password = document.getElementById('password').value;
- var confirmPassword = document.getElementById('confirm-password').value;
- if (password == confirmPassword) {
- updatePassword(user, confirmPassword)
- .then(() => {
- document.getElementById('saveSecurity').innerText = 'Save';
-
- document.getElementById('password').value = '';
- document.getElementById('confirm-password').value = '';
- })
- .catch((error) => {
- document.getElementById('saveSecurity').innerText = 'Save';
-
- window.alert(error);
- });
- }
- })
- .catch((error) => {
- document.getElementById('saveSecurity').innerText = 'Save';
- window.alert(error);
- });
- }
-
- return (
+ return (
<>
User Settings
@@ -491,1157 +206,21 @@ export default function Dashboard() {
- {general && (
-
-
-
-
-
-
- {' '}
- General
-
-
-
-
- Security
-
-
-
-
- Email Preferences
-
-
-
-
- Billing
-
-
-
-
-
-
-
-
- General
-
-
-
-
-
-
- Profile
-
-
- This information will be displayed publicly so be
- careful what you share.
-
-
-
-
-
- First name
-
-
-
-
-
-
- Last name
-
-
-
-
-
-
-
-
- Profile Picture
-
-
-
-
-
-
handlePopupOpen()} className="ml-4 bg-neutral cursor:pointer block rounded-md px-3 py-2 text-sm font-semibold text-white shadow-sm ring-1 ring-inset ring-slate-300 hover:bg-neutral-800 peer-focus:ring-2 peer-focus:ring-blue-600">
- Change
-
-
-
-
-
-
-
- Bio
-
-
-
-
-
- Brief description for your profile. URLs are
- hyperlinked.
-
-
-
-
-
- Github Username
-
-
-
- Your GitHub link: github.com/{inputText}
-
-
-
-
-
-
-
- Personal Information
-
-
- This information will be displayed publicly so be
- careful what you share.
-
-
-
-
-
- Email address
-
-
-
-
-
-
- Location
-
-
- Afghanistan
- Åland Islands
- Albania
- Algeria
- American Samoa
- Andorra
- Angola
- Anguilla
- Antarctica
-
- Antigua and Barbuda
-
- Argentina
- Armenia
- Aruba
- Australia
- Austria
- Azerbaijan
- Bahamas
- Bahrain
- Bangladesh
- Barbados
- Belarus
- Belgium
- Belize
- Benin
- Bermuda
- Bhutan
- Bolivia
-
- Bosnia and Herzegovina
-
- Botswana
- Bouvet Island
- Brazil
-
- British Indian Ocean Territory
-
-
- Brunei Darussalam
-
- Bulgaria
- Burkina Faso
- Burundi
- Cambodia
- Cameroon
- Canada
- Cape Verde
- Cayman Islands
-
- Central African Republic
-
- Chad
- Chile
- China
-
- Christmas Island
-
-
- Cocos (Keeling) Islands
-
- Colombia
- Comoros
- Congo
-
- Congo, The Democratic Republic of The
-
- Cook Islands
- Costa Rica
- Cote D'ivoire
- Croatia
- Cuba
- Cyprus
- Czech Republic
- Denmark
- Djibouti
- Dominica
-
- Dominican Republic
-
- Ecuador
- Egypt
- El Salvador
-
- Equatorial Guinea
-
- Eritrea
- Estonia
- Ethiopia
-
- Falkland Islands (Malvinas)
-
- Faroe Islands
- Fiji
- Finland
- France
- French Guiana
-
- French Polynesia
-
-
- French Southern Territories
-
- Gabon
- Gambia
- Georgia
- Germany
- Ghana
- Gibraltar
- Greece
- Greenland
- Grenada
- Guadeloupe
- Guam
- Guatemala
- Guernsey
- Guinea
- Guinea-bissau
- Guyana
- Haiti
-
- Heard Island and Mcdonald Islands
-
-
- Holy See (Vatican City State)
-
- Honduras
- Hong Kong
- Hungary
- Iceland
- India
- Indonesia
-
- Iran, Islamic Republic of
-
- Iraq
- Ireland
- Isle of Man
- Israel
- Italy
- Jamaica
- Japan
- Jersey
- Jordan
- Kazakhstan
- Kenya
- Kiribati
-
- Korea, Democratic People's Republic of
-
-
- Korea, Republic of
-
- Kuwait
- Kyrgyzstan
-
- Lao People's Democratic Republic
-
- Latvia
- Lebanon
- Lesotho
- Liberia
-
- Libyan Arab Jamahiriya
-
- Liechtenstein
- Lithuania
- Luxembourg
- Macao
-
- Macedonia, The Former Yugoslav Republic of
-
- Madagascar
- Malawi
- Malaysia
- Maldives
- Mali
- Malta
-
- Marshall Islands
-
- Martinique
- Mauritania
- Mauritius
- Mayotte
- Mexico
-
- Micronesia, Federated States of
-
-
- Moldova, Republic of
-
- Monaco
- Mongolia
- Montenegro
- Montserrat
- Morocco
- Mozambique
- Myanmar
- Namibia
- Nauru
- Nepal
- Netherlands
-
- Netherlands Antilles
-
- New Caledonia
- New Zealand
- Nicaragua
- Niger
- Nigeria
- Niue
- Norfolk Island
-
- Northern Mariana Islands
-
- Norway
- Oman
- Pakistan
- Palau
-
- Palestinian Territory, Occupied
-
- Panama
-
- Papua New Guinea
-
- Paraguay
- Peru
- Philippines
- Pitcairn
- Poland
- Portugal
- Puerto Rico
- Qatar
- Reunion
- Romania
-
- Russian Federation
-
- Rwanda
- Saint Helena
-
- Saint Kitts and Nevis
-
- Saint Lucia
-
- Saint Pierre and Miquelon
-
-
- Saint Vincent and The Grenadines
-
- Samoa
- San Marino
-
- Sao Tome and Principe
-
- Saudi Arabia
- Senegal
- Serbia
- Seychelles
- Sierra Leone
- Singapore
- Slovakia
- Slovenia
- Solomon Islands
- Somalia
- South Africa
-
- South Georgia and The South Sandwich Islands
-
- Spain
- Sri Lanka
- Sudan
- Suriname
-
- Svalbard and Jan Mayen
-
- Swaziland
- Sweden
- Switzerland
-
- Syrian Arab Republic
-
- Taiwan
- Tajikistan
-
- Tanzania, United Republic of
-
- Thailand
- Timor-leste
- Togo
- Tokelau
- Tonga
-
- Trinidad and Tobago
-
- Tunisia
- Turkey
- Turkmenistan
-
- Turks and Caicos Islands
-
- Tuvalu
- Uganda
- Ukraine
-
- United Arab Emirates
-
- United Kingdom
- United States
-
- United States Minor Outlying Islands
-
- Uruguay
- Uzbekistan
- Vanuatu
- Venezuela
- Viet Nam
-
- Virgin Islands, British
-
-
- Virgin Islands, U.S.
-
-
- Wallis and Futuna
-
- Western Sahara
- Yemen
- Zambia
- Zimbabwe
-
-
-
-
- {/* PROFILE PICTURE POP-UP */}
-
-
- handlePopupClose()}>
-
-
-
- {
- handlePopupClose()
- localStorage.setItem("22-18-update", false)
- }}
- className="fixed inset-0 bg-gray-900 bg-opacity-75 transition-opacity" />
-
-
-
-
-
-
-
Change Profile Picture
-
-
-
-
-
- Current Profile Picture
-
-
-
- {/* INPUT BOX */}
-
-
- {selectedImage ? (
-
-
-
- New Profile Picture
-
-
- ) : (
-
-
-
-
-
Click here or Drag an Image!
-
- )}
-
-
-
-
-
-
- handlePopupClose()}>Close
-
-
-
- handleSaveChanges()}>Save
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Save
-
-
-
-
-
-
-
- )}
-
- {billing && (
-
-
-
-
-
-
- {' '}
- General
-
-
-
-
- Security
-
-
-
-
- Email Preferences
-
-
-
-
- Billing
-
-
-
+
+
+
+ {general && (
+
+ {/*CONTAINING THE BODY OF GENERAL SECTION*/}
+
+ )}
-
-
-
- Billing
-
-
-
-
-
-
FREE
- Standard Account
-
-
-
- CHANGE PLAN
-
-
-
-
- Usage Limits
-
-
-
-
- Terminal Usage
-
-
- 0%{' '}
-
-
-
-
-
-
- CPU Burst Usage
-
- 0%
-
-
-
-
- Container Hardware: Standard Compute
-
-
-
-
- CTFGuide currently has a very generous grant from Google Cloud
- Platform, which allows us to provide free compute to our
- users. However, this grant is limited, and we may have to
- start charging for compute in the future. If we do, we will
- give you a 30 day notice before we start charging for compute.
-
-
-
-
-
- Upgrade to{' '}
-
- CTFGuide Pro
-
-
-
-
-
Monthly
- $4.99/month
-
-
-
Annually
- $35.88/year
-
-
-
- What do you get?
-
-
-
Access to exclusive learning content.
-
-
-
Show of an exclusive CTFGuide Pro badge
-
-
-
Animated profile pictures**
-
-
-
Increased container time
-
-
-
- * For the features marked with a star, it means it has not
- been released yet. For every month you have CTFGuide Pro, if
- the feature has not been implemented yet, you'll be given an
- additional free month of Pro.
-
-
-
-
-
- Dev Testing
-
-
- CTFGuidePro
-
- CTFGuideStudentsEDU
-
-
- CTFGuideInstitutionEDU
-
-
-
-
-
- Stripe Checkout Demo
-
-
-
-
- Update card infomation
-
-
- cancel subscription
-
-
-
-
-
-
- )}
-
- {security && (
-
-
-
-
-
-
- {' '}
- General
-
-
-
-
- Security
-
-
-
-
- Email Preferences
-
-
-
-
- Billing
-
-
-
-
-
-
-
-
- Security
-
-
-
-
-
-
- Password Management
-
-
- Change your password
-
-
-
-
-
- New Password
-
-
-
-
-
-
- Confirm Password
-
-
-
-
-
-
- Current Password
-
-
-
-
-
-
- Save
-
-
-
-
-
-
- )}
-
- {preferences && (
-
-
-
-
-
-
- {' '}
- General
-
-
-
-
- Security
-
-
-
-
- Email Preferences
-
-
-
-
- Billing
-
-
-
-
-
-
-
-
- Email Preferences
-
-
-
-
- Notifications
-
-
-
-
-
-
-
- Friend Requests
-
-
-
-
-
-
-
-
-
-
- Creator Notifications
-
-
- Get notified when your challenges get verified.
-
-
-
-
-
-
-
-
- Save
-
-
-
-
-
-
-
- )}
+
+
>
);
}
+
diff --git a/src/pages/settings/billing.jsx b/src/pages/settings/billing.jsx
new file mode 100644
index 00000000..2a61c5ea
--- /dev/null
+++ b/src/pages/settings/billing.jsx
@@ -0,0 +1,284 @@
+
+import { loadStripe } from '@stripe/stripe-js';
+const STRIPE_KEY = process.env.NEXT_PUBLIC_APP_STRIPE_KEY;
+import Head from 'next/head';
+import { Footer } from '@/components/Footer';
+import { StandardNav } from '@/components/StandardNav';
+import Sidebar from '@/components/settingComponents/sidebar';
+
+export default function Billing(){
+
+
+
+
+
+ const redirectToCheckout = async (event) => {
+ try {
+ const stripe = await loadStripe(STRIPE_KEY);
+ const subscriptionType = document.getElementById('paymentType').value;
+ console.log(subscriptionType);
+
+ const response = await fetch(
+ `${process.env.NEXT_PUBLIC_API_URL}/payments/stripe/create-checkout-session`,
+ {
+ method: 'POST',
+ body: JSON.stringify({
+ subType: subscriptionType,
+ quantity: 1,
+ operation: 'subscription',
+ data: {},
+ }),
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ credentials: 'include'
+ }
+ );
+
+ const session = await response.json();
+ if (session.error) {
+ console.log('Creating the stripe session failed');
+ return;
+ }
+
+ const result = await stripe.redirectToCheckout({
+ sessionId: session.sessionId,
+ });
+
+ if (result.error) {
+ console.log(result.error.message);
+ }
+ } catch (error) {
+ console.log(error);
+ }g
+ };
+
+ const updateCardInfo = async () => {
+ try {
+ const stripe = await loadStripe(STRIPE_KEY);
+ const subscriptionType = document.getElementById('paymentType').value;
+
+ const response = await fetch(
+ `${process.env.NEXT_PUBLIC_API_URL}/payments/stripe/update-card`,
+ {
+ method: 'POST',
+ credentials: 'include',
+ body: JSON.stringify({
+ subType: subscriptionType,
+ }),
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ }
+ );
+
+ const session = await response.json();
+
+ await stripe.redirectToCheckout({
+ sessionId: session.sessionId,
+ });
+ } catch (error) {
+ console.log(error);
+ }
+ };
+
+ const cancelSubscription = async () => {
+ try {
+ const subscriptionType = document.getElementById('paymentType').value;
+ const url = `${process.env.NEXT_PUBLIC_API_URL}/payments/stripe/cancel`;
+ const response = await fetch(url, {
+ method: 'PUT',
+ credentials: 'include',
+ body: JSON.stringify({
+ subType: subscriptionType,
+ }),
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ });
+ const data = await response.json();
+ console.log(data.message);
+ } catch (err) {
+ console.log(err);
+ }
+ };
+
+ return(
+ <>
+
+
User Settings
+
+
+
+
+
+
+
+
+
+
+
+
+ Billing
+
+
+
+
+
+
FREE
+ Standard Account
+
+
+
+ CHANGE PLAN
+
+
+
+
+ Usage Limits
+
+
+
+
+ Terminal Usage
+
+
+ 0%{' '}
+
+
+
+
+
+
+ CPU Burst Usage
+
+ 0%
+
+
+
+
+ Container Hardware: Standard Compute
+
+
+
+
+ CTFGuide currently has a very generous grant from Google Cloud
+ Platform, which allows us to provide free compute to our
+ users. However, this grant is limited, and we may have to
+ start charging for compute in the future. If we do, we will
+ give you a 30 day notice before we start charging for compute.
+
+
+
+
+
+ Upgrade to{' '}
+
+ CTFGuide Pro
+
+
+
+
+
Monthly
+ $4.99/month
+
+
+
Annually
+ $35.88/year
+
+
+
+ What do you get?
+
+
+
Access to exclusive learning content.
+
+
+
Show of an exclusive CTFGuide Pro badge
+
+
+
Animated profile pictures**
+
+
+
Increased container time
+
+
+
+ * For the features marked with a star, it means it has not
+ been released yet. For every month you have CTFGuide Pro, if
+ the feature has not been implemented yet, you'll be given an
+ additional free month of Pro.
+
+
+
+
+
+ Dev Testing
+
+
+ CTFGuidePro
+
+ CTFGuideStudentsEDU
+
+
+ CTFGuideInstitutionEDU
+
+
+
+
+
+ Stripe Checkout Demo
+
+
+
+
+ Update card infomation
+
+
+ cancel subscription
+
+
+
+
+
+
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/src/pages/settings/general.jsx b/src/pages/settings/general.jsx
new file mode 100644
index 00000000..6055405c
--- /dev/null
+++ b/src/pages/settings/general.jsx
@@ -0,0 +1,526 @@
+
+import React from 'react'
+import { useState } from 'react';
+import { Transition, Dialog } from '@headlessui/react';
+import { Fragment } from 'react';
+import { Locations } from '@/components/settingComponents/locations';
+import { useRouter } from 'next/router';
+import { getStorage, ref, uploadBytesResumable, getDownloadURL } from 'firebase/storage';
+import { getCookie } from '@/utils/request';
+import { useEffect } from 'react';
+import Head from 'next/head';
+import { Footer } from '@/components/Footer';
+import { StandardNav } from '@/components/StandardNav';
+import Sidebar from '@/components/settingComponents/sidebar';
+export default function General(){
+
+
+ const router = useRouter();
+
+ const [isPopupOpen, setIsPopupOpen] = useState(false);
+ const [selectedImage, setSelectedImage] = useState(null);
+
+ const [inputText, setInputText] = useState('');
+
+ const handleInputChange = (event) => {
+ setInputText(event.target.value);
+ };
+ const [pfp, setPfp] = useState(`https://robohash.org/KshitijIsCool.png?set=set1&size=150x150`);
+ const [open, setOpen] = useState(true);
+
+ var pfpString = '';
+ var pfpChanged = false;
+
+ function pfpChange() {
+ pfpChanged = true;
+ }
+
+ const handlePopupOpen = () => {
+ setIsPopupOpen(true);
+ }
+
+ useEffect(() => {
+ const fileInput = document.getElementById('fileInput');
+
+
+ var xhr = new XMLHttpRequest();
+
+ xhr.addEventListener('readystatechange', function() {
+ if (this.readyState === 4) {
+ console.log(this.responseText);
+ try {
+ if (document.getElementById('first-name')) {
+
+ setUsername(JSON.parse(this.responseText).username);
+ }
+
+ } catch (e) {
+ console.log(e);
+ }
+ }
+ });
+
+ xhr.open('GET', `${process.env.NEXT_PUBLIC_API_URL}/account`);
+ let token = getCookie();
+ xhr.setRequestHeader('Authorization', 'Bearer ' + token);
+ xhr.withCredentials = true;
+ xhr.send();
+ }, []);
+
+ const handlePopupClose = () => {
+ setIsPopupOpen(false);
+ }
+
+ const handleImageChange = (event) => {
+ const file = event.target.files[0];
+ setSelectedImage(file);
+ }
+
+ const handleSaveChanges = async () => {
+ if (!selectedImage) {
+ console.log("No image selected");
+ setIsPopupOpen(false)
+ return;
+ }
+
+
+ // upload to firebase storage
+ try {
+ const storage = getStorage();
+ const metadata = {
+ contentType: 'image/jpeg',
+ };
+
+ const storageRef = ref(storage, `${email}/pictures/pfp`);
+ const uploadTask = uploadBytesResumable(storageRef, selectedImage, metadata)
+
+ uploadTask.on('state_changed',
+ (snapshot) => {
+ // progress function
+ const progress = Math.round((snapshot.bytesTransferred / snapshot.totalBytes) * 100);
+ console.log('Upload is ' + progress + '% done');
+ switch (snapshot.state) {
+ case 'paused':
+ console.log('Upload is paused');
+ break;
+ case 'running':
+ console.log('Upload is running');
+ break;
+ }
+ },
+ (error) => {
+ switch (error.code) {
+ case 'storage/unauthorized':
+ console.log('User does not have permission to access the object');
+ break;
+ case 'storage/canceled':
+ console.log('User canceled the upload');
+ break;
+ case 'storage/unknown':
+ console.log('Unknown error occurred, inspect error.serverResponse');
+ break;
+ }
+ },
+ async () => {
+ const imageUrl = await getDownloadURL(uploadTask.snapshot.ref)
+ console.log(imageUrl)
+ console.log(user);
+ const endPoint = process.env.NEXT_PUBLIC_API_URL + '/users/' + username + '/updatePfp';
+ const body = { imageUrl }
+ const response = await request(endPoint, "POST", body);
+ console.log("Here is the result: ", response)
+ if (response.success) {
+ console.log("profile picture uploaded successfully");
+ } else {
+ console.log("Failed to upload profile picture");
+ }
+ window.location.reload();
+ console.log('test');
+ }
+ );
+ setIsPopupOpen(false);
+
+
+ } catch (err) {
+ console.log(err);
+ console.log("An error occured while uploading profile picture");
+ }
+ }
+
+ const handleClick = () => {}
+
+ function saveGeneral() {
+ document.getElementById('save').innerHTML = 'Saving...';
+
+ var firstName = document.getElementById('first-name').value;
+ var lastName = document.getElementById('last-name').value;
+ var bio = document.getElementById('bio').value;
+ var github = document.getElementById('url').value;
+ var location = document.getElementById('location').value;
+
+ var data = JSON.stringify({
+ bio: bio,
+ githubUrl: github,
+ firstName: firstName,
+ lastName: lastName,
+ location: location,
+ });
+
+ var xhr = new XMLHttpRequest();
+
+ xhr.addEventListener('readystatechange', function() {
+ if (this.readyState === 4) {
+ console.log(this.responseText);
+ document.getElementById('save').innerHTML = 'Save';
+ }
+ });
+
+ xhr.open('PUT', `${process.env.NEXT_PUBLIC_API_URL}/account`);
+ xhr.setRequestHeader('Content-Type', 'application/json');
+ let token = getCookie();
+ xhr.setRequestHeader('Authorization', 'Bearer ' + token);
+ xhr.withCredentials = true;
+ xhr.send(data);
+
+ }
+
+ return(
+ <>
+
+
User Settings
+
+
+
+
+
+
+
+
+
+
+
+
+ General
+
+
+
+
+
+
+ Profile
+
+
+ This information will be displayed publicly so be
+ careful what you share.
+
+
+
+
+
+ First name
+
+
+
+
+
+
+ Last name
+
+
+
+
+
+
+
+
+ Profile Picture
+
+
+
+
+
+
handlePopupOpen()} className="ml-4 bg-neutral cursor:pointer block rounded-md px-3 py-2 text-sm font-semibold text-white shadow-sm ring-1 ring-inset ring-slate-300 hover:bg-neutral-800 peer-focus:ring-2 peer-focus:ring-blue-600">
+ Change
+
+
+
+
+
+
+
+ Bio
+
+
+
+
+
+ Brief description for your profile. URLs are
+ hyperlinked.
+
+
+
+
+
+ Github Username
+
+
+
+ Your GitHub link: github.com/{inputText}
+
+
+
+
+
+
+
+ Personal Information
+
+
+ This information will be displayed publicly so be
+ careful what you share.
+
+
+
+
+
+ Email address
+
+
+
+
+ {/* LOCATION OPTIONS */}
+
+
+ Location
+
+
+
+
+
+ {/* PROFILE PICTURE POP-UP */}
+
+
+ handlePopupClose()}>
+
+
+
+ {
+ handlePopupClose()
+ localStorage.setItem("22-18-update", false)
+ }}
+ className="fixed inset-0 bg-gray-900 bg-opacity-75 transition-opacity" />
+
+
+
+
+
+
+
Change Profile Picture
+
+
+
+
+
+ Current Profile Picture
+
+
+
+ {/* INPUT BOX */}
+
+
+ {selectedImage ? (
+
+
+
+ New Profile Picture
+
+
+ ) : (
+
+
+
+
+
Click here or Drag an Image!
+
+ )}
+
+
+
+
+
+
+ handlePopupClose()}>Close
+
+
+
+ handleSaveChanges()}>Save
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Save
+
+
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/src/pages/settings/preferences.jsx b/src/pages/settings/preferences.jsx
new file mode 100644
index 00000000..a8242ee3
--- /dev/null
+++ b/src/pages/settings/preferences.jsx
@@ -0,0 +1,165 @@
+import { getCookie } from '@/utils/request';
+import Head from 'next/head';
+import { Footer } from '@/components/Footer';
+import { StandardNav } from '@/components/StandardNav';
+import Sidebar from '@/components/settingComponents/sidebar';
+export default function Preferences(){
+ function loadPreferences() {
+ // WARNING: For GET requests, body is set to null by browsers.
+
+ var xhr = new XMLHttpRequest();
+
+ xhr.addEventListener('readystatechange', function() {
+ if (this.readyState === 4) {
+ console.log(this.responseText);
+ console.log('PREFFF');
+ try {
+ if (JSON.parse(this.responseText)[0].value == true) {
+ document.getElementById('friend-notif').checked = true;
+ }
+
+ if (JSON.parse(this.responseText)[1].value == true) {
+ document.getElementById('challenge-notif').checked = true;
+ }
+ } catch (error) {
+ // .alert(error)
+ }
+ }
+ });
+
+ xhr.open('GET', `${process.env.NEXT_PUBLIC_API_URL}/account/preferences`);
+ let token = getCookie();
+ xhr.setRequestHeader('Authorization', 'Bearer ' + token);
+ xhr.withCredentials = true;
+ xhr.send();
+ }
+
+ function savePreferences() {
+ document.getElementById('savePreferences').innerHTML = 'Saving...';
+
+ var data = JSON.stringify({
+ FRIEND_ACCEPT: document.getElementById('friend-notif').checked,
+ CHALLENGE_VERIFY: document.getElementById('challenge-notif').checked,
+ });
+
+ var xhr = new XMLHttpRequest();
+
+ xhr.addEventListener('readystatechange', function() {
+ if (this.readyState === 4) {
+ document.getElementById('savePreferences').innerHTML = 'Save';
+ }
+ });
+
+ xhr.open('PUT', `${process.env.NEXT_PUBLIC_API_URL}/account/preferences`);
+
+ xhr.setRequestHeader('Content-Type', 'application/json');
+ let token = getCookie();
+ xhr.setRequestHeader('Authorization', 'Bearer ' + token);
+ xhr.withCredentials = true;
+
+ xhr.send(data);
+ }
+
+
+ return(
+ <>
+
+
User Settings
+
+
+
+
+
+
+
+
+
+
+
+
+ Email Preferences
+
+
+
+
+ Notifications
+
+
+
+
+
+
+
+ Friend Requests
+
+
+
+
+
+
+
+
+
+
+ Creator Notifications
+
+
+ Get notified when your challenges get verified.
+
+
+
+
+
+
+
+
+ Save
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/src/pages/settings/security.jsx b/src/pages/settings/security.jsx
new file mode 100644
index 00000000..4dd473ec
--- /dev/null
+++ b/src/pages/settings/security.jsx
@@ -0,0 +1,159 @@
+import Head from 'next/head';
+import { Footer } from '@/components/Footer';
+import { StandardNav } from '@/components/StandardNav';
+import Sidebar from '@/components/settingComponents/sidebar';
+import { useState } from 'react';
+import {
+ updatePassword,
+ getAuth,
+ reauthenticateWithCredential,
+ EmailAuthProvider,
+ confirmPasswordReset,
+} from 'firebase/auth';
+
+const STRIPE_KEY = process.env.NEXT_PUBLIC_APP_STRIPE_KEY;
+
+
+export default function Security(){
+ const [inputText, setInputText] = useState('');
+
+ const auth = getAuth();
+ const user = auth.currentUser;
+
+ const handleInputChange = (event) => {
+ setInputText(event.target.value);
+ };
+
+ function saveSecurity() {
+ document.getElementById('saveSecurity').innerText = 'Saving...';
+ var oldPassword = document.getElementById('oldPassword').value;
+
+ reauthenticateWithCredential(
+ user,
+ EmailAuthProvider.credential(user.email, oldPassword)
+ )
+ .then(() => {
+ var password = document.getElementById('password').value;
+ var confirmPassword = document.getElementById('confirm-password').value;
+
+ if (password == confirmPassword) {
+ updatePassword(user, confirmPassword)
+ .then(() => {
+ document.getElementById('saveSecurity').innerText = 'Save';
+
+ document.getElementById('password').value = '';
+ document.getElementById('confirm-password').value = '';
+ })
+ .catch((error) => {
+ document.getElementById('saveSecurity').innerText = 'Save';
+ window.alert(error);
+ });
+ }
+ })
+ .catch((error) => {
+ document.getElementById('saveSecurity').innerText = 'Save';
+ window.alert(error);
+ });
+ }
+
+ return(
+ <>
+
+
User Settings
+
+
+
+
+
+
+
+
+
+
+
+
+ Security
+
+
+
+
+
+
+ Password Management
+
+
+ Change your password
+
+
+
+
+
+ New Password
+
+
+
+
+
+
+ Confirm Password
+
+
+
+
+
+
+ Current Password
+
+
+
+
+
+
+ Save
+
+
+
+
+
+
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index 23069836..33b30d29 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4453,6 +4453,11 @@ react-router@6.14.2:
dependencies:
"@remix-run/router" "1.7.2"
+react-select-country-list@^2.2.3:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/react-select-country-list/-/react-select-country-list-2.2.3.tgz#af263072a7797a660e7bd67702495dd1f95268ab"
+ integrity sha512-eRgXL613dVyJiE99yKDYLvSBKDxvIlhkmvO2DVIjdKVyUQq6kBqoMUV/2zuRIAsbRXgBGmKjeL1dxjf7zTfszg==
+
react-simplemde-editor@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/react-simplemde-editor/-/react-simplemde-editor-5.2.0.tgz#7a4c8b97e4989cb129b45ba140145d71bdc0684e"