diff --git a/package.json b/package.json index 7e788f6..4d3dbb9 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "@sorosave/frontend", + "name": "sorosave-frontend", "version": "0.1.0", "private": true, "scripts": { @@ -9,19 +9,18 @@ "lint": "next lint" }, "dependencies": { - "@sorosave/sdk": "workspace:*", - "@stellar/freighter-api": "^2.0.0", - "next": "^14.2.0", - "react": "^18.3.0", - "react-dom": "^18.3.0" + "next": "^14.0.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "@stellar/stellar-sdk": "^11.0.0", + "@stellar/freighter-api": "^1.0.0", + "react-joyride": "^2.5.4", + "tailwindcss": "^3.3.0" }, "devDependencies": { "@types/node": "^20.0.0", - "@types/react": "^18.3.0", - "@types/react-dom": "^18.3.0", - "autoprefixer": "^10.4.0", - "postcss": "^8.4.0", - "tailwindcss": "^3.4.0", - "typescript": "^5.5.0" + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.0", + "typescript": "^5.0.0" } -} +} \ No newline at end of file diff --git a/src/app/providers.tsx b/src/app/providers.tsx index 98f8bf5..7f3021b 100644 --- a/src/app/providers.tsx +++ b/src/app/providers.tsx @@ -2,6 +2,7 @@ import React, { createContext, useContext, useState, useCallback, useEffect } from "react"; import { connectWallet, getPublicKey, isFreighterInstalled } from "@/lib/wallet"; +import { OnboardingTour } from "@/components/OnboardingTour"; interface WalletContextType { address: string | null; @@ -55,6 +56,7 @@ export function Providers({ children }: { children: React.ReactNode }) { }} > {children} + ); -} +} \ No newline at end of file diff --git a/src/components/OnboardingTour.tsx b/src/components/OnboardingTour.tsx new file mode 100644 index 0000000..8a6c1f7 --- /dev/null +++ b/src/components/OnboardingTour.tsx @@ -0,0 +1,84 @@ +import { useEffect, useState } from "react"; +import Joyride, { CallBackProps, STATUS, Step } from "react-joyride"; +import { useWallet } from "@/app/providers"; +import { useRouter } from "next/navigation"; + +const steps: Step[] = [ + { + target: "body", + content: "Welcome to SoroSave! Let's take a quick tour of the app's key features.", + placement: "center", + disableBeacon: true, + }, + { + target: "[data-testid='wallet-connect-button']", + content: "First, connect your Stellar wallet to interact with the protocol.", + placement: "right", + }, + { + target: "[data-testid='groups-list']", + content: "Browse existing savings groups and see what's available.", + placement: "right", + }, + { + target: "[data-testid='group-card']", + content: "Click on a group to view details and join.", + placement: "right", + }, + { + target: "[data-testid='join-group-button']", + content: "Join a group by clicking this button and confirming the transaction.", + placement: "right", + }, + { + target: "[data-testid='contribute-button']", + content: "Once in a group, contribute your savings each cycle.", + placement: "right", + }, +]; + +export function OnboardingTour() { + const [run, setRun] = useState(false); + const [stepIndex, setStepIndex] = useState(0); + const { isConnected } = useWallet(); + const router = useRouter(); + + useEffect(() => { + const hasVisited = localStorage.getItem("onboardingTourCompleted"); + if (!hasVisited) { + setRun(true); + } + }, []); + + const handleJoyrideCallback = (data: CallBackProps) => { + const { status, type, index } = data; + + if (status === STATUS.FINISHED || status === STATUS.SKIPPED) { + localStorage.setItem("onboardingTourCompleted", "true"); + setRun(false); + } + + if (type === "step:after" && index === 1 && !isConnected) { + router.push("/wallet"); + } + + setStepIndex(index); + }; + + return ( + + ); +} \ No newline at end of file