Skip to content

Commit

Permalink
Scoring profiles & structure changes & home & bug fixs
Browse files Browse the repository at this point in the history
  • Loading branch information
cqb13 committed Nov 26, 2023
1 parent 48acccf commit a806f30
Show file tree
Hide file tree
Showing 27 changed files with 907 additions and 356 deletions.
245 changes: 216 additions & 29 deletions app/account/page.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
"use client";

import updateSetupDefaultProfile from "@/utils/firebase/db/updateSetupDefaultProfile";
import NotificationPopup from "@/components/general/notificationPopup";
import updateDisplayName from "@/utils/firebase/db/updateDisplayName";
import updateProfileType from "@/utils/firebase/db/updateProfileType";
import deleteAccount from "@/utils/firebase/account/deleteAccount";
import googleSignOut from "@/utils/firebase/account/googleSignOut";
import updateProfiles from "@/utils/firebase/db/updateProfiles";
import ConfirmPopup from "@/components/misc/confirmPopup";
import getUserDoc from "@/utils/firebase/db/getUserDoc";
import { useAuthContext } from "@context/authContext";
import Dropdown from "@/components/general/dropdown";
import Slider from "@/components/general/slider";
import Button from "@/components/general/button";
import Input from "@/components/general/input";
import { useState, useEffect } from "react";
Expand All @@ -18,7 +21,6 @@ import Image from "next/image";

export default function History() {
// general
const [userDoc, setUserDoc] = useState({} as any);
const { user } = useAuthContext() as { user: any };
const router = useRouter();

Expand All @@ -38,6 +40,21 @@ export default function History() {
const [profileType, setProfileType] = useState("Private");
const [photoURL, setPhotoURL] = useState("");

// profiles
const [profiles, setProfiles] = useState([] as any[]);
const [currentProfile, setCurrentProfile] = useState({} as any);
const [profileName, setProfileName] = useState("");
const [setupDefaultProfile, setSetupDefaultProfile] = useState<number>(0);

// scoring
const [location, setLocation] = useState<string>("");
const [distanceUnit, setDistanceUnit] = useState<string>("");
const [distance, setDistance] = useState<number>(0);
const [ends, setEnds] = useState<number>(0);
const [arrowsPerEnd, setArrowsPerEnd] = useState<number>(0);
const [splitEnds, setSplitEnds] = useState<number>(0);
const [bow, setBow] = useState<string>("");

useEffect(() => {
if (!user) return;
auth.onAuthStateChanged((user) => {
Expand All @@ -49,14 +66,32 @@ export default function History() {
});

getUserDoc(auth.currentUser).then((doc: any) => {
setUserDoc(doc);
setNamePlaceholder(doc.displayName);
setProfileType(doc.profileType);
setSetupDefaultProfile(doc.setupDefaultProfile);
processProfiles(doc.profiles);
const bigPhotoURL = doc.photoURL.replace("s96-c", "s500-c");
setPhotoURL(bigPhotoURL);
});
}, [user]);

const processProfiles = async (dbProfiles: string[]) => {
loadProfile(dbProfiles[0]);
setProfiles(dbProfiles);
};

const loadProfile = (profile: any) => {
setCurrentProfile(profile);
setLocation(profile.location);
setProfileName(profile.profileName);
setDistanceUnit(profile.distanceUnit);
setDistance(profile.distance);
setEnds(profile.ends);
setArrowsPerEnd(profile.arrowsPerEnd);
setSplitEnds(profile.splitEnds);
setBow(profile.bow);
};

const updateName = () => {
updateDisplayName(auth.currentUser, name);
setName("");
Expand All @@ -80,40 +115,192 @@ export default function History() {
setDeletePopup(false);
};

const saveProfile = () => {
const profileId = currentProfile.profileId;
const tempProfiles = [...profiles]; // Create a shallow copy of the profiles array

if (!checkIfUniqueProfileName(profileName, profileId)) {
setNotification(true);
setNotificationType("error");
setNotificationTitle("Error");
setNotificationMessage("Profile name already exists");
return;
}

let tempProfile = { ...currentProfile }; // Create a shallow copy of the currentProfile object
tempProfile.location = location;
tempProfile.profileName = profileName;
tempProfile.distanceUnit = distanceUnit;
tempProfile.distance = distance;
tempProfile.ends = ends;
tempProfile.arrowsPerEnd = arrowsPerEnd;
tempProfile.splitEnds = splitEnds;
tempProfile.bow = bow;

if (JSON.stringify(currentProfile) === JSON.stringify(tempProfile)) {
setNotification(true);
setNotificationType("error");
setNotificationTitle("Error");
setNotificationMessage("No changes made");
return;
}

tempProfiles[profileId - 1] = tempProfile;
setProfiles(tempProfiles);
updateProfiles(user, tempProfiles);

setNotification(true);
setNotificationType("success");
setNotificationTitle("Success");
setNotificationMessage("Profile updated");
};

const checkIfUniqueProfileName = (name: string, profileId: number) => {
for (let i = 0; i < profiles.length; i++) {
if (
profiles[i].profileName == name &&
profiles[i].profileId != profileId
) {
return false;
}
}
return true;
};

const switchProfile = (newProfileName: any) => {
profiles.forEach((profile) => {
if (profile.profileName == newProfileName) {
loadProfile(profile);
return;
}
});
};

const updateSetupProfile = () => {
setSetupDefaultProfile(currentProfile.profileId);
updateSetupDefaultProfile(user, currentProfile.profileId);
};

return (
<>
<section className='shadow-card p-10 border border-gray-300 rounded-md flex gap-2 w-full max-mdLg:flex-col max-mdLg:items-center'>
<Image
src={photoURL}
alt='use pfp'
className='rounded-2xl'
width={300}
height={300}
/>
<div className='flex gap-2 w-full max-smSm:flex-col'>
<div className='flex flex-col py-4 gap-2 w-full'>
<Input
value={name}
placeholder={`username: ${namePlaceholder}`}
type='text'
updateValue={setName}
<div className='w-full flex flex-col gap-2'>
<section className='shadow-card p-10 border border-gray-300 rounded-md flex flex-col gap-2 w-full max-mdLg:flex-col max-mdLg:items-center'>
<h2>Account Settings</h2>
<div className='flex gap-2'>
<Image
src={photoURL}
alt='use pfp'
className='rounded-2xl'
width={300}
height={300}
/>
<Button title='Update Name' onClick={updateName} />
<div className='flex flex-col items-center justify-center'>
<p>Social Profile</p>
<div className='flex gap-2 w-full max-smSm:flex-col'>
<div className='flex flex-col py-4 gap-2 w-full'>
<Input
value={name}
placeholder={`username: ${namePlaceholder}`}
type='text'
updateValue={setName}
/>
<Button title='Update Name' onClick={updateName} />
<div className='flex flex-col items-center justify-center'>
<p>Social Profile</p>
<Dropdown
title={profileType}
items={["Private", "Public", "Email Only"]}
setSelected={changeProfileType}
/>
</div>
</div>
<div className='flex flex-col-reverse py-4 gap-2 w-full'>
<Button title='Sign Out' onClick={() => googleSignOut()} />
<Button title='Delete Account' onClick={deleteAction} />
</div>
</div>
</div>
</section>
<section className='shadow-card p-10 border border-gray-300 rounded-md flex flex-col gap-2 w-full max-mdLg:flex-col max-mdLg:items-center'>
<h2>Scoring Profiles</h2>
<div className='flex gap-2 items-center'>
<div className='flex flex-col gap-2'>
<Dropdown
title={location}
items={["Indoor", "Outdoor"]}
newSelectedItem={location}
setSelected={setLocation}
/>
<Dropdown
title={distanceUnit}
items={["M (meters)", "YD (yards)", "FT (feet)"]}
newSelectedItem={distanceUnit}
setSelected={setDistanceUnit}
/>
<Dropdown
title={profileType}
items={["Private", "Public", "Email Only"]}
setSelected={changeProfileType}
title={bow}
items={["Barebow", "Olympic Recurve", "Compound"]}
newSelectedItem={bow}
setSelected={setBow}
/>
</div>
<div className='grid grid-cols-2 gap-2'>
<Slider
title='Distance'
jump={1}
defaultValue={distance}
min={1}
max={100}
update={setDistance}
/>
<Slider
title='Ends'
jump={1}
defaultValue={ends}
min={1}
max={40}
update={setEnds}
/>
<Slider
title='Arrow Per End'
jump={1}
defaultValue={arrowsPerEnd}
min={1}
max={12}
update={setArrowsPerEnd}
/>
<Slider
title='Split Ends'
jump={1}
defaultValue={splitEnds}
min={1}
max={4}
update={setSplitEnds}
/>
</div>
<div className='flex flex-col gap-2'>
{profiles ? (
<Dropdown
title={profileName}
items={profiles.map((profile) => profile.profileName)}
setSelected={setProfileName}
onNewSelection={switchProfile}
/>
) : null}
<Input
value={profileName}
placeholder={"profile name"}
type='text'
updateValue={setProfileName}
/>
<Button title='Save' onClick={saveProfile} />
<Button
title='Set as Default'
disabled={setupDefaultProfile == currentProfile.profileId}
onClick={updateSetupProfile}
/>
</div>
</div>
<div className='flex flex-col-reverse py-4 gap-2 w-full'>
<Button title='Sign Out' onClick={() => googleSignOut()} />
<Button title='Delete Account' onClick={deleteAction} />
</div>
</div>
</section>
</section>
</div>
{deletePopup ? (
<ConfirmPopup
title='Delete Game'
Expand Down
Binary file removed app/favicon.ico
Binary file not shown.
File renamed without changes
28 changes: 26 additions & 2 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import "./globals.css";
const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
metadataBase: new URL("https://archery.cqb13.dev"),
title: "Archery Scoring",
description: "Keep track of your archery scores.",
keywords: [
Expand All @@ -34,21 +35,44 @@ export const metadata: Metadata = {
address: false,
telephone: false
},
themeColor: "black",
manifest: "https://archery.cqb13.dev/manifest.json",
openGraph: {
title: "Archery Scoring",
description: "Keep track of your archery scores.",
description: "Keep track of your archery scores..",
url: "https://archery.cqb13.dev/",
siteName: "Archery Scoring",
images: [
{
url: "https://archery.cqb13.dev/icon.png",
width: 600,
height: 600,
alt: "Bow"
alt: "Logo"
}
],
locale: "en_US",
type: "website"
},
icons: {
icon: "/icon.png"
},
viewport: {
width: "device-width",
initialScale: 1,
maximumScale: 1
},
robots: {
index: true,
follow: true,
nocache: false,
googleBot: {
index: true,
follow: true,
noimageindex: false,
"max-video-preview": "auto",
"max-image-preview": "large",
"max-snippet": -1
}
}
};

Expand Down
8 changes: 8 additions & 0 deletions app/not-found.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default function NotFound() {
return (
<div className='flex flex-col items-center justify-center h-[90vh] text-black'>
<h1 className='text-4xl font-bold'>404</h1>
<h2 className='text-2xl font-medium'>Page not found</h2>
</div>
);
}
Loading

0 comments on commit a806f30

Please sign in to comment.