Skip to content

Commit

Permalink
added daily streak feature
Browse files Browse the repository at this point in the history
  • Loading branch information
NancyAanchal committed Jul 16, 2024
1 parent 0593e92 commit 922341e
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 6 deletions.
78 changes: 78 additions & 0 deletions nepalingo-web/src/components/StreakContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import React, {
createContext,
useContext,
useState,
useEffect,
ReactNode,
} from "react";
import supabase from "./userAuth/supabaseClient";
import { useAuth } from "./userAuth/AuthContext";

interface StreakContextProps {
currentStreak: number;
longestStreak: number;
updateStreak: () => void;
}

export const StreakContext = createContext<StreakContextProps>({
currentStreak: 0,
longestStreak: 0,
updateStreak: () => {},
});

export const StreakProvider = ({ children }: { children: ReactNode }) => {
const { user } = useAuth();
const [currentStreak, setCurrentStreak] = useState(1);
const [longestStreak, setLongestStreak] = useState(1);

useEffect(() => {
const fetchStreakData = async () => {
if (user) {
const { data } = await supabase
.from("user_daily_streaks")
.select("*")
.eq("user_id", user.id)
.single();

if (data) {
setCurrentStreak(data.current_streak);
setLongestStreak(data.longest_streak);
}
}
};

fetchStreakData();
}, [user]);

const updateStreak = async () => {
const currentDate = new Date().toISOString().split("T")[0]; // Get current date
const lastUpdateDate = localStorage.getItem("lastUpdateDate");

if (user) {
const { data, error } = await supabase.rpc("update_streak", {

Check failure on line 52 in nepalingo-web/src/components/StreakContext.tsx

View workflow job for this annotation

GitHub Actions / test_build

'error' is assigned a value but never used
user_id: user.id,
});

if (data && currentDate !== lastUpdateDate) {
setCurrentStreak(data.current_streak);
setLongestStreak(data.longest_streak);
}
}
};

return (
<StreakContext.Provider
value={{ currentStreak, longestStreak, updateStreak }}
>
{children}
</StreakContext.Provider>
);
};

export const useStreak = () => {
const context = useContext(StreakContext);
if (context === undefined) {
throw new Error("useStreak must be used within a StreakProvider");
}
return context;
};
25 changes: 22 additions & 3 deletions nepalingo-web/src/components/header/UserProfile.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import React, { useState } from "react";
import React, { useState, useContext } from "react";
import UserAvatar from "../UserAvatar";
import Menu from "./Menu";
import { useAuth } from "../userAuth/AuthContext";
import { StreakContext } from "../StreakContext";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faFire } from "@fortawesome/free-solid-svg-icons";

const UserProfile: React.FC = () => {
const [isOpen, setIsOpen] = useState(false);
const { user, signOut } = useAuth();
const { currentStreak, longestStreak } = useContext(StreakContext); // Get streak data from context

const toggleMenu = () => {
setIsOpen(!isOpen);
Expand All @@ -20,17 +24,32 @@ const UserProfile: React.FC = () => {

const options = [
{ label: `Username: ${user?.user_metadata?.username}`, value: "username" },
{ label: `Current Streak: ${currentStreak} days`, value: "currentStreak" },
{ label: `Longest Streak: ${longestStreak} days`, value: "longestStreak" },
{ label: "Log out", value: "signOut" },
];

return (
<div className="relative inline-block text-left">
<button
type="button"
className="inline-flex justify-center items-center w-10 h-10 rounded-full border border-gray-300 shadow-sm bg-gray-700 text-sm font-medium hover:bg-gray-600 focus:outline-none"
className="inline-flex justify-center items-center w-12 h-12 rounded-full border border-gray-300 shadow-sm bg-gray-700 text-sm font-medium hover:bg-gray-600 focus:outline-none"
onClick={toggleMenu}
>
<UserAvatar />
<div className="relative">
<UserAvatar />
{currentStreak > 0 && (
<div className="absolute bottom-1 right-3 transform translate-x-1/2 translate-y-1/2 flex items-center justify-center">
<FontAwesomeIcon
icon={faFire}
className="text-yellow-600 text-2xl"
/>
<span className="absolute text-sm text-white">
{currentStreak}
</span>
</div>
)}
</div>
</button>
<Menu isOpen={isOpen} onSelect={handleSelect} options={options} />
</div>
Expand Down
6 changes: 4 additions & 2 deletions nepalingo-web/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import ReactDOM from "react-dom/client";
import App from "./App";
import "./index.css";
import { AuthProvider } from "./components/userAuth/AuthContext";

import { StreakProvider } from "./components/StreakContext";
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<AuthProvider>
<App />
<StreakProvider>
<App />
</StreakProvider>
</AuthProvider>
</React.StrictMode>
);
8 changes: 7 additions & 1 deletion nepalingo-web/src/pages/Home/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React from "react";
import React, { useEffect } from "react";
import { Link } from "react-router-dom";
import logo from "../../assets/logo.png";
import Header from "../../components/header/Header";
import ReactGA from "react-ga4";
import { useAuth } from "../../components/userAuth/AuthContext";
import { useStreak } from "../../components/StreakContext";

const Home: React.FC = () => {
ReactGA.send({
Expand All @@ -12,6 +13,11 @@ const Home: React.FC = () => {
title: "home",
});
const { user } = useAuth();
const { updateStreak } = useStreak();

useEffect(() => {
updateStreak(); // Trigger streak update on home page load
}, []);

return (
<div className="flex flex-col items-center justify-between h-screen bg-gradient-to-r from-black via-gray-800 to-black text-white">
Expand Down

0 comments on commit 922341e

Please sign in to comment.