Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions tickity-rn-app/app/(tabs)/account.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,6 @@ export default function AccountScreen() {
/>
}
>
<View style={styles.header}>
<Text style={styles.headerTitle}>Account</Text>
<Text style={styles.headerSubtitle}>
Manage your wallet and preferences
</Text>
</View>

{account ? (
<View style={styles.accountContainer}>
{/* Wallet Info Card */}
Expand Down
224 changes: 189 additions & 35 deletions tickity-rn-app/app/(tabs)/favourites.tsx
Original file line number Diff line number Diff line change
@@ -1,68 +1,222 @@
import AnimatedNFTCard from "@/components/AnimatedNFTCard";
import useGetUserNFTs from "@/hooks/useGetUserNFTs";
import { LinearGradient } from "expo-linear-gradient";
import { router } from "expo-router";
import React, { useState } from "react";
import { Button, StyleSheet, Text, View } from "react-native";
import React from "react";
import {
ActivityIndicator,
Dimensions,
FlatList,
RefreshControl,
StyleSheet,
Text,
View,
} from "react-native";

const { width } = Dimensions.get("window");

const Favourites = () => {
const [showAR, setShowAR] = useState(false);
const { nfts, hasNFTs, nftCount, isLoading, error, refetch } =
useGetUserNFTs();

return (
<View style={styles.container}>
<Text style={styles.title}>Favourites</Text>
const renderNFTCard = ({ item, index }: { item: any; index: number }) => (
<AnimatedNFTCard
ticketId={item.ticketId}
ticketType={item.ticketType}
eventName={item.eventName}
eventImage={item.eventImage}
purchaseDate={item.purchaseDate}
tokenURI={item.tokenURI}
metadata={item.metadata}
index={index}
onPress={() => {
// Navigate to NFT details or event page
router.push(`/yourevent/${item.eventAddress}`);
}}
/>
);

const renderEmptyState = () => (
<View style={styles.emptyContainer}>
<LinearGradient
colors={["#667eea", "#764ba2"]}
style={styles.emptyGradient}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 1 }}
>
<View style={styles.emptyContent}>
<Text style={styles.emptyEmoji}>🎫</Text>
<Text style={styles.emptyTitle}>No NFTs Yet</Text>
<Text style={styles.emptySubtitle}>
Your minted NFTs will appear here
</Text>
<Text style={styles.emptyDescription}>
Purchase tickets to events and they'll be displayed as beautiful
NFTs in your collection
</Text>
</View>
</LinearGradient>
</View>
);

const renderHeader = () => (
<View style={styles.header}>
<Text style={styles.title}>My NFT Collection</Text>
<Text style={styles.subtitle}>
Here you'll find all your favourite events in one place
{hasNFTs
? `You have ${nftCount} minted NFT${nftCount !== 1 ? "s" : ""}`
: "Your minted NFTs will appear here"}
</Text>
<Text style={styles.description}>
Save events you love and access them quickly whenever you need them
</Text>
<View style={styles.buttonContainer}>
<Button
title="Discover Events"
onPress={() => {
router.push("/(tabs)/");
}}
/>
<View style={styles.buttonSpacer} />
</View>
);

if (isLoading) {
return (
<View style={styles.loadingContainer}>
<ActivityIndicator size="large" color="#fff" />
<Text style={styles.loadingText}>Loading your NFTs...</Text>
</View>
);
}

if (error) {
return (
<View style={styles.errorContainer}>
<Text style={styles.errorTitle}>Oops! Something went wrong</Text>
<Text style={styles.errorText}>
{error instanceof Error ? error.message : "Failed to load your NFTs"}
</Text>
</View>
);
}

return (
<View style={styles.container}>
{hasNFTs ? (
<FlatList
data={nfts}
renderItem={renderNFTCard}
keyExtractor={(item) => item.ticketId}
numColumns={2}
columnWrapperStyle={styles.row}
contentContainerStyle={styles.listContainer}
ListHeaderComponent={renderHeader}
refreshControl={
<RefreshControl
refreshing={isLoading}
onRefresh={refetch}
tintColor="#fff"
colors={["#fff"]}
/>
}
showsVerticalScrollIndicator={false}
/>
) : (
<View style={styles.container}>
{renderHeader()}
{renderEmptyState()}
</View>
)}
</View>
);
};

const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
backgroundColor: "#000",
},
loadingContainer: {
flex: 1,
backgroundColor: "#000",
justifyContent: "center",
alignItems: "center",
},
loadingText: {
color: "#fff",
fontSize: 16,
marginTop: 16,
},
errorContainer: {
flex: 1,
backgroundColor: "#000",
justifyContent: "center",
alignItems: "center",
padding: 20,
},
errorTitle: {
color: "#fff",
fontSize: 20,
fontWeight: "bold",
marginBottom: 8,
},
errorText: {
color: "#ccc",
fontSize: 16,
textAlign: "center",
},
header: {
padding: 20,
paddingBottom: 10,
},
title: {
fontSize: 28,
fontWeight: "bold",
marginBottom: 10,
textAlign: "center",
marginBottom: 8,
color: "#fff",
},
subtitle: {
fontSize: 18,
fontSize: 16,
color: "#ccc",
lineHeight: 22,
},
listContainer: {
paddingHorizontal: 20,
paddingBottom: 20,
},
row: {
justifyContent: "space-between",
},
emptyContainer: {
flex: 1,
justifyContent: "center",
alignItems: "center",
paddingHorizontal: 20,
},
emptyGradient: {
borderRadius: 20,
padding: 2,
width: "100%",
maxWidth: 300,
},
emptyContent: {
backgroundColor: "rgba(20, 20, 20, 0.95)",
borderRadius: 18,
padding: 30,
alignItems: "center",
},
emptyEmoji: {
fontSize: 48,
marginBottom: 16,
},
emptyTitle: {
fontSize: 24,
fontWeight: "bold",
color: "#fff",
marginBottom: 15,
marginBottom: 8,
textAlign: "center",
lineHeight: 24,
},
description: {
fontSize: 14,
emptySubtitle: {
fontSize: 16,
color: "#ccc",
marginBottom: 12,
textAlign: "center",
lineHeight: 20,
marginBottom: 30,
},
buttonContainer: {
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
},
buttonSpacer: {
width: 20,
emptyDescription: {
fontSize: 14,
color: "#aaa",
textAlign: "center",
lineHeight: 20,
},
});

Expand Down
Loading