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