Skip to content

Commit

Permalink
Almost done with stripe onboarding
Browse files Browse the repository at this point in the history
  • Loading branch information
Winston-Hsiao committed Nov 6, 2024
1 parent 1be7a42 commit 1881425
Show file tree
Hide file tree
Showing 9 changed files with 596 additions and 150 deletions.
12 changes: 11 additions & 1 deletion frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ import Login from "@/components/pages/Login";
import Logout from "@/components/pages/Logout";
import NotFound from "@/components/pages/NotFound";
import Profile from "@/components/pages/Profile";
import SellerDashboard from "@/components/pages/SellerDashboard";
import Signup from "@/components/pages/Signup";
import { AlertQueue, AlertQueueProvider } from "@/hooks/useAlertQueue";
import { AuthenticationProvider } from "@/hooks/useAuth";

import GDPRBanner from "./components/gdpr/gdprbanner";
import DeleteConnect from "./components/pages/DeleteConnect";
import DownloadsPage from "./components/pages/Download";
import PlaygroundPage from "./components/pages/MujocoPlayground";
import OrderSuccess from "./components/pages/OrderSuccess";
Expand Down Expand Up @@ -86,9 +88,17 @@ const App = () => {
<Route path="/pro" element={<StompyPro />} />
<Route path="/mini" element={<StompyMini />} />
<Route
path="/start-selling"
path="/seller-onboarding"
element={<SellerOnboarding />}
/>
<Route
path="/seller-dashboard"
element={<SellerDashboard />}
/>
<Route
path="/delete-connect"
element={<DeleteConnect />}
/>

<Route path="/success" element={<OrderSuccess />} />
<Route path="/orders" element={<OrdersPage />} />
Expand Down
85 changes: 85 additions & 0 deletions frontend/src/components/pages/DeleteConnect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { useEffect } from "react";
import { useNavigate } from "react-router-dom";

import { useAlertQueue } from "@/hooks/useAlertQueue";
import { useAuthentication } from "@/hooks/useAuth";

export default function DeleteConnect() {
const navigate = useNavigate();
const auth = useAuthentication();
const { addErrorAlert, addAlert } = useAlertQueue();

useEffect(() => {
if (auth.isLoading) return;

if (!auth.isAuthenticated) {
navigate("/login");
return;
}

// Only allow access in development
if (process.env.NODE_ENV !== "development") {
navigate("/");
return;
}
}, [auth.isLoading, auth.isAuthenticated]);

const handleDeleteTestAccounts = async () => {
try {
const { data, error } = await auth.client.POST(
"/stripe/connect-account/delete-test-accounts",
{},
);

if (error) {
addErrorAlert(error);
return;
}

addAlert(`Successfully deleted ${data.count} test accounts`, "success");
setTimeout(() => {
navigate("/seller-onboarding");
}, 2000);
} catch (error) {
addErrorAlert(`Failed to delete test accounts: ${error}`);
}
};

if (auth.isLoading) {
return (
<div className="container mx-auto px-4 py-8">
<div className="max-w-2xl mx-auto">
<p>Loading...</p>
</div>
</div>
);
}

return (
<div className="container mx-auto px-4 py-8">
<div className="max-w-2xl mx-auto">
<h1 className="text-3xl font-bold mb-6">
Delete Test Connect Accounts
</h1>

<div className="bg-red-50 p-6 rounded-lg mb-6">
<h2 className="text-red-800 font-semibold mb-2">⚠️ Warning</h2>
<p className="text-red-700 mb-4">
This action will delete all test Stripe Connect accounts associated
with this environment. This operation cannot be undone.
</p>
<p className="text-red-700 mb-4">
This functionality is only available in development mode.
</p>
</div>

<button
onClick={handleDeleteTestAccounts}
className="w-full bg-red-600 text-white px-6 py-3 rounded-lg hover:bg-red-700"
>
Delete All Test Connect Accounts
</button>
</div>
</div>
);
}
75 changes: 39 additions & 36 deletions frontend/src/components/pages/Profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import UpvotedGrid from "@/components/listings/UpvotedGrid";
import { Card, CardContent, CardHeader } from "@/components/ui/Card";
import { Input, TextArea } from "@/components/ui/Input/Input";
import Spinner from "@/components/ui/Spinner";
import { Tooltip } from "@/components/ui/ToolTip";
import { Button } from "@/components/ui/button";
import { paths } from "@/gen/api";
import { useAlertQueue } from "@/hooks/useAlertQueue";
Expand Down Expand Up @@ -161,40 +162,13 @@ export const RenderProfile = (props: RenderProfileProps) => {
</p>
</div>
{!isEditing && canEdit && (
<div className="flex flex-col items-center space-y-2">
<div className="flex flex-wrap gap-2 justify-center">
<Button onClick={() => navigate("/keys")} variant="primary">
API Keys
</Button>
<Button onClick={() => setIsEditing(true)} variant="outline">
Edit Profile
</Button>
<div className="flex flex-wrap gap-2 justify-center">
<Button onClick={() => navigate("/keys")} variant="primary">
API Keys
</Button>
<Button onClick={() => navigate("/orders")} variant="default">
Orders
</Button>
{!user.stripe_connect_account_id ? (
<Button
onClick={() => navigate("/start-selling")}
variant="default"
>
Become a Seller
</Button>
) : !user.stripe_connect_onboarding_completed ? (
<Button
onClick={() => navigate("/start-selling")}
variant="default"
>
Complete Seller Setup
</Button>
) : (
<Button
onClick={() => navigate("/start-selling")}
variant="default"
>
Seller Dashboard
</Button>
)}
</div>
</div>
)}
{isAdmin && !canEdit && (
Expand Down Expand Up @@ -329,7 +303,7 @@ export const RenderProfile = (props: RenderProfileProps) => {
{user.bio ? (
<p>{user.bio}</p>
) : (
<p className="text-gray-11">
<p className="text-gray-11 text-sm">
No bio set. Edit your profile to add a bio.
</p>
)}
Expand All @@ -341,9 +315,38 @@ export const RenderProfile = (props: RenderProfileProps) => {

<Card className="w-full max-w-4xl mx-auto">
<CardHeader>
<h2 className="text-2xl font-bold">Listings</h2>
<h2 className="text-2xl font-bold">Store</h2>
</CardHeader>
<CardContent>
<div className="flex gap-2">
<Button onClick={() => navigate("/orders")} variant="primary">
Orders
</Button>
{!user.stripe_connect_account_id ? (
<Tooltip content="Start seller onboarding" position="bottom">
<Button
onClick={() => navigate("/seller-onboarding")}
variant="outline"
>
Sell Robots
</Button>
</Tooltip>
) : !user.stripe_connect_onboarding_completed ? (
<Button
onClick={() => navigate("/seller-onboarding")}
variant="outline"
>
Complete Seller Setup
</Button>
) : (
<Button
onClick={() => navigate("/seller-dashboard")}
variant="outline"
>
Seller Dashboard
</Button>
)}
</div>
<div className="flex flex-col items-center space-y-4">
<Tabs
defaultValue="own"
Expand All @@ -353,13 +356,13 @@ export const RenderProfile = (props: RenderProfileProps) => {
<TabsList className="flex justify-center space-x-4 mb-4">
<TabsTrigger
value="own"
className="px-3 py-1.5 rounded-md transition-colors duration-300 hover:bg-gray-11 hover:text-gray-1 data-[state=active]:bg-primary-9 data-[state=active]:text-gray-1"
className="text-sm px-3 py-1.5 rounded-md transition-colors duration-300 hover:bg-gray-9 hover:text-gray-1 data-[state=active]:bg-gray-12 data-[state=active]:text-gray-1"
>
Overview
Your Listings
</TabsTrigger>
<TabsTrigger
value="upvoted"
className="px-3 py-1.5 rounded-md transition-colors duration-300 hover:bg-gray-11 hover:text-gray-1 data-[state=active]:bg-primary-9 data-[state=active]:text-gray-1"
className="text-sm px-3 py-1.5 rounded-md transition-colors duration-300 hover:bg-gray-9 hover:text-gray-1 data-[state=active]:bg-gray-12 data-[state=active]:text-gray-1"
>
Upvoted
</TabsTrigger>
Expand Down
60 changes: 60 additions & 0 deletions frontend/src/components/pages/SellerDashboard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { useEffect } from "react";
import { useNavigate } from "react-router-dom";

import { useAuthentication } from "@/hooks/useAuth";

export default function SellerDashboard() {
const navigate = useNavigate();
const auth = useAuthentication();

useEffect(() => {
if (auth.isLoading) return;

if (!auth.isAuthenticated) {
navigate("/login");
return;
}

// Redirect to onboarding if not completed
if (!auth.currentUser?.stripe_connect_onboarding_completed) {
navigate("/seller-onboarding");
return;
}
}, [auth.isLoading, auth.isAuthenticated, auth.currentUser]);

if (auth.isLoading) {
return (
<div className="container mx-auto px-4 py-8">
<div className="max-w-2xl mx-auto">
<p>Loading...</p>
</div>
</div>
);
}

return (
<div className="container mx-auto px-4 py-8">
<div className="max-w-2xl mx-auto">
<h1 className="text-3xl font-bold mb-6">Seller Dashboard</h1>

<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-xl font-semibold mb-4">Account Status</h2>
<p className="text-green-600 mb-4">
✓ Your seller account is active and ready to receive payments
</p>

<div className="mt-6">
<a
href={`https://dashboard.stripe.com/${auth.currentUser?.stripe_connect_account_id}`}
target="_blank"
rel="noopener noreferrer"
className="bg-primary-9 text-white px-6 py-3 rounded-lg hover:bg-primary-9/80 inline-block"
>
Open Stripe Dashboard
</a>
</div>
</div>
</div>
</div>
);
}
Loading

0 comments on commit 1881425

Please sign in to comment.