-
-
-
-
+
+ {/* Centered Logo */}
+
+
+
+
+
+
+ Join Discord
+
+
+ {/* Search Bar */}
+ {/*
+
+
+
*/}
-
-
- );
-};
+
+ )
+}
+
+export default NavBar
diff --git a/src/components/profile/ApiSection.module.css b/src/components/profile/ApiSection.module.css
new file mode 100644
index 0000000..74cb9a8
--- /dev/null
+++ b/src/components/profile/ApiSection.module.css
@@ -0,0 +1,66 @@
+.title {
+ font-size: 24px;
+ font-weight: 600;
+ color: #242424;
+ padding: 24px 0px 10px;
+ margin: 0 24px;
+}
+
+.buttonParent {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ gap: 12px;
+ width: calc(100% - 48px);
+ margin: 0 24px;
+}
+
+.button {
+ border-radius: 14px;
+ background-color: #f98c13;
+ height: 38px;
+ overflow: hidden;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+ padding: 8px 0px;
+ box-sizing: border-box;
+ max-width: 300px;
+ transition: all 0.2s ease;
+ cursor: pointer;
+}
+
+.checkoutButton {
+ background-color: #FF4463;
+ margin-left: auto;
+}
+
+.button.active {
+ background-color: #f98c13;
+}
+
+.button:hover {
+ transform: translateY(-1px);
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.text {
+ position: relative;
+ line-height: 22px;
+ font-weight: 600;
+ margin: 0 14px;
+ color: #fff;
+}
+
+@media (max-width: 768px) {
+ .buttonParent {
+ width: calc(100% - 48px);
+ margin: 0 24px;
+ flex-wrap: wrap;
+ }
+
+ .checkoutButton {
+ margin-left: 0;
+ }
+}
diff --git a/src/components/profile/ApiSection.tsx b/src/components/profile/ApiSection.tsx
new file mode 100644
index 0000000..5ebe208
--- /dev/null
+++ b/src/components/profile/ApiSection.tsx
@@ -0,0 +1,47 @@
+import { FC } from 'react';
+import { useRouter } from 'next/router';
+import styles from './ApiSection.module.css';
+
+export const ApiSection: FC = () => {
+ const router = useRouter();
+
+ const handleNavigateToSaas = () => {
+ router.push('/saas');
+ };
+
+ const handleNavigateToEliza = () => {
+ router.push('/eliza');
+ };
+
+ const handleNavigateToCheckout = () => {
+ router.push('/eliza'); // Points to eliza/index
+ };
+
+ return (
+
+ );
+};
+
+export default ApiSection;
diff --git a/src/components/profile/ProfileData.module.css b/src/components/profile/ProfileData.module.css
new file mode 100644
index 0000000..f31eb4c
--- /dev/null
+++ b/src/components/profile/ProfileData.module.css
@@ -0,0 +1,92 @@
+.container {
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ padding: 14px 24px;
+ max-width: 800px;
+ margin: 0 auto;
+}
+
+.profileContainer {
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+ gap: 16px;
+}
+
+.userInfo {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ justify-content: center;
+}
+
+.userName {
+ font-family: 'SF Compact Round', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+ font-size: 28px;
+ font-weight: 600;
+ color: #fff;
+ margin: 0;
+}
+
+.userRole {
+ font-family: 'SF Compact Round', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+ font-size: 18px;
+ font-weight: 600;
+ color: #7E7E7E;
+}
+
+.imageContainer {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 120px;
+ height: 120px;
+}
+
+.profileImage {
+ border-radius: 50%;
+ object-fit: cover;
+ width: 100%;
+ height: 100%;
+}
+
+.signOutButton {
+ background-color: #9B8D7D;
+ color: white;
+ font-weight: 600;
+ padding: 8px 16px;
+ border-radius: 14px;
+ font-size: 14px;
+ border: none;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ margin-left: auto;
+ height: 38px;
+ white-space: nowrap;
+}
+
+.signOutButton:hover {
+ background-color: #8a7f71;
+ transform: translateY(-1px);
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.signOutButton:active {
+ transform: translateY(0);
+ box-shadow: none;
+}
+
+@media (max-width: 768px) {
+ .container {
+ padding: 14px 16px 24px;
+ }
+
+ .userName {
+ font-size: 24px;
+ }
+
+ .userRole {
+ font-size: 16px;
+ }
+}
\ No newline at end of file
diff --git a/src/components/profile/ProfileData.tsx b/src/components/profile/ProfileData.tsx
new file mode 100644
index 0000000..14045ac
--- /dev/null
+++ b/src/components/profile/ProfileData.tsx
@@ -0,0 +1,46 @@
+import { FC } from "react";
+import { useSession, signOut } from "next-auth/react";
+import Image from "next/image";
+import styles from "./ProfileData.module.css";
+
+export const ProfileData: FC = () => {
+ const { data: session } = useSession();
+
+
+
+ // Helper function to determine the user role
+ const getUserRole = () => {
+ if (!session?.user?.connections) return "Partner";
+ if ("telegram" in session.user.connections) return "Telegram";
+ if ("discord" in session.user.connections) return "Discord";
+ return "Partner";
+ };
+
+ return (
+
+
+ {session?.user?.image && (
+
+
+
+ )}
+
+
+ {session?.user?.name || "Anonymous"}
+
+ {getUserRole()}
+
+
+
+ );
+};
+
+export default ProfileData;
diff --git a/src/components/ProfileHoldings.module.css b/src/components/profile/ProfileHoldings.module.css
similarity index 100%
rename from src/components/ProfileHoldings.module.css
rename to src/components/profile/ProfileHoldings.module.css
diff --git a/src/components/ProfileHoldings.tsx b/src/components/profile/ProfileHoldings.tsx
similarity index 100%
rename from src/components/ProfileHoldings.tsx
rename to src/components/profile/ProfileHoldings.tsx
diff --git a/src/components/profile/ProfileTotals.module.css b/src/components/profile/ProfileTotals.module.css
new file mode 100644
index 0000000..2f1e6c0
--- /dev/null
+++ b/src/components/profile/ProfileTotals.module.css
@@ -0,0 +1,108 @@
+.container {
+ width: 100%;
+ /* max-width: 800px; */
+ /* margin: 0 auto; */
+ padding: 24px;
+}
+
+.metricsGrid {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 12px;
+}
+
+.metricCard {
+ background: #2D2D2D;;
+ backdrop-filter: blur(4px);
+ border-radius: 24px;
+ padding: 14px;
+ position: relative;
+ overflow: hidden;
+}
+
+.metricCard:first-child {
+ grid-column: 1 / -1;
+ background: #2D2D2D;;
+}
+
+.metricContent {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ position: relative;
+ z-index: 1;
+}
+
+.metricsAi {
+ color: #7E7E7E;
+ font-size: 14px;
+ font-family: 'SF Compact Round', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+ font-weight: 500;
+ line-height: 18px;
+}
+
+.metricInfo {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+}
+
+.value {
+ font-family: 'SF Compact Round', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+ font-size: 22px;
+ font-weight: 600;
+}
+
+.trustScorevalue {
+ font-family: 'SF Compact Round', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+ font-size: 38px;
+ font-weight: 600;
+}
+
+.label {
+ font-family: 'SF Compact Round', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+ font-size: 16px;
+ font-weight: 600;
+ color: #FFFFFF
+}
+
+.progressBar {
+ position: relative;
+ margin-top: 8px;
+ /* Adds some space between the progress bar and the bottom of the card */
+ height: 12px;
+ /* Slightly thicker to make it stand out */
+ background: #FF4463;
+ /* Set to the specified color */
+ border-radius: 50px;
+ transition: width 0.3s ease;
+}
+
+.progressContainer {
+ position: relative;
+ margin-top: 8px;
+ /* Space between the progress bar and bottom */
+ height: 12px;
+ background: #8B2C45;
+ /* Darker version of #FF4463 */
+ border-radius: 50px;
+}
+
+@media (max-width: 768px) {
+ .container {
+ padding: 16px;
+ }
+
+ .metricsGrid {
+ grid-template-columns: 1fr;
+ }
+
+ .value {
+ font-size: 20px;
+ }
+
+ .metricsAi {
+ font-size: 13px;
+ }
+}
+
diff --git a/src/components/profile/ProfileTotals.tsx b/src/components/profile/ProfileTotals.tsx
new file mode 100644
index 0000000..7d60262
--- /dev/null
+++ b/src/components/profile/ProfileTotals.tsx
@@ -0,0 +1,191 @@
+import type { NextPage } from 'next';
+import { useCallback, useEffect, useState } from 'react';
+import { useWallet } from '@solana/wallet-adapter-react';
+import Image from 'next/image';
+import styles from './ProfileTotals.module.css';
+
+type View = 'profile' | 'holdings';
+
+interface ProfileTotalsProps {
+ onViewChange?: (view: View) => void;
+}
+
+interface MetricsData {
+ trustScore: number | null;
+ successRate: number | null;
+ transparency: number | null;
+ shillingScore: number | null;
+ recommendations: number | null;
+ rank: number | null;
+ totalPartners: number | null;
+ userHoldings: number | null;
+}
+
+const displayMetric = (value: number | null): string => {
+ return value !== null ? value.toString() : "-";
+};
+
+const formatDate = (date: Date): string => {
+ const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
+ const month = months[date.getMonth()];
+ const day = date.getDate();
+ return `${month} ${day}`;
+};
+
+const getLastThirtyDaysRange = (): string => {
+ const end = new Date();
+ const start = new Date();
+ start.setDate(end.getDate() - 30);
+
+ return `${formatDate(start)} - ${formatDate(end)}`;
+};
+
+const ProfileTotals: NextPage
= ({ onViewChange = () => { } }) => {
+ const { publicKey } = useWallet();
+ const [activeView, setActiveView] = useState('profile');
+ const [metrics, setMetrics] = useState({
+ trustScore: null,
+ successRate: null,
+ transparency: null,
+ shillingScore: null,
+ recommendations: null,
+ rank: null,
+ totalPartners: null,
+ userHoldings: null
+ });
+ const [isLoading, setIsLoading] = useState(true);
+
+ useEffect(() => {
+ const fetchData = async () => {
+ if (!publicKey) return;
+
+ try {
+ setIsLoading(true);
+
+ const dashboardResponse = await fetch('/api/dashboard');
+ const dashboardData = await dashboardResponse.json();
+
+ const holdingsResponse = await fetch('/api/userHoldings');
+ const holdingsData = await holdingsResponse.json();
+
+ if (dashboardData.partners && dashboardData.trustScores) {
+ const userPartner = dashboardData.partners.find(
+ (p: any) => p.owner.toLowerCase() === publicKey.toString().toLowerCase()
+ );
+
+ const userRank = userPartner
+ ? dashboardData.partners.findIndex(
+ (p: any) => p.owner.toLowerCase() === publicKey.toString().toLowerCase()
+ ) + 1
+ : 0;
+
+ setMetrics(prev => ({
+ ...prev,
+ trustScore: dashboardData.trustScores[publicKey.toString()] || 0,
+ rank: userRank,
+ totalPartners: dashboardData.partners.length,
+ userHoldings: holdingsData.holdings || 0
+ }));
+ }
+ } catch (error) {
+ console.error('Error fetching data:', error);
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ fetchData();
+ }, [publicKey]);
+
+ const handleViewChange = useCallback((view: View) => {
+ setActiveView(view);
+ onViewChange(view);
+ }, [onViewChange]);
+
+ const dateRange = getLastThirtyDaysRange();
+
+ const formatNumber = (num: number): string => {
+ if (num >= 1000000) {
+ return `${(num / 1000000).toFixed(0)}m+`;
+ }
+ return num.toString();
+ };
+
+ if (!isLoading) {
+ return Loading...
;
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
Trust Score
+
Assigned from AI Marc
+
+
+ {/*
{metrics.trustScore}
*/}
+
+
+
+
+
+
+
+
+
+
{displayMetric(metrics.rank)}
+
Rank
+
+
+
+
+ {/*
+
+
+
+
{formatNumber(metrics.userHoldings)}
+
Tokens
+
+
+
*/}
+
+
+
+
+
+
{displayMetric(metrics.successRate)}
+
Success Rate
+
+
+
+
+
+
+
+
+
{displayMetric(metrics.shillingScore)}
+
Shills
+
+
+
+
+
+
+
+
+
{displayMetric(metrics.recommendations)}
+
Joined
+
+
+
+
+
+ );
+};
+
+export default ProfileTotals;
diff --git a/src/components/ProfileWallets.module.css b/src/components/profile/ProfileWallets.module.css
similarity index 84%
rename from src/components/ProfileWallets.module.css
rename to src/components/profile/ProfileWallets.module.css
index 864fd74..f89664c 100644
--- a/src/components/ProfileWallets.module.css
+++ b/src/components/profile/ProfileWallets.module.css
@@ -54,7 +54,7 @@
color: #fff;
}
.numberParent {
- width: calc(100% - 48px);
+ width: 100%;
position: relative;
display: flex;
flex-direction: column;
@@ -67,35 +67,30 @@
font-size: 18px;
color: #242424;
font-family: var(--font-family-base);
- margin: 0 24px;
+ margin: 0 14px;
}
.title {
font-size: 24px;
font-weight: 600;
- color: #242424;
- margin: 24px;
+ color: #fff;
+ padding: 24px 0px 10px;
+ margin: 0;
}
.buttonParent {
display: flex;
flex-direction: row;
align-items: center;
gap: 12px;
- width: calc(100% - 48px);
- margin: 0 24px;
+ width: 100%;
}
@media (max-width: 768px) {
- .numberParent {
- padding: 0;
- width: calc(100% - 48px);
- margin: 0 24px;
+ .numberParent,
+ .buttonParent {
+ width: 100%;
}
.title {
- margin: 24px;
- }
- .buttonParent {
- width: calc(100% - 48px);
- margin: 0 24px;
+ padding: 24px 0px 10px;
}
}
diff --git a/src/components/ProfileWallets.tsx b/src/components/profile/ProfileWallets.tsx
similarity index 97%
rename from src/components/ProfileWallets.tsx
rename to src/components/profile/ProfileWallets.tsx
index 499358b..bac6ffa 100644
--- a/src/components/ProfileWallets.tsx
+++ b/src/components/profile/ProfileWallets.tsx
@@ -33,7 +33,7 @@ const ProfileWallets: FC = ({ truncateLength = 4 }) => {
return (
-
Wallets
+
{wallet ? (
= ({ provider }) => {
const { data: session, status } = useSession();
-
+
useEffect(() => {
- console.log('Session updated:', {
+ console.log("Session updated:", {
session,
status,
provider,
- account: session?.user?.connections?.[provider.toLowerCase()]
+ account: session?.user?.connections?.[provider.toLowerCase()],
});
}, [session, status, provider]);
// Check if this provider is the active one
- const isThisProviderActive = !!session?.user?.connections?.[provider.toLowerCase()];
+ const isThisProviderActive =
+ !!session?.user?.connections?.[provider.toLowerCase()];
const handleClick = () => {
if (session) {
@@ -31,19 +32,17 @@ const SocialButton: FC
= ({ provider }) => {
};
return (
-
- {isThisProviderActive
- ? `Disconnect ${provider}`
- : `Connect with ${provider}`}
+ {isThisProviderActive ? `${provider}` : `Connect with ${provider}`}
{isThisProviderActive && session?.user?.name && (
-
- ({session.user.name})
-
+
({session.user.name})
)}
);
@@ -51,21 +50,18 @@ const SocialButton: FC = ({ provider }) => {
export const Socials: FC = () => {
// Commented out GitHub and Twitter, only using Discord for now
- const providers = ['Discord']; // ['GitHub', 'Discord', 'Twitter'];
+ const providers = ["Discord"]; // ['GitHub', 'Discord', 'Twitter'];
return (
-
Socials
+
{providers.map((provider) => (
-
+
))}
);
};
-export default Socials;
\ No newline at end of file
+export default Socials;
diff --git a/src/components/saas/BuyCredits.module.css b/src/components/saas/BuyCredits.module.css
new file mode 100644
index 0000000..e480953
--- /dev/null
+++ b/src/components/saas/BuyCredits.module.css
@@ -0,0 +1,165 @@
+.container {
+ width: 100%;
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 32px 16px;
+ border-radius: 14px;
+ }
+
+ .header {
+ text-align: center;
+ margin-bottom: 32px;
+ padding: 0 16px;
+ }
+
+ .title {
+ font-size: clamp(24px, 5vw, 36px);
+ font-weight: 600;
+ color: #242424;
+ margin-bottom: 12px;
+ }
+
+ .subtitle {
+ font-size: clamp(14px, 4vw, 18px);
+ color: #666;
+ max-width: 600px;
+ margin: 0 auto;
+ }
+
+ .creditGrid {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 24px;
+ margin-top: 24px;
+ padding: 0 8px;
+ }
+
+ .creditCard {
+ background-color: #E8E3D6;
+ border-radius: 12px;
+ padding: clamp(20px, 4vw, 32px);
+ color: black;
+ transition: all 0.3s ease;
+ border: 2px solid transparent;
+ width: 100%;
+ max-width: 400px;
+ margin: 0 auto;
+ position: relative;
+ }
+
+ .highlighted {
+ background-color: #F98C12;
+ color: white;
+ position: relative;
+ }
+
+ .popularBadge {
+ position: absolute;
+ top: -12px;
+ left: 50%;
+ transform: translateX(-50%);
+ background-color: #242424;
+ color: white;
+ padding: 4px 12px;
+ border-radius: 20px;
+ font-size: 12px;
+ font-weight: 600;
+ }
+
+ .tierName {
+ font-size: clamp(20px, 4vw, 24px);
+ font-weight: 600;
+ margin-bottom: 12px;
+ text-align: center;
+ }
+
+ .credits {
+ font-size: clamp(32px, 6vw, 42px);
+ font-weight: 700;
+ text-align: center;
+ margin-bottom: 8px;
+ }
+
+ .price {
+ font-size: clamp(28px, 5vw, 36px);
+ font-weight: 700;
+ text-align: center;
+ margin-bottom: 16px;
+ }
+
+ .currency {
+ font-size: 0.6em;
+ vertical-align: super;
+ margin-right: 2px;
+ }
+
+ .description {
+ text-align: center;
+ margin-bottom: 24px;
+ font-size: clamp(14px, 3vw, 16px);
+ opacity: 0.9;
+ }
+
+ .features {
+ list-style: none;
+ padding: 0;
+ margin: 0 0 24px 0;
+ }
+
+ .feature {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-bottom: 12px;
+ font-size: clamp(13px, 3vw, 14px);
+ line-height: 1.4;
+ }
+
+ .checkmark {
+ color: #F98C12;
+ font-weight: bold;
+ }
+
+ .highlighted .checkmark {
+ color: white;
+ }
+
+ @media (max-width: 1024px) {
+ .creditGrid {
+ grid-template-columns: repeat(2, 1fr);
+ }
+ }
+
+ @media (max-width: 768px) {
+ .container {
+ padding: 24px 12px;
+ }
+
+ .creditGrid {
+ grid-template-columns: 1fr;
+ gap: 20px;
+ }
+
+ .creditCard {
+ padding: 24px 20px;
+ }
+ }
+
+ @media (max-width: 480px) {
+ .container {
+ padding: 16px 8px;
+ }
+
+ .header {
+ margin-bottom: 24px;
+ }
+
+ .creditGrid {
+ gap: 16px;
+ }
+
+ .popularBadge {
+ font-size: 10px;
+ padding: 4px 8px;
+ }
+ }
\ No newline at end of file
diff --git a/src/components/saas/BuyCredits.tsx b/src/components/saas/BuyCredits.tsx
new file mode 100644
index 0000000..8820fc8
--- /dev/null
+++ b/src/components/saas/BuyCredits.tsx
@@ -0,0 +1,99 @@
+import { FC } from 'react';
+import styles from './BuyCredits.module.css';
+import GetStarted from './GetStarted';
+
+interface CreditPackage {
+ name: string;
+ credits: number;
+ price: number;
+ description: string;
+ features: string[];
+ highlighted?: boolean;
+}
+
+const creditPackages: CreditPackage[] = [
+ {
+ name: "Starter",
+ credits: 1000,
+ price: 9,
+ description: "For testing and small projects",
+ features: [
+ "1,000 API Request Credits",
+ "30 Days Validity",
+ "Basic Support",
+ "Real-time Access",
+ "Basic Analytics"
+ ]
+ },
+ {
+ name: "Growth",
+ credits: 5000,
+ price: 39,
+ description: "Ideal for growing applications",
+ features: [
+ "5,000 API Credits",
+ "60 Days Validity",
+ "Priority Support",
+ "Real-time Access",
+ "Advanced Analytics"
+ ],
+ highlighted: true
+ },
+ {
+ name: "Scale",
+ credits: 20000,
+ price: 149,
+ description: "For high-volume applications",
+ features: [
+ "20,000 API Credits",
+ "90 Days Validity",
+ "Premium Support",
+ "Real-time Access",
+ "Enterprise Analytics"
+ ]
+ }
+];
+
+const CreditCard: FC = ({ name, credits, price, description, features, highlighted }) => (
+
+ {highlighted &&
MOST POPULAR
}
+
{name}
+
{credits.toLocaleString()}
+
+ $
+ {price}
+
+
{description}
+
+ {features.map((feature, index) => (
+ -
+ ✓
+ {feature}
+
+ ))}
+
+
+
+);
+
+const BuyCredits: FC = () => {
+ return (
+
+
+
Make More Requests
+
Choose the request package that suits your needs
+
+
+ {creditPackages.map((pkg, index) => (
+
+ ))}
+
+
+ );
+};
+
+export default BuyCredits;
\ No newline at end of file
diff --git a/src/components/saas/GetStarted.module.css b/src/components/saas/GetStarted.module.css
new file mode 100644
index 0000000..18f0b29
--- /dev/null
+++ b/src/components/saas/GetStarted.module.css
@@ -0,0 +1,27 @@
+.button {
+ width: 100%;
+ padding: 12px 24px;
+ border: none;
+ border-radius: 8px;
+ background-color: #F98C12;
+ color: white;
+ font-weight: 600;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ font-size: 16px;
+ }
+
+ .button:disabled {
+ opacity: 0.7;
+ cursor: not-allowed;
+ }
+
+ .button:hover:not(:disabled) {
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(249, 140, 18, 0.3);
+ }
+
+ .highlighted {
+ background-color: white;
+ color: #F98C12;
+ }
\ No newline at end of file
diff --git a/src/components/saas/GetStarted.tsx b/src/components/saas/GetStarted.tsx
new file mode 100644
index 0000000..527a332
--- /dev/null
+++ b/src/components/saas/GetStarted.tsx
@@ -0,0 +1,71 @@
+import { FC, useState } from 'react';
+import { useWallet } from '@solana/wallet-adapter-react';
+import {
+ LAMPORTS_PER_SOL,
+ PublicKey,
+ Transaction,
+ SystemProgram,
+ Connection
+} from '@solana/web3.js';
+import { useConnection } from '@solana/wallet-adapter-react';
+import styles from './GetStarted.module.css';
+
+interface GetStartedProps {
+ tier: string;
+ price: number;
+ isHighlighted?: boolean;
+}
+
+// Move this to a safe initialization
+const getTreasuryWallet = (): PublicKey | null => {
+ try {
+ const walletAddress = process.env.NEXT_PUBLIC_TREASURY_WALLET_SOL;
+ if (!walletAddress) {
+ console.error('Treasury wallet address not found in environment variables');
+ return null;
+ }
+ return new PublicKey(walletAddress);
+ } catch (e) {
+ console.error('Invalid treasury wallet address:', e);
+ return null;
+ }
+};
+
+const TREASURY_WALLET = getTreasuryWallet();
+const HELIUS_RPC = process.env.NEXT_PUBLIC_SOLANA_API ?
+ `https://rpc.helius.xyz/?api-key=${process.env.NEXT_PUBLIC_SOLANA_API}` :
+ null;
+
+const GetStarted: FC = ({ tier, price, isHighlighted }) => {
+ const { publicKey, sendTransaction } = useWallet();
+ const { connection } = useConnection();
+ const [isLoading, setIsLoading] = useState(false);
+
+ const handlePayment = async () => {
+ if (!publicKey || !TREASURY_WALLET || !HELIUS_RPC) {
+ console.error('Missing required configuration');
+ return;
+ }
+
+ setIsLoading(true);
+ try {
+ // ... rest of the payment logic
+ } catch (error) {
+ console.error('Payment failed:', error);
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ return (
+
+ );
+};
+
+export default GetStarted;
\ No newline at end of file
diff --git a/src/components/saas/Pricing.module.css b/src/components/saas/Pricing.module.css
new file mode 100644
index 0000000..69ce62c
--- /dev/null
+++ b/src/components/saas/Pricing.module.css
@@ -0,0 +1,245 @@
+.container {
+ width: 100%;
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 32px 16px;
+ border-radius: 14px;
+}
+
+.header {
+ text-align: center;
+ margin-bottom: 32px;
+ padding: 0 16px;
+}
+
+.title {
+ font-size: clamp(24px, 5vw, 36px);
+ font-weight: 600;
+ color: #242424;
+ margin-bottom: 12px;
+}
+
+.subtitle {
+ font-size: clamp(14px, 4vw, 18px);
+ color: #666;
+ max-width: 600px;
+ margin: 0 auto;
+}
+
+.pricingGrid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
+ gap: 24px;
+ margin-top: 24px;
+ padding: 0 8px;
+}
+
+.pricingCard {
+ background-color: #E8E3D6;
+ border-radius: 12px;
+ padding: clamp(20px, 4vw, 32px);
+ color: black;
+ transition: all 0.3s ease;
+ border: 2px solid transparent;
+ width: 100%;
+ max-width: 400px;
+ margin: 0 auto;
+}
+
+.highlighted {
+ background-color: #F98C12;
+ color: white;
+ position: relative;
+ order: -1;
+}
+
+.highlighted::before {
+ content: "MOST POPULAR";
+ position: absolute;
+ top: -12px;
+ left: 50%;
+ transform: translateX(-50%);
+ background-color: #242424;
+ color: white;
+ padding: 4px 12px;
+ border-radius: 20px;
+ font-size: clamp(10px, 3vw, 12px);
+ font-weight: 600;
+ white-space: nowrap;
+}
+
+.tierName {
+ font-size: clamp(20px, 4vw, 24px);
+ font-weight: 600;
+ margin-bottom: 12px;
+}
+
+.price {
+ font-size: clamp(36px, 6vw, 48px);
+ font-weight: 700;
+ margin-bottom: 12px;
+ display: flex;
+ align-items: baseline;
+ gap: 4px;
+}
+
+.currency {
+ font-size: clamp(18px, 4vw, 24px);
+}
+
+.period {
+ font-size: clamp(14px, 3vw, 16px);
+ color: #666;
+ font-weight: normal;
+}
+
+.description {
+ font-size: clamp(14px, 3vw, 16px);
+ margin-bottom: 20px;
+ line-height: 1.5;
+}
+
+.requestLimit {
+ font-size: clamp(12px, 3vw, 14px);
+ font-weight: 600;
+ padding: 8px 16px;
+ background-color: rgba(0, 0, 0, 0.05);
+ border-radius: 20px;
+ display: inline-block;
+ margin-bottom: 20px;
+}
+
+.features {
+ list-style: none;
+ padding: 0;
+ margin: 0 0 24px 0;
+}
+
+.feature {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-bottom: 12px;
+ font-size: clamp(13px, 3vw, 14px);
+ line-height: 1.4;
+}
+
+.checkmark {
+ color: #F98C12;
+ font-weight: bold;
+ font-size: 16px;
+ flex-shrink: 0;
+}
+
+.highlighted .checkmark {
+ color: white;
+}
+
+.button {
+ width: 100%;
+ padding: clamp(10px, 3vw, 12px) clamp(16px, 4vw, 24px);
+ border: none;
+ border-radius: 8px;
+ background-color: #F98C12;
+ color: white;
+ font-weight: 600;
+ font-size: clamp(14px, 3vw, 16px);
+ cursor: pointer;
+ transition: all 0.2s ease;
+}
+
+.button:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(249, 140, 18, 0.3);
+}
+
+.highlightedButton {
+ background-color: white;
+ color: #F98C12;
+}
+
+@media (max-width: 768px) {
+ .container {
+ padding: 24px 12px;
+ }
+
+ .pricingGrid {
+ gap: 20px;
+ margin-top: 20px;
+ }
+
+ .pricingCard {
+ padding: 24px 20px;
+ }
+
+ .feature {
+ margin-bottom: 10px;
+ }
+}
+
+@media (max-width: 480px) {
+ .container {
+ padding: 16px 8px;
+ }
+
+ .header {
+ margin-bottom: 24px;
+ }
+
+ .pricingGrid {
+ gap: 16px;
+ }
+
+ .highlighted::before {
+ font-size: 10px;
+ padding: 4px 8px;
+ }
+}
+
+.creditsCTA {
+ margin-top: 64px;
+ text-align: center;
+ padding: 32px;
+ font-weight: bold;
+ background-color: #E8E3D6;
+ border-radius: 12px;
+ width: 100%;
+}
+
+.creditsCTA p {
+ font-size: 18px;
+ color: #242424;
+ margin-bottom: 16px;
+}
+
+.creditsButton {
+ display: inline-block;
+ padding: 14px 32px;
+ background-color: #F98C12;
+ color: white;
+ font-weight: 600;
+ border-radius: 8px;
+ text-decoration: none;
+ transition: all 0.2s ease;
+ font-size: 16px;
+}
+
+.creditsButton:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(249, 140, 18, 0.3);
+}
+
+@media (max-width: 768px) {
+ .creditsCTA {
+ margin-top: 48px;
+ padding: 24px 16px;
+ }
+
+ .creditsCTA p {
+ font-size: 16px;
+ }
+
+ .creditsButton {
+ padding: 12px 24px;
+ }
+}
\ No newline at end of file
diff --git a/src/components/saas/Pricing.tsx b/src/components/saas/Pricing.tsx
new file mode 100644
index 0000000..4c6cf22
--- /dev/null
+++ b/src/components/saas/Pricing.tsx
@@ -0,0 +1,106 @@
+import { FC } from 'react';
+import Link from 'next/link';
+import styles from './Pricing.module.css';
+import GetStarted from './GetStarted';
+
+interface PricingTier {
+ name: string;
+ price: number;
+ description: string;
+ features: string[];
+ requestLimit: string;
+ highlighted?: boolean;
+}
+
+const pricingTiers: PricingTier[] = [
+ {
+ name: "Basic",
+ price: 49,
+ description: "Perfect for getting started with Trust Score API",
+ requestLimit: "10,000 requests/month",
+ features: [
+ "Trust Score API Access",
+ "Basic Documentation",
+ "Email Support",
+ "Real-time Updates",
+ "Basic Analytics"
+ ]
+ },
+ {
+ name: "Pro",
+ price: 149,
+ description: "For growing projects that need more power",
+ requestLimit: "50,000 requests/month",
+ features: [
+ "Everything in Basic",
+ "Advanced Analytics",
+ "Priority Support",
+ "Historical Data Access",
+ "Custom Webhooks"
+ ],
+ highlighted: true
+ },
+ {
+ name: "Enterprise",
+ price: 499,
+ description: "For large-scale applications that need advanced features",
+ requestLimit: "200,000 requests/month",
+ features: [
+ "Everything in Pro",
+ "Dedicated Support",
+ "Custom Integration",
+ "SLA Guarantee",
+ "White-label Options"
+ ]
+ }
+];
+
+const PricingCard: FC = ({ name, price, description, features, requestLimit, highlighted }) => (
+
+
{name}
+
+ $
+ {price}
+ /month
+
+
{description}
+
{requestLimit}
+
+ {features.map((feature, index) => (
+ -
+ ✓
+ {feature}
+
+ ))}
+
+
+
+);
+
+const Pricing: FC = () => {
+ return (
+
+
+
Simple, Transparent Pricing
+
Choose the plan that's right for you
+
+
+ {pricingTiers.map((tier, index) => (
+
+ ))}
+
+
+
Need more?
+
+ Buy Credits
+
+
+
+ );
+};
+
+export default Pricing;
\ No newline at end of file
diff --git a/src/components/trust/RecomendationsList.module.css b/src/components/trust/RecomendationsList.module.css
new file mode 100644
index 0000000..1c879ae
--- /dev/null
+++ b/src/components/trust/RecomendationsList.module.css
@@ -0,0 +1,110 @@
+.frameParent {
+ width: 100%;
+ max-width: 100%;
+ margin: 0 auto;
+ padding: 8px;
+ color: #9B8D7D;
+}
+
+.headingParent {
+ display: grid;
+ grid-template-columns: 2fr 1fr 1fr 1fr 1fr;
+ align-items: center;
+ padding: 12px 16px;
+ gap: 16px;
+ border-radius: 14px;
+}
+
+.heading {
+ font-size: 12px;
+ line-height: 140%;
+ text-transform: uppercase;
+ font-weight: 600;
+ color: #9B8D7D;
+ text-align: left;
+}
+
+.row, .row1 {
+ display: grid;
+ grid-template-columns: 2fr 1fr 1fr 1fr 1fr;
+ align-items: center;
+ padding: 8px 16px;
+ gap: 16px;
+ color: black;
+ border-radius: 14px;
+ width: 100%;
+}
+
+.row {
+ background: #E8E3D6;
+}
+
+.row1 {
+ background: #EDE9DE;
+}
+
+.rowChild {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+}
+
+.tokenImage {
+ width: 34px;
+ height: 34px;
+ border-radius: 50%;
+ object-fit: cover;
+}
+
+.textParent {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+}
+
+.text1 {
+ font-weight: bold;
+ color: #242424;
+ font-size: 16px;
+}
+
+.text2 {
+ color: #242424;
+ font-size: 14px;
+ font-weight: 500;
+}
+
+.positive {
+ color: #10B981;
+ font-weight: 600;
+}
+
+.negative {
+ color: #EF4444;
+ font-weight: 600;
+}
+
+@media (max-width: 768px) {
+ .headingParent, .row, .row1 {
+ grid-template-columns: 2fr 1fr 1fr 1fr;
+ padding: 8px 12px;
+ gap: 12px;
+ }
+
+ .heading:last-child, .text2:last-child {
+ display: none; /* Hide date on mobile */
+ }
+
+ .text1 {
+ font-size: 14px;
+ }
+
+ .text2 {
+ font-size: 12px;
+ }
+
+ .tokenImage {
+ width: 28px;
+ height: 28px;
+ }
+}
\ No newline at end of file
diff --git a/src/components/trust/RecomendationsList.tsx b/src/components/trust/RecomendationsList.tsx
new file mode 100644
index 0000000..3b72389
--- /dev/null
+++ b/src/components/trust/RecomendationsList.tsx
@@ -0,0 +1,105 @@
+import type { FC } from 'react';
+import Image from "next/image";
+import styles from './RecomendationsList.module.css';
+
+interface Transaction {
+ id: number;
+ token: string;
+ type: 'buy' | 'sell';
+ price: number;
+ performance: number;
+ date: string;
+ status: 'success' | 'pending' | 'failed';
+}
+
+const mockTransactions: Transaction[] = [
+ {
+ id: 1,
+ token: "BONK",
+ type: 'buy',
+ price: 0.00000234,
+ performance: 12.5,
+ date: '2024-03-15',
+ status: 'success'
+ },
+ {
+ id: 2,
+ token: "JTO",
+ type: 'sell',
+ price: 1.24,
+ performance: -5.2,
+ date: '2024-03-14',
+ status: 'success'
+ },
+ {
+ id: 3,
+ token: "PYTH",
+ type: 'buy',
+ price: 0.45,
+ performance: 8.7,
+ date: '2024-03-13',
+ status: 'success'
+ },
+ // Add more mock transactions as needed
+];
+
+const RecomendationsList: FC = () => {
+ const formatDate = (dateString: string) => {
+ return new Date(dateString).toLocaleDateString('en-US', {
+ month: 'short',
+ day: 'numeric',
+ year: 'numeric'
+ });
+ };
+
+ const formatPerformance = (performance: number) => {
+ const isPositive = performance > 0;
+ return (
+
+ {isPositive ? '+' : ''}{performance}%
+
+ );
+ };
+
+ return (
+
+
+
TOKEN
+
TYPE
+
PRICE
+
PERFORMANCE
+
DATE
+
+ {mockTransactions.map((transaction) => (
+
+
+
+ {transaction.type.toUpperCase()}
+
+
+ ${transaction.price.toFixed(8)}
+
+
+ {formatPerformance(transaction.performance)}
+
+
+ {formatDate(transaction.date)}
+
+
+ ))}
+
+ );
+};
+
+export default RecomendationsList;
\ No newline at end of file
diff --git a/src/components/trust/ScoreCard.module.css b/src/components/trust/ScoreCard.module.css
new file mode 100644
index 0000000..15b7ed7
--- /dev/null
+++ b/src/components/trust/ScoreCard.module.css
@@ -0,0 +1,31 @@
+.card {
+ background-color: #FA9737;
+ border-radius: 0.75rem;
+ padding: 1.5rem;
+ transition: all 0.2s ease-in-out;
+}
+
+.card:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+}
+
+.title {
+ color: #242424;
+ font-weight: 600;
+ font-size: 0.875rem;
+ margin-bottom: 0.5rem;
+}
+
+.value {
+ color: white;
+ font-size: 1.5rem;
+ font-weight: 600;
+ margin-bottom: 0.5rem;
+}
+
+.description {
+ color: #242424;
+ font-weight: 400;
+ font-size: 0.875rem;
+}
\ No newline at end of file
diff --git a/src/components/trust/ScoreCard.tsx b/src/components/trust/ScoreCard.tsx
new file mode 100644
index 0000000..08c2dc0
--- /dev/null
+++ b/src/components/trust/ScoreCard.tsx
@@ -0,0 +1,22 @@
+import React from 'react';
+import styles from './ScoreCard.module.css';
+
+interface ScoreCardProps {
+ title: string;
+ value: number;
+ description: string;
+}
+
+const ScoreCard: React.FC = ({ title, value, description }) => {
+ return (
+
+
{title}
+
+ {value.toFixed(2)}
+
+
{description}
+
+ );
+};
+
+export default ScoreCard;
\ No newline at end of file
diff --git a/src/components/trust/TrustScoreChart.module.css b/src/components/trust/TrustScoreChart.module.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/components/trust/TrustScoreChart.tsx b/src/components/trust/TrustScoreChart.tsx
new file mode 100644
index 0000000..be4b410
--- /dev/null
+++ b/src/components/trust/TrustScoreChart.tsx
@@ -0,0 +1,103 @@
+import { FC } from 'react';
+import { Line } from 'react-chartjs-2';
+import {
+ Chart as ChartJS,
+ CategoryScale,
+ LinearScale,
+ PointElement,
+ LineElement,
+ Title,
+ Tooltip,
+ Legend,
+ ChartOptions,
+ Filler
+} from 'chart.js';
+
+ChartJS.register(
+ CategoryScale,
+ LinearScale,
+ PointElement,
+ LineElement,
+ Title,
+ Tooltip,
+ Legend,
+ Filler
+);
+
+// Mock data - replace with real data later
+const mockData = {
+ trustScore: {
+ labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
+ data: [75, 78, 80, 82, 84, 85.5],
+ },
+ trustRank: {
+ labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
+ data: [200, 180, 165, 155, 145, 140],
+ }
+};
+
+const TrustScoreChart: FC = () => {
+ const options: ChartOptions<'line'> = {
+ responsive: true,
+ maintainAspectRatio: false,
+ plugins: {
+ legend: {
+ position: 'top' as const,
+ labels: {
+ color: '#242424',
+ font: {
+ weight: 600
+ }
+ }
+ },
+ },
+ scales: {
+ y: {
+ grid: {
+ color: '#E8E3D6'
+ },
+ ticks: {
+ color: '#242424'
+ }
+ },
+ x: {
+ grid: {
+ color: '#E8E3D6'
+ },
+ ticks: {
+ color: '#242424'
+ }
+ }
+ }
+ };
+
+ const trustScoreData = {
+ labels: mockData.trustScore.labels,
+ datasets: [
+ {
+ label: 'Trust Score',
+ data: mockData.trustScore.data,
+ borderColor: '#F98C12',
+ backgroundColor: 'rgba(249, 140, 18, 0.1)',
+ fill: true,
+ tension: 0.4,
+ },
+ {
+ label: 'Trust Rank',
+ data: mockData.trustRank.data,
+ borderColor: '#242424',
+ backgroundColor: 'rgba(36, 36, 36, 0.1)',
+ fill: true,
+ tension: 0.4,
+ }
+ ],
+ };
+
+ return (
+
+
+
+ );
+};
+
+export default TrustScoreChart;
\ No newline at end of file
diff --git a/src/hooks/useDashboard.ts b/src/hooks/useDashboard.ts
new file mode 100644
index 0000000..536c02a
--- /dev/null
+++ b/src/hooks/useDashboard.ts
@@ -0,0 +1,55 @@
+import { useState, useEffect } from 'react';
+import { get } from '../utils/axios';
+
+const fetchHighestRankedUsers = async () => {
+ console.log("sdasdsdadasd=?????????");
+
+ try {
+ const response = await get('/user/highestRankedUsers');
+ return response.data;
+ } catch (error) {
+ console.error('Error fetching highest ranked users:', error);
+ throw error;
+ }
+};
+
+
+
+interface Partner {
+ trustScore: number;
+ avatarUrl?: string;
+ rank?:number
+ id?: string;
+ name?: string;
+}
+
+interface DashboardData {
+ partners: Partner[];
+}
+
+export const useDashboard = () => {
+ const [data, setData] = useState(null);
+ const [isLoading, setIsLoading] = useState(true);
+ const [error, setError] = useState(null);
+
+ useEffect(() => {
+ const fetchDashboard = async () => {
+ try {
+ const partners = await fetchHighestRankedUsers();
+
+
+ setData({partners});
+ } catch (err) {
+ setError(err instanceof Error ? err : new Error('Failed to fetch dashboard data'));
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ fetchDashboard();
+ }, []);
+
+
+
+ return { data, isLoading, error };
+};
\ No newline at end of file
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index e9c7db0..4ab05e9 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -1,51 +1,56 @@
-import { AppProps } from 'next/app';
-import Head from 'next/head';
-import { FC } from 'react';
-import { SessionProvider } from 'next-auth/react'; // Import SessionProvider
-import { ContextProvider } from '../contexts/ContextProvider';
-import { AppBar } from '../components/nav-element/NavBar';
-import { ContentContainer } from '../components/ContentContainer';
-import { Footer } from '../components/Footer';
-import Notifications from '../components/Notification';
-import '../styles/profile.css'; // Adjust the path based on your project structure.
-require('@solana/wallet-adapter-react-ui/styles.css');
-require('../styles/globals.css');
+import { AppProps } from "next/app"
+import Head from "next/head"
+import Script from "next/script"
+import { FC } from "react"
+import { SessionProvider } from "next-auth/react"
+import { ContextProvider } from "../contexts/ContextProvider"
+import NavBar from "../components/nav-element/NavBar"
+import { ContentContainer } from "../components/ContentContainer"
+import Notifications from "../components/Notification"
+import "../styles/profile.css" // Adjust the path based on your project structure.
+require("@solana/wallet-adapter-react-ui/styles.css")
+require("../styles/globals.css")
-import { WalletAdapterNetwork } from '@solana/wallet-adapter-base';
+import { WalletAdapterNetwork } from "@solana/wallet-adapter-base"
import {
ConnectionProvider,
- WalletProvider
-} from '@solana/wallet-adapter-react';
+ WalletProvider,
+} from "@solana/wallet-adapter-react"
import {
PhantomWalletAdapter,
- SolflareWalletAdapter
-} from '@solana/wallet-adapter-wallets';
+ SolflareWalletAdapter,
+} from "@solana/wallet-adapter-wallets"
-const wallets = [
- new PhantomWalletAdapter(),
- new SolflareWalletAdapter()
-];
+const wallets = [new PhantomWalletAdapter(), new SolflareWalletAdapter()]
const App: FC = ({ Component, pageProps }) => {
- return (
- {/* Wrap everything in SessionProvider */}
-
- ai16z Partners Lounge
-
+ return (
+
+
+ ai16z Partners Lounge
+
-
-
-
-
- );
-};
+