Skip to content

Commit

Permalink
admin panel v1.0.2
Browse files Browse the repository at this point in the history
  • Loading branch information
cangndz75 committed Dec 9, 2024
1 parent cd0eb80 commit 321d8c6
Show file tree
Hide file tree
Showing 6 changed files with 367 additions and 64 deletions.
53 changes: 46 additions & 7 deletions api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,17 @@ const authenticateToken = (req, res, next) => {

app.post('/register', async (req, res) => {
try {
const { email, password, firstName, lastName, role, image, aboutMe, interests, communityId } = req.body;
const {
email,
password,
firstName,
lastName,
role,
image,
aboutMe,
interests,
communityId,
} = req.body;

const newUser = new User({
email,
Expand All @@ -75,19 +85,21 @@ app.post('/register', async (req, res) => {
}
}

res.status(201).json({ message: 'User registered successfully', userId: newUser._id });
res
.status(201)
.json({message: 'User registered successfully', userId: newUser._id});
} catch (error) {
res.status(500).json({ message: 'Internal Server Error' });
res.status(500).json({message: 'Internal Server Error'});
}
});

app.post('/login', async (req, res) => {
try {
const { email, password } = req.body;
const user = await User.findOne({ email });
const {email, password} = req.body;
const user = await User.findOne({email});

if (!user || user.password !== password) {
return res.status(401).json({ message: 'Invalid credentials' });
return res.status(401).json({message: 'Invalid credentials'});
}

res.status(200).json({
Expand All @@ -103,7 +115,7 @@ app.post('/login', async (req, res) => {
following: user.following,
});
} catch (error) {
res.status(500).json({ message: 'Internal Server Error' });
res.status(500).json({message: 'Internal Server Error'});
}
});

Expand Down Expand Up @@ -1750,3 +1762,30 @@ app.put('/user/:userId/privacy', async (req, res) => {
res.status(500).json({message: 'Internal server error'});
}
});

app.post('/beorganizator', async (req, res) => {
console.log('Request received:', req.body);

const {email, firstName, lastName, reason} = req.body;

if (!email || !firstName || !lastName || !reason) {
return res.status(400).json({message: 'Please fill out all required fields.'});
}

try {
const user = await User.findOne({email});

if (!user) {
return res.status(404).json({message: 'User not found.'});
}

user.role = 'organizer';
user.aboutMe = reason;
await user.save();

return res.status(200).json({message: 'You are now an organizer!'});
} catch (error) {
console.error('Error updating user role:', error);
return res.status(500).json({message: 'An unexpected error occurred. Please try again later.'});
}
});
12 changes: 12 additions & 0 deletions navigation/StackNavigator.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import AdminEventSetUpScreen from '../screens/admin/AdminEventSetUpScreen';
import AdminCreateVenueScreen from '../screens/admin/AdminCreateVenueScreen';
import AdminCreateCommunityScreen from '../screens/admin/AdminCreateCommunityScreen';
import ManageRequest from '../screens/admin/ManageRequest';
import SearchScreen from '../screens/SearchScreen';
import BecomeOrganizerScreen from '../screens/BecomeOrganizerScreen';
const Stack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();

Expand Down Expand Up @@ -200,6 +202,16 @@ const MainStack = () => (
component={ManageRequest}
options={{headerShown: false}}
/>
<Stack.Screen
name="SearchScreen"
component={SearchScreen}
options={{headerShown: false}}
/>
<Stack.Screen
name="BecomeOrganizerScreen"
component={BecomeOrganizerScreen}
options={{headerShown: false}}
/>
</Stack.Navigator>
);

Expand Down
220 changes: 220 additions & 0 deletions screens/BecomeOrganizerScreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
import React, {useContext, useState, useEffect} from 'react';
import {
View,
Text,
TextInput,
TouchableOpacity,
Alert,
StyleSheet,
ActivityIndicator,
} from 'react-native';
import Ionicons from 'react-native-vector-icons/Ionicons';
import axios from 'axios';
import {AuthContext} from '../AuthContext';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {useNavigation} from '@react-navigation/native';

const BecomeOrganizerScreen = () => {
const {userId} = useContext(AuthContext);
const [formData, setFormData] = useState({
fullName: '',
email: '',
phone: '',
reason: '',
});
const [loading, setLoading] = useState(true);
const [editable, setEditable] = useState({
fullName: false,
email: false,
});
const navigation = useNavigation();

useEffect(() => {
const fetchUserData = async () => {
try {
const token = await AsyncStorage.getItem('token');
const response = await axios.get(
`http://10.0.2.2:8000/user/${userId}`,
{
headers: {Authorization: `Bearer ${token}`},
},
);

const user = response.data;
setFormData({
fullName: `${user.firstName} ${user.lastName}`,
email: user.email,
phone: '',
reason: '',
});
setLoading(false);
} catch (error) {
console.error('Error fetching user data:', error);
Alert.alert('Error', 'Failed to load user details.');
setLoading(false);
}
};

fetchUserData();
}, [userId]);

const handleInputChange = (key, value) => {
setFormData({...formData, [key]: value});
};

const handleSubmit = async () => {
const {fullName, email, phone, reason} = formData;

if (!fullName || !email || !reason) {
Alert.alert('Error', 'Please fill out all required fields.');
return;
}

try {
const token = await AsyncStorage.getItem('token');
await axios.post(
`http://10.0.2.2:8000/beorganizator`,
{
email,
firstName: fullName.split(' ')[0],
lastName: fullName.split(' ').slice(1).join(' '),
phone,
reason,
},
{headers: {Authorization: `Bearer ${token}`}},
);

Alert.alert('Success', 'You are now an organizer!');
await AsyncStorage.removeItem('token');
navigation.navigate('LoginScreen');
} catch (error) {
console.error('Error submitting form:', error);
Alert.alert('Error', 'Failed to submit the form. Please try again.');
}
};

if (loading) {
return (
<View style={styles.centered}>
<ActivityIndicator size="large" color="#5c6bc0" />
</View>
);
}

return (
<View style={styles.container}>
<Text style={styles.title}>Become an Organizer</Text>
<Text style={styles.subtitle}>
Fill out the form below to apply as an organizer.
</Text>

<View style={styles.inputContainer}>
<TextInput
style={styles.input}
placeholder="Full Name"
value={formData.fullName}
editable={editable.fullName}
onChangeText={text => handleInputChange('fullName', text)}
/>
<TouchableOpacity
onPress={() =>
setEditable(prev => ({...prev, fullName: !prev.fullName}))
}>
<Ionicons name="pencil" size={20} color="#5c6bc0" />
</TouchableOpacity>
</View>

<View style={styles.inputContainer}>
<TextInput
style={styles.input}
placeholder="Email"
value={formData.email}
editable={editable.email}
onChangeText={text => handleInputChange('email', text)}
/>
<TouchableOpacity
onPress={() => setEditable(prev => ({...prev, email: !prev.email}))}>
<Ionicons name="pencil" size={20} color="#5c6bc0" />
</TouchableOpacity>
</View>

<TextInput
style={styles.input}
placeholder="Phone Number"
value={formData.phone}
keyboardType="phone-pad"
onChangeText={text => handleInputChange('phone', text)}
/>
<TextInput
style={[styles.input, {height: 100}]}
placeholder="Why do you want to become an organizer?"
multiline
value={formData.reason}
onChangeText={text => handleInputChange('reason', text)}
/>

<TouchableOpacity style={styles.submitButton} onPress={handleSubmit}>
<Text style={styles.submitButtonText}>Submit</Text>
</TouchableOpacity>
</View>
);
};

export default BecomeOrganizerScreen;

const styles = StyleSheet.create({
container: {
flex: 1,
padding: 16,
backgroundColor: '#f8f8f8',
},
title: {
fontSize: 24,
fontWeight: 'bold',
color: '#333',
textAlign: 'center',
marginBottom: 8,
},
subtitle: {
fontSize: 16,
color: '#666',
textAlign: 'center',
marginBottom: 20,
},
input: {
backgroundColor: '#fff',
borderWidth: 1,
borderColor: '#ccc',
borderRadius: 8,
padding: 12,
marginBottom: 10,
flex: 1,
},
inputContainer: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: '#fff',
borderWidth: 1,
borderColor: '#ccc',
borderRadius: 8,
paddingHorizontal: 12,
marginBottom: 10,
},
submitButton: {
backgroundColor: '#5c6bc0',
padding: 15,
borderRadius: 8,
alignItems: 'center',
marginTop: 20,
},
submitButtonText: {
color: '#fff',
fontSize: 16,
fontWeight: 'bold',
},
centered: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
28 changes: 21 additions & 7 deletions screens/EventScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const EventScreen = () => {
route.params?.searchQuery || '',
);
const [filterModalVisible, setFilterModalVisible] = useState(false);
const [appliedFilters, setAppliedFilters] = useState({});

const categories = ['All', 'Sports', 'Music', 'Football'];

Expand All @@ -48,12 +49,18 @@ const EventScreen = () => {
}
};

const filteredEvents = events.filter(
event =>
(selectedCategory === 'All' ||
event.eventType.toLowerCase() === selectedCategory.toLowerCase()) &&
event.title.toLowerCase().includes(searchQuery.toLowerCase()),
);
const filteredEvents = events.filter(event => {
const matchesCategory =
selectedCategory === 'All' ||
event.eventType.toLowerCase() === selectedCategory.toLowerCase();
const matchesQuery = event.title
.toLowerCase()
.includes(searchQuery.toLowerCase());
const matchesFilters = Object.keys(appliedFilters).every(key =>
event[key] ? appliedFilters[key].includes(event[key]) : true,
);
return matchesCategory && matchesQuery && matchesFilters;
});

const renderHeader = () => (
<View style={{padding: 12, backgroundColor: '#7b61ff'}}>
Expand Down Expand Up @@ -133,7 +140,14 @@ const EventScreen = () => {
<FilterModal
visible={filterModalVisible}
onClose={() => setFilterModalVisible(false)}
onApply={filters => console.log(filters)}
onApply={filters => {
setAppliedFilters(filters);
setFilterModalVisible(false);
}}
onReset={() => {
setAppliedFilters({});
setFilterModalVisible(false);
}}
/>
</>
}
Expand Down
Loading

0 comments on commit 321d8c6

Please sign in to comment.