Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove connect wallet button and improve UX #147

Closed
wants to merge 15 commits into from
Closed
43 changes: 0 additions & 43 deletions src/app/admin/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ export default function AdminPanel() {
const [error, setError] = useState<string | null>(null);
const [searchTerm, setSearchTerm] = useState<string>("");
const [roleFilter, setRoleFilter] = useState<UserRole | "All">("All");
const [isAdmin, setIsAdmin] = useState<boolean>(false);
const [editingProfile, setEditingProfile] = useState<{
[key: string]: {
assigned_agent_address: string;
Expand All @@ -49,32 +48,9 @@ export default function AdminPanel() {
const [sortOrder, setSortOrder] = useState<SortOrder>(null);

useEffect(() => {
checkAdminStatus();
fetchProfiles();
}, []);

const checkAdminStatus = async () => {
try {
const {
data: { user },
} = await supabase.auth.getUser();
if (!user) throw new Error("Not authenticated");

const { data, error } = await supabase
.from("profiles")
.select("role")
.eq("id", user.id)
.single();

if (error) throw error;
setIsAdmin(data.role === "Admin");
} catch (error) {
console.error("Failed to verify admin status:", error);
setError("Failed to verify admin status");
setIsAdmin(false);
}
};

const formatEmail = (email: string): string => {
return email.split("@")[0].toUpperCase();
};
Expand Down Expand Up @@ -123,11 +99,6 @@ export default function AdminPanel() {
};

const updateProfile = async (userId: string): Promise<void> => {
if (!isAdmin) {
setError("Only admins can update profiles");
return;
}

try {
setError(null);
const updates: Partial<Profile> = {
Expand Down Expand Up @@ -221,20 +192,6 @@ export default function AdminPanel() {
return <Loader />;
}

if (!isAdmin) {
return (
<Card className="max-w-4xl mx-auto my-8">
<CardContent className="pt-6">
<Alert>
<AlertDescription>
Access denied. Only administrators can manage profiles.
</AlertDescription>
</Alert>
</CardContent>
</Card>
);
}

return (
<Card className="w-full mx-auto my-8">
<CardHeader>
Expand Down
88 changes: 53 additions & 35 deletions src/app/application-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { useUserData } from "@/hooks/useUserData";
import { Wallet } from "lucide-react";
import SignOut from "@/components/auth/SignOut";
import Image from "next/image";
import { supabase } from "@/utils/supabase/client";

function AccountDropdownMenu({
anchor,
Expand Down Expand Up @@ -73,7 +74,24 @@ function AccountDropdownMenu({

export function ApplicationLayout({ children }: { children: React.ReactNode }) {
const pathname = usePathname();
const { data: userData, isLoading } = useUserData();
const { data: userData, isLoading, refetch } = useUserData();

// Add a listener for auth state changes
React.useEffect(() => {
const { data: authListener } = supabase.auth.onAuthStateChange(
async (event) => {
if (event === "SIGNED_IN" || event === "TOKEN_REFRESHED") {
// Refetch user data when signed in or token is refreshed
await refetch();
}
}
);

// Cleanup subscription
return () => {
authListener.subscription.unsubscribe();
};
}, [refetch]);

const displayAddress = React.useMemo(() => {
if (!userData?.stxAddress) return "";
Expand Down Expand Up @@ -136,10 +154,6 @@ export function ApplicationLayout({ children }: { children: React.ReactNode }) {

<SidebarBody>
<SidebarSection>
{/* <SidebarItem href="/dashboard" current={pathname === "/"}>
<DashboardIcon />
<SidebarLabel>Dashboard</SidebarLabel>
</SidebarItem> */}
<SidebarItem href="/chat" current={pathname === "/chat"}>
<ChatBubbleBottomCenterTextIcon />
<SidebarLabel>Chat</SidebarLabel>
Expand Down Expand Up @@ -181,41 +195,45 @@ export function ApplicationLayout({ children }: { children: React.ReactNode }) {
<DocumentTextIcon />
<SidebarLabel>Terms of Service</SidebarLabel>
</SidebarItem>
<SidebarItem>
<Wallet />
<SidebarLabel className="flex flex-col">
{isLoading ? "Loading..." : displayAgentAddress}
{userData?.agentAddress && (
<span className="text-xs text-zinc-500 dark:text-zinc-400">
{userData.agentBalance !== null
? `${userData.agentBalance.toFixed(5)} STX`
: "Loading balance..."}
</span>
)}
</SidebarLabel>
</SidebarItem>
{userData && !isLoading && (
<SidebarItem>
<Wallet />
<SidebarLabel className="flex flex-col">
{isLoading ? "Loading..." : displayAgentAddress}
{userData?.agentAddress && (
<span className="text-xs text-zinc-500 dark:text-zinc-400">
{userData.agentBalance !== null
? `${userData.agentBalance.toFixed(5)} STX`
: "Loading balance..."}
</span>
)}
</SidebarLabel>
</SidebarItem>
)}
</SidebarSection>
</SidebarBody>

<SidebarFooter className=" p-4">
<Dropdown>
<DropdownButton as={SidebarItem}>
<span className="flex min-w-0 items-center gap-3">
<Avatar initials="P" className="size-10" square alt="" />
<span className="min-w-0">
<span className="block truncate text-sm font-medium text-zinc-950 dark:text-white">
{isLoading ? "Loading..." : displayAddress}
</span>
<span className="block truncate text-xs font-normal text-zinc-500 dark:text-zinc-400">
{isLoading ? "Loading..." : displayRole}
{userData && !isLoading && (
<SidebarFooter className="p-4">
<Dropdown>
<DropdownButton as={SidebarItem}>
<span className="flex min-w-0 items-center gap-3">
<Avatar initials="P" className="size-10" square alt="" />
<span className="min-w-0">
<span className="block truncate text-sm font-medium text-zinc-950 dark:text-white">
{displayAddress}
</span>
<span className="block truncate text-xs font-normal text-zinc-500 dark:text-zinc-400">
{displayRole}
</span>
</span>
</span>
</span>
<ChevronUpIcon />
</DropdownButton>
<AccountDropdownMenu userData={userData} anchor="top start" />
</Dropdown>
</SidebarFooter>
<ChevronUpIcon />
</DropdownButton>
<AccountDropdownMenu userData={userData} anchor="top start" />
</Dropdown>
</SidebarFooter>
)}
</Sidebar>
}
>
Expand Down
23 changes: 20 additions & 3 deletions src/app/chat/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
import React from "react";
import { headers } from "next/headers";
import Chat from "@/components/chat/Chat";
import Link from "next/link";

export const runtime = "edge";

const page = () => {
return (
<Chat />
);
const headersList = headers();
const authStatus = headersList.get("x-auth-status");

if (authStatus === "unauthorized") {
return (
<div className="w-full h-full flex items-center justify-center">
<div className="text-center">
{/* THIS IS SHOWN WHEN THE USER IS NOT AUTHENTICATED INSTEAD OF FULL REDIRECT TO CONNECT*/}
<h2 className="text-xl font-semibold mb-4">Limited Access</h2>
<Link href={"/connect"}>connect to access the chat</Link>
</div>
</div>
);
}
// Render chat component if authenticated
return <Chat />;
};

export default page;
49 changes: 49 additions & 0 deletions src/app/connect/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"use client";

import { useEffect, useRef } from "react";
import { useSearchParams } from "next/navigation";
import { useAuth } from "@/hooks/useAuth";

export default function ConnectPage() {
const { connectWallet } = useAuth();
const searchParams = useSearchParams();
const redirectPath = searchParams.get("redirect") || "/chat";
const hasInitiatedConnection = useRef(false);

useEffect(() => {
const initiateConnection = async () => {
if (hasInitiatedConnection.current) return;
hasInitiatedConnection.current = true;

try {
console.log("Starting connection process");
console.log("Redirect path:", redirectPath);

const result = await connectWallet();

console.log("Connection result:", result);

if (result.success) {
console.log("Attempting to redirect to:", redirectPath);
window.location.href = redirectPath;
} else {
console.log("Connection failed, redirecting to home");
window.location.href = "/";
}
} catch (error) {
console.error("Error in connection process:", error);
window.location.href = "/";
}
};

initiateConnection();
}, [connectWallet, redirectPath]);

return (
<div className="flex justify-center items-center min-h-screen">
<div className="text-center">
<p>Redirecting to {redirectPath}...</p>
</div>
</div>
);
}
19 changes: 18 additions & 1 deletion src/app/crews/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@

import React from "react";
import Crews from "@/components/crews/Crews";
import { Metadata } from "next";
import { headers } from "next/headers";
import Link from "next/link";

export const metadata: Metadata = {
title: "Crews",
};

export const runtime = "edge";

const page = () => {
const headersList = headers();
const authStatus = headersList.get("x-auth-status");

if (authStatus === "unauthorized") {
return (
<div className="w-full h-full flex items-center justify-center">
<div className="text-center">
{/* THIS IS SHOWN WHEN THE USER IS NOT AUTHENTICATED INSTEAD OF FULL REDIRECT TO CONNECT*/}
<h2 className="text-xl font-semibold mb-4">Limited Access</h2>
<Link href={"/connect"}>connect to access the crews</Link>
</div>
</div>
);
}
return <Crews />;
};

Expand Down
17 changes: 8 additions & 9 deletions src/app/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,18 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ThemeProvider } from "@/components/ui/theme-provider";
import { Toaster } from "@/components/ui/toaster";
import { ApplicationLayout } from "./application-layout";
import { usePathname } from "next/navigation";

const queryClient = new QueryClient();

export function Providers({ children }: { children: React.ReactNode }) {
const pathname = usePathname();
// const pathname = usePathname();

const content =
pathname === "/" ? (
children
) : (
<ApplicationLayout>{children}</ApplicationLayout>
);
// const content =
// pathname === "/" ? (
// children
// ) : (
// <ApplicationLayout>{children}</ApplicationLayout>
// );

return (
<ThemeProvider
Expand All @@ -26,7 +25,7 @@ export function Providers({ children }: { children: React.ReactNode }) {
disableTransitionOnChange
>
<QueryClientProvider client={queryClient}>
{content}
<ApplicationLayout>{children}</ApplicationLayout>
<Toaster />
</QueryClientProvider>
</ThemeProvider>
Expand Down
7 changes: 4 additions & 3 deletions src/components/Home/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import React from "react";
import Image from "next/image";
// import Authentication from "../auth/Authentication"; #FOR GITHUB AUTH
import SignIn from "../auth/StacksAuth";
// import SignIn from "../auth/StacksAuth";

export default function Home() {
return (
Expand All @@ -17,11 +17,12 @@ export default function Home() {
height={400}
/>

{/* WE CAN REMOVE THIS NOW */}
<div className="w-full max-w-md px-4">
{/* Authentication component */}
<div className="pt-4">
{/* <div className="pt-4">
<SignIn />
</div>
</div> */}
</div>
</div>
</div>
Expand Down
Loading
Loading