notification store and update in local storage
This commit is contained in:
@@ -6,12 +6,15 @@ import { AppRegistry } from 'react-native';
|
||||
import App from './App';
|
||||
import { name as appName } from './app.json';
|
||||
import { Provider } from 'react-redux';
|
||||
import { store } from './src/redux/store';
|
||||
import { persistor, store } from './src/redux/store';
|
||||
import { PersistGate } from 'redux-persist/integration/react';
|
||||
|
||||
// ✅ Wrapper with Provider
|
||||
const ReduxWrapper = () => (
|
||||
<Provider store={store}>
|
||||
<App />
|
||||
<PersistGate loading={null} persistor={persistor}>
|
||||
<App />
|
||||
</PersistGate>
|
||||
</Provider>
|
||||
);
|
||||
|
||||
|
||||
Generated
+45
-1
@@ -9,6 +9,7 @@
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"@notifee/react-native": "^9.1.8",
|
||||
"@react-native-async-storage/async-storage": "^1.24.0",
|
||||
"@react-native-clipboard/clipboard": "^1.16.3",
|
||||
"@react-native-community/blur": "^4.4.1",
|
||||
"@react-native-community/slider": "^5.0.1",
|
||||
@@ -45,7 +46,8 @@
|
||||
"react-native-vector-icons": "^10.3.0",
|
||||
"react-native-walkthrough-tooltip": "^1.6.0",
|
||||
"react-native-worklets": "^0.6.0",
|
||||
"react-redux": "^9.2.0"
|
||||
"react-redux": "^9.2.0",
|
||||
"redux-persist": "^6.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
@@ -3288,6 +3290,18 @@
|
||||
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@react-native-async-storage/async-storage": {
|
||||
"version": "1.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.24.0.tgz",
|
||||
"integrity": "sha512-W4/vbwUOYOjco0x3toB8QCr7EjIP6nE9G7o8PMguvvjYT5Awg09lyV4enACRx4s++PPulBiBSjL0KTFx2u0Z/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"merge-options": "^3.0.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react-native": "^0.0.0-0 || >=0.60 <1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native-clipboard/clipboard": {
|
||||
"version": "1.16.3",
|
||||
"license": "MIT",
|
||||
@@ -7892,6 +7906,15 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-plain-obj": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
|
||||
"integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-regex": {
|
||||
"version": "1.2.1",
|
||||
"dev": true,
|
||||
@@ -9094,6 +9117,18 @@
|
||||
"version": "5.2.1",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/merge-options": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz",
|
||||
"integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-plain-obj": "^2.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/merge-stream": {
|
||||
"version": "2.0.0",
|
||||
"license": "MIT"
|
||||
@@ -13213,6 +13248,15 @@
|
||||
"version": "5.0.1",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/redux-persist": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz",
|
||||
"integrity": "sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"redux": ">4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/redux-thunk": {
|
||||
"version": "3.1.0",
|
||||
"license": "MIT",
|
||||
|
||||
+3
-1
@@ -11,6 +11,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@notifee/react-native": "^9.1.8",
|
||||
"@react-native-async-storage/async-storage": "^1.24.0",
|
||||
"@react-native-clipboard/clipboard": "^1.16.3",
|
||||
"@react-native-community/blur": "^4.4.1",
|
||||
"@react-native-community/slider": "^5.0.1",
|
||||
@@ -47,7 +48,8 @@
|
||||
"react-native-vector-icons": "^10.3.0",
|
||||
"react-native-walkthrough-tooltip": "^1.6.0",
|
||||
"react-native-worklets": "^0.6.0",
|
||||
"react-redux": "^9.2.0"
|
||||
"react-redux": "^9.2.0",
|
||||
"redux-persist": "^6.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
|
||||
@@ -9,13 +9,13 @@ import {
|
||||
StyleProp,
|
||||
} from "react-native";
|
||||
import LinearGradient from "react-native-linear-gradient";
|
||||
import { Ionicons } from "@react-native-vector-icons/ionicons";
|
||||
import { Ionicons, IoniconsIconName } from "@react-native-vector-icons/ionicons";
|
||||
import colors from "../colors"; // Assuming your pastel colors are defined here
|
||||
|
||||
type CardProps = {
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
iconName?: string;
|
||||
iconName?: IoniconsIconName;
|
||||
onPress?: () => void;
|
||||
backOne?: string;
|
||||
backTwo?: string;
|
||||
@@ -89,7 +89,7 @@ const AnimatedCard: React.FC<CardProps> = ({
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
card: {
|
||||
minWidth: 170,
|
||||
// minWidth: 170,
|
||||
flex: 1,
|
||||
height: 170,
|
||||
marginHorizontal: 8,
|
||||
@@ -101,13 +101,16 @@ const styles = StyleSheet.create({
|
||||
shadowOpacity: 0.15,
|
||||
shadowRadius: 12,
|
||||
elevation: 5,
|
||||
backgroundColor: colors.white,
|
||||
},
|
||||
gradient: {
|
||||
position: "relative",
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
// justifyContent: "center",
|
||||
// alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
borderRadius: 24,
|
||||
overflow: "hidden",
|
||||
gap: 10,
|
||||
},
|
||||
graphicCircleLarge: {
|
||||
position: "absolute",
|
||||
|
||||
@@ -2,6 +2,7 @@ import React from "react";
|
||||
import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import {Ionicons} from "@react-native-vector-icons/ionicons";
|
||||
import colors from "../colors";
|
||||
|
||||
type HeaderProps = {
|
||||
title: string;
|
||||
@@ -17,8 +18,8 @@ const Header: React.FC<HeaderProps> = ({
|
||||
showBack = true,
|
||||
onBackPress,
|
||||
rightAction,
|
||||
titleColor = "",
|
||||
arrowColor='pink'
|
||||
titleColor = colors.primary,
|
||||
arrowColor = colors.primary
|
||||
}) => {
|
||||
const navigation = useNavigation();
|
||||
|
||||
@@ -32,6 +33,11 @@ const Header: React.FC<HeaderProps> = ({
|
||||
|
||||
return (
|
||||
<View style={styles.header}>
|
||||
{showBack && (
|
||||
<TouchableOpacity onPress={handleBack} style={{padding:6}}>
|
||||
<Ionicons name="arrow-back" size={24} color={arrowColor} />
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
<Text style={[styles.headerTitle, {color:titleColor}]}>{title}</Text>
|
||||
<View>{rightAction}</View>
|
||||
</View>
|
||||
|
||||
@@ -20,6 +20,7 @@ import InviteScreen from "../screens/InviteScreen";
|
||||
import ManagementTabNavigation from "../screens/management/ManagementTabNavigation";
|
||||
import TransactionsList from "../screens/transaction/TransactionList";
|
||||
import RandomSelectUserScreen from "../screens/management/RandomSelectUserScreen";
|
||||
import Notification from "../screens/notification/Notification";
|
||||
|
||||
export type RootStackParamList = {
|
||||
Splash: undefined;
|
||||
@@ -42,6 +43,7 @@ export type RootStackParamList = {
|
||||
ManagementTabs:{ groupId: string | number;}
|
||||
TransactionList:undefined
|
||||
RandomSelectUserScreen: { groupId: string | number, cycleNumber: number };
|
||||
Notification:undefined
|
||||
};
|
||||
|
||||
const Stack = createNativeStackNavigator<RootStackParamList>();
|
||||
@@ -95,6 +97,7 @@ const linking = {
|
||||
<Stack.Screen name="ManagementTabs" component={ManagementTabNavigation} options={{ headerShown: false }} />
|
||||
<Stack.Screen name="TransactionList" component={TransactionsList} options={{ headerShown: false }} />
|
||||
<Stack.Screen name="RandomSelectUserScreen" component={RandomSelectUserScreen} options={{ headerShown: false }} />
|
||||
<Stack.Screen name="Notification" component={Notification} options={{ headerShown: false }} />
|
||||
</Stack.Navigator>
|
||||
</NavigationContainer>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||
|
||||
// Define the shape of a notification object
|
||||
export interface Notification {
|
||||
id: string;
|
||||
title: string;
|
||||
message: string;
|
||||
time: string;
|
||||
read: boolean;
|
||||
}
|
||||
|
||||
// Define the slice state type
|
||||
interface NotificationState {
|
||||
notifications: Notification[];
|
||||
}
|
||||
|
||||
// Initial state
|
||||
const initialState: NotificationState = {
|
||||
notifications: [],
|
||||
};
|
||||
|
||||
const notificationSlice = createSlice({
|
||||
name: 'notifications',
|
||||
initialState,
|
||||
reducers: {
|
||||
addNotification: (state, action: PayloadAction<Notification>) => {
|
||||
// Adds the new notification to the top
|
||||
state.notifications.unshift(action.payload);
|
||||
},
|
||||
removeNotification: (state, action: PayloadAction<string>) => {
|
||||
// Remove notification by id
|
||||
state.notifications = state.notifications.filter(
|
||||
(item) => item.id !== action.payload
|
||||
);
|
||||
},
|
||||
clearAllNotifications: (state) => {
|
||||
state.notifications = [];
|
||||
},
|
||||
markAsRead: (state, action: PayloadAction<string>) => {
|
||||
// Mark one notification as read
|
||||
const notification = state.notifications.find(
|
||||
(item) => item.id === action.payload
|
||||
);
|
||||
if (notification) {
|
||||
notification.read = true;
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const {
|
||||
addNotification,
|
||||
removeNotification,
|
||||
clearAllNotifications,
|
||||
markAsRead,
|
||||
} = notificationSlice.actions;
|
||||
|
||||
export default notificationSlice.reducer;
|
||||
+47
-10
@@ -1,13 +1,50 @@
|
||||
// store.ts
|
||||
import { configureStore } from "@reduxjs/toolkit";
|
||||
import userReducer from "./userSlice"; // adjust the path
|
||||
// // store.ts
|
||||
// import { configureStore } from "@reduxjs/toolkit";
|
||||
// import userReducer from "./userSlice"; // adjust the path
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: {
|
||||
user: userReducer, // register user slice here
|
||||
},
|
||||
// export const store = configureStore({
|
||||
// reducer: {
|
||||
// user: userReducer, // register user slice here
|
||||
// },
|
||||
// });
|
||||
|
||||
// // ✅ Types for TypeScript
|
||||
// export type RootState = ReturnType<typeof store.getState>;
|
||||
// export type AppDispatch = typeof store.dispatch;
|
||||
|
||||
|
||||
|
||||
import { configureStore, combineReducers } from '@reduxjs/toolkit';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import { persistReducer, persistStore } from 'redux-persist';
|
||||
|
||||
// import slices
|
||||
import userReducer from './userSlice';
|
||||
import notificationReducer from './notificationSlice';
|
||||
|
||||
// combine reducers
|
||||
const rootReducer = combineReducers({
|
||||
user: userReducer,
|
||||
notifications: notificationReducer,
|
||||
});
|
||||
|
||||
// ✅ Types for TypeScript
|
||||
export type RootState = ReturnType<typeof store.getState>;
|
||||
export type AppDispatch = typeof store.dispatch;
|
||||
// persist configuration
|
||||
const persistConfig = {
|
||||
key: 'root',
|
||||
storage: AsyncStorage,
|
||||
whitelist: ['user', 'notifications'], // persist both slices
|
||||
};
|
||||
|
||||
// wrap root reducer with persistReducer
|
||||
const persistedReducer = persistReducer(persistConfig, rootReducer);
|
||||
|
||||
// configure store
|
||||
export const store = configureStore({
|
||||
reducer: persistedReducer,
|
||||
middleware: (getDefaultMiddleware) =>
|
||||
getDefaultMiddleware({
|
||||
serializableCheck: false,
|
||||
}),
|
||||
});
|
||||
|
||||
export const persistor = persistStore(store);
|
||||
|
||||
+24
-22
@@ -20,7 +20,7 @@ import { setUserData } from "../../redux/userSlice";
|
||||
import { TabNavigationProp } from "../../navigation/BottomTabs";
|
||||
import UserProfileStatus from "./UserProfileStatus";
|
||||
import AnimatedCard from "../../components/common/AnimatedCard";
|
||||
import { Ionicons } from "@react-native-vector-icons/ionicons";
|
||||
import { Ionicons, IoniconsIconName } from "@react-native-vector-icons/ionicons";
|
||||
import { apiCall } from "../../utils/ApiHelper";
|
||||
|
||||
if (Platform.OS === "android" && UIManager.setLayoutAnimationEnabledExperimental) {
|
||||
@@ -49,16 +49,16 @@ interface ActionItem {
|
||||
|
||||
// Updated action items with a prettier pastel palette
|
||||
const organizerActions: ActionItem[] = [
|
||||
{ id: "1", title: "My Groups", subtitle: "Manage your groups", action: "NAVIGATE_MANAGEMENT", tab: "My Groups", iconName: "people-circle-outline", backOne: '#decbfcff', backTwo: '#B799FF' },
|
||||
{ id: "2", title: "Joined Groups", subtitle: "View member groups", action: "NAVIGATE_MANAGEMENT", tab: "Joined Groups", iconName: "people-outline", backOne: '#D7E9F7', backTwo: '#82AAE3' },
|
||||
{ id: "3", title: "Requests", subtitle: "Check new requests", action: "NAVIGATE_MANAGEMENT", tab: "Requests", iconName: "notifications-outline", backOne: '#DFF6DD', backTwo: '#88D18A' },
|
||||
{ id: "4", title: "Create Group", subtitle: "Create a new group", action: "NAVIGATE_CREATE_GROUP", tab: "Requests", iconName: "people-outline", backOne: '#DFF6DD', backTwo: '#88D18A' },
|
||||
{ id: "1", title: "My Groups", subtitle: "Manage your groups", action: "NAVIGATE_MANAGEMENT", tab: "My Groups", iconName: "people-circle-outline", backOne: '#decbfcff', backTwo: '#B799FF' },
|
||||
{ id: "2", title: "Joined Groups", subtitle: "View member groups", action: "NAVIGATE_MANAGEMENT", tab: "Joined Groups", iconName: "people-outline", backOne: '#D7E9F7', backTwo: '#82AAE3' },
|
||||
{ id: "3", title: "Requests", subtitle: "Check new requests", action: "NAVIGATE_MANAGEMENT", tab: "Requests", iconName: "notifications-outline", backOne: '#DFF6DD', backTwo: '#88D18A' },
|
||||
{ id: "4", title: "Create Group", subtitle: "Create a new group", action: "NAVIGATE_CREATE_GROUP", tab: "Requests", iconName: "people-outline", backOne: '#DFF6DD', backTwo: '#88D18A' },
|
||||
];
|
||||
|
||||
const userActions: ActionItem[] = [
|
||||
{ id: "1", title: "Joined Groups", subtitle: "See your groups", action: "NAVIGATE_MANAGEMENT", tab: "Joined Groups", iconName: "person-outline", backOne: '#D7E9F7', backTwo: '#82AAE3' },
|
||||
{ id: "2", title: "Your Requests", subtitle: "Track your requests", action: "NAVIGATE_MANAGEMENT", tab: "Your Requests", iconName: "mail-open-outline", backOne: '#FFF4D2', backTwo: '#FFB344' },
|
||||
{ id: "3", title: "Transactions", subtitle: "View your history", action: "TRANSACTION", iconName: "receipt-outline", backOne: '#decbfcff', backTwo: '#B799FF' },
|
||||
{ id: "1", title: "Joined Groups", subtitle: "See your groups", action: "NAVIGATE_MANAGEMENT", tab: "Joined Groups", iconName: "person-outline", backOne: '#D7E9F7', backTwo: '#82AAE3' },
|
||||
{ id: "2", title: "Your Requests", subtitle: "Track your requests", action: "NAVIGATE_MANAGEMENT", tab: "Your Requests", iconName: "mail-open-outline", backOne: '#FFF4D2', backTwo: '#FFB344' },
|
||||
{ id: "3", title: "Transactions", subtitle: "View your history", action: "TRANSACTION", iconName: "receipt-outline", backOne: '#decbfcff', backTwo: '#B799FF' },
|
||||
];
|
||||
|
||||
const Home: React.FC = () => {
|
||||
@@ -100,15 +100,15 @@ const Home: React.FC = () => {
|
||||
|
||||
const renderGridItem: ListRenderItem<ActionItem> = ({ item }) => (
|
||||
<View style={styles.cardWrapper}>
|
||||
<AnimatedCard
|
||||
key={item.id}
|
||||
title={item.title}
|
||||
subtitle={item.subtitle}
|
||||
iconName={item.iconName}
|
||||
backOne={item.backOne}
|
||||
backTwo={item.backTwo}
|
||||
onPress={() => handleActionPress(item)}
|
||||
/>
|
||||
<AnimatedCard
|
||||
key={item.id}
|
||||
title={item.title}
|
||||
subtitle={item.subtitle}
|
||||
iconName={item.iconName}
|
||||
backOne={item.backOne}
|
||||
backTwo={item.backTwo}
|
||||
onPress={() => handleActionPress(item)}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -124,15 +124,16 @@ const Home: React.FC = () => {
|
||||
<Text style={styles.greeting}>Hello,</Text>
|
||||
<Text style={styles.userName}>{user.firstName || apiUser?.firstName || 'User'}</Text>
|
||||
</View>
|
||||
<TouchableOpacity onPress={() => navigation.navigate("Profile" as never)}>
|
||||
<Image source={getProfileImageUri()} style={styles.profileImage} />
|
||||
<TouchableOpacity onPress={() => navigation.navigate("Notification" as never)}>
|
||||
{/* <Image source={getProfileImageUri()} style={styles.profileImage} /> */}
|
||||
<Ionicons name="notifications-outline" size={30} color={colors.textDark} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
|
||||
<UserProfileStatus />
|
||||
|
||||
<Text style={styles.sectionTitle}>Quick Actions</Text>
|
||||
|
||||
|
||||
<FlatList
|
||||
data={actions}
|
||||
renderItem={renderGridItem}
|
||||
@@ -184,6 +185,7 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
cardWrapper: {
|
||||
flex: 1,
|
||||
marginHorizontal: 8,
|
||||
// marginHorizontal: 8,
|
||||
// backgroundColor:'red'
|
||||
},
|
||||
});
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
FlatList,
|
||||
StyleSheet,
|
||||
} from 'react-native';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import {
|
||||
addNotification,
|
||||
removeNotification,
|
||||
clearAllNotifications,
|
||||
} from '../../redux/notificationSlice';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import { Ionicons } from '@react-native-vector-icons/ionicons';
|
||||
import AppView from '../../components/AppView';
|
||||
import Header from '../../components/common/Header';
|
||||
|
||||
const Notification = () => {
|
||||
const dispatch = useDispatch();
|
||||
const notifications = useSelector(
|
||||
(state: any) => state.notifications.notifications
|
||||
);
|
||||
|
||||
const handleAdd = () => {
|
||||
const newNotification = {
|
||||
id: Date.now().toString(),
|
||||
title: 'New Message',
|
||||
message: 'You have a new message in your inbox.',
|
||||
time: new Date().toLocaleString(),
|
||||
read: false,
|
||||
};
|
||||
dispatch(addNotification(newNotification));
|
||||
};
|
||||
|
||||
const handleDelete = (id: string) => {
|
||||
dispatch(removeNotification(id));
|
||||
};
|
||||
|
||||
const handleClearAll = () => {
|
||||
dispatch(clearAllNotifications());
|
||||
};
|
||||
|
||||
return (
|
||||
<AppView>
|
||||
{/* Header with Add and Clear All */}
|
||||
<Header title='Notifications' rightAction={<LinearGradient
|
||||
colors={['#FF6B6B', '#FF8E53']}
|
||||
style={styles.clearButtonGradient}>
|
||||
<TouchableOpacity onPress={handleClearAll}>
|
||||
<Text style={styles.clearButtonText}>Delete All</Text>
|
||||
</TouchableOpacity>
|
||||
</LinearGradient>}
|
||||
/>
|
||||
|
||||
|
||||
{/* Add Notification Button */}
|
||||
{/* <LinearGradient
|
||||
colors={['#4facfe', '#00f2fe']}
|
||||
style={styles.addButtonGradient}>
|
||||
<TouchableOpacity onPress={handleAdd}>
|
||||
<Text style={styles.addButtonText}>Add Notification</Text>
|
||||
</TouchableOpacity>
|
||||
</LinearGradient> */}
|
||||
|
||||
{/* Notification List */}
|
||||
<FlatList
|
||||
data={notifications}
|
||||
keyExtractor={(item) => item.id}
|
||||
showsVerticalScrollIndicator={false}
|
||||
contentContainerStyle={styles.listContainer}
|
||||
renderItem={({ item }) => (
|
||||
<LinearGradient
|
||||
colors={['#f5f7fa', '#c3cfe2']}
|
||||
style={styles.notificationCard}>
|
||||
<View style={styles.notificationContent}>
|
||||
<View style={{ flex: 1 }}>
|
||||
<Text style={styles.title}>{item.title}</Text>
|
||||
<Text style={styles.message}>{item.message}</Text>
|
||||
<Text style={styles.time}>{item.time}</Text>
|
||||
</View>
|
||||
<TouchableOpacity onPress={() => handleDelete(item.id)}>
|
||||
<Ionicons name="trash-outline" size={22} color="#e63946" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</LinearGradient>
|
||||
)}
|
||||
ListEmptyComponent={
|
||||
<Text style={styles.emptyText}>No notifications found.</Text>
|
||||
}
|
||||
/>
|
||||
</AppView>
|
||||
);
|
||||
};
|
||||
|
||||
export default Notification;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
headerContainer: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: 16,
|
||||
paddingTop: 12,
|
||||
},
|
||||
headerTitle: {
|
||||
fontSize: 20,
|
||||
fontWeight: '700',
|
||||
color: '#222',
|
||||
},
|
||||
clearButtonGradient: {
|
||||
borderRadius: 8,
|
||||
paddingVertical: 6,
|
||||
paddingHorizontal: 14,
|
||||
},
|
||||
clearButtonText: {
|
||||
color: '#fff',
|
||||
fontWeight: '600',
|
||||
},
|
||||
addButtonGradient: {
|
||||
margin: 16,
|
||||
borderRadius: 8,
|
||||
paddingVertical: 10,
|
||||
alignItems: 'center',
|
||||
},
|
||||
addButtonText: {
|
||||
color: '#fff',
|
||||
fontWeight: '600',
|
||||
fontSize: 16,
|
||||
},
|
||||
listContainer: {
|
||||
paddingHorizontal: 12,
|
||||
paddingBottom: 30,
|
||||
},
|
||||
notificationCard: {
|
||||
borderRadius: 10,
|
||||
padding: 12,
|
||||
marginBottom: 10,
|
||||
shadowColor: '#000',
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 5,
|
||||
elevation: 2,
|
||||
},
|
||||
notificationContent: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
},
|
||||
title: {
|
||||
fontWeight: '700',
|
||||
fontSize: 16,
|
||||
color: '#333',
|
||||
},
|
||||
message: {
|
||||
fontSize: 14,
|
||||
color: '#555',
|
||||
marginTop: 2,
|
||||
},
|
||||
time: {
|
||||
fontSize: 12,
|
||||
color: '#888',
|
||||
marginTop: 4,
|
||||
},
|
||||
emptyText: {
|
||||
textAlign: 'center',
|
||||
marginTop: 60,
|
||||
fontSize: 16,
|
||||
color: '#999',
|
||||
},
|
||||
});
|
||||
@@ -377,7 +377,7 @@ const Profile = () => {
|
||||
<View style={styles.header}>
|
||||
<Text style={styles.headerTitle}>User Profile</Text>
|
||||
<TouchableOpacity onPress={() => confirmLogout(navigation)} style={styles.refreshButton}>
|
||||
<Ionicons name="log-out-outline" size={24} color={colors.Profile} />
|
||||
<Ionicons name="log-out-outline" size={24} color={colors.primary} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
{/* if (fetching || !user) {
|
||||
@@ -701,7 +701,7 @@ const styles = StyleSheet.create({
|
||||
borderBottomRightRadius: 20,
|
||||
},
|
||||
headerTitle: {
|
||||
fontSize: 22, fontWeight: "600", color: colors.Profile
|
||||
fontSize: 22, fontWeight: "600", color: colors.primary
|
||||
},
|
||||
refreshButton: {
|
||||
padding: 4,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
export const BASE_URL = "https://api.godemo.in/FundCollect/api/"
|
||||
// export const BASE_URL = "https://api.godemo.in/FundCollect/api/"
|
||||
export const BASE_URL = "http://192.168.1.5:9060/api/"
|
||||
export const LOGIN_URL = `${BASE_URL}user/generate/otp?mobiles=`
|
||||
export const VARIFY_OTP_URL = `${BASE_URL}user/otp/verify`
|
||||
export const ORGRAGISTRATION = `${BASE_URL}organizer/registration/apply`
|
||||
|
||||
Reference in New Issue
Block a user