Skip to content

Commit

Permalink
Merge pull request #29 from tawanda-kembo/fix/adds-pygments-dependency
Browse files Browse the repository at this point in the history
fix: adds pygments dependency
  • Loading branch information
tawandakembo authored Sep 22, 2024
2 parents 4ce85e0 + 6708a32 commit 311e464
Show file tree
Hide file tree
Showing 51 changed files with 1,652 additions and 38 deletions.
Binary file added docs/examples/.DS_Store
Binary file not shown.
5 changes: 5 additions & 0 deletions docs/examples/appointment-scheduler/.firebaserc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"projects": {
"default": "code-collator"
}
}
22 changes: 22 additions & 0 deletions docs/examples/appointment-scheduler/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
node_modules/
.expo/
dist/
npm-debug.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision
*.orig.*
web-build/

# macOS
.DS_Store

# @generated expo-cli sync-2b81b286409207a5da26e14c78851eb30d8ccbdb
# The following patterns were generated by expo-cli

expo-env.d.ts
# @end expo-cli

package-lock.json
50 changes: 50 additions & 0 deletions docs/examples/appointment-scheduler/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Welcome to your Expo app 👋

This is an [Expo](https://expo.dev) project created with [`create-expo-app`](https://www.npmjs.com/package/create-expo-app).

## Get started

1. Install dependencies

```bash
npm install
```

2. Start the app

```bash
npx expo start
```

In the output, you'll find options to open the app in a

- [development build](https://docs.expo.dev/develop/development-builds/introduction/)
- [Android emulator](https://docs.expo.dev/workflow/android-studio-emulator/)
- [iOS simulator](https://docs.expo.dev/workflow/ios-simulator/)
- [Expo Go](https://expo.dev/go), a limited sandbox for trying out app development with Expo

You can start developing by editing the files inside the **app** directory. This project uses [file-based routing](https://docs.expo.dev/router/introduction).

## Get a fresh project

When you're ready, run:

```bash
npm run reset-project
```

This command will move the starter code to the **app-example** directory and create a blank **app** directory where you can start developing.

## Learn more

To learn more about developing your project with Expo, look at the following resources:

- [Expo documentation](https://docs.expo.dev/): Learn fundamentals, or go into advanced topics with our [guides](https://docs.expo.dev/guides).
- [Learn Expo tutorial](https://docs.expo.dev/tutorial/introduction/): Follow a step-by-step tutorial where you'll create a project that runs on Android, iOS, and the web.

## Join the community

Join our community of developers creating universal apps.

- [Expo on GitHub](https://github.com/expo/expo): View our open source platform and contribute.
- [Discord community](https://chat.expo.dev): Chat with Expo users and ask questions.
36 changes: 36 additions & 0 deletions docs/examples/appointment-scheduler/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"expo": {
"name": "appointment-scheduler",
"slug": "appointment-scheduler",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/images/icon.png",
"scheme": "myapp",
"userInterfaceStyle": "automatic",
"splash": {
"image": "./assets/images/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"ios": {
"supportsTablet": true
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/images/adaptive-icon.png",
"backgroundColor": "#ffffff"
}
},
"web": {
"bundler": "metro",
"output": "static",
"favicon": "./assets/images/favicon.png"
},
"plugins": [
"expo-router"
],
"experiments": {
"typedRoutes": true
}
}
}
45 changes: 45 additions & 0 deletions docs/examples/appointment-scheduler/app/(tabs)/_layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import FontAwesome from '@expo/vector-icons/FontAwesome';
import { Tabs } from 'expo-router';
import { useColorScheme } from 'react-native';

import Colors from '@/constants/Colors';

function TabBarIcon(props: {
name: React.ComponentProps<typeof FontAwesome>['name'];
color: string;
}) {
return <FontAwesome size={28} style={{ marginBottom: -3 }} {...props} />;
}

export default function TabLayout() {
const colorScheme = useColorScheme();

return (
<Tabs
screenOptions={{
tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint,
}}>
<Tabs.Screen
name="index"
options={{
title: 'Home',
tabBarIcon: ({ color }) => <TabBarIcon name="home" color={color} />,
}}
/>
<Tabs.Screen
name="appointments"
options={{
title: 'Appointments',
tabBarIcon: ({ color }) => <TabBarIcon name="calendar" color={color} />,
}}
/>
<Tabs.Screen
name="profile"
options={{
title: 'Profile',
tabBarIcon: ({ color }) => <TabBarIcon name="user" color={color} />,
}}
/>
</Tabs>
);
}
149 changes: 149 additions & 0 deletions docs/examples/appointment-scheduler/app/(tabs)/appointments.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import React, { useState, useEffect } from 'react';
import { StyleSheet, ScrollView, Button, Alert, FlatList } from 'react-native';
import { Calendar } from 'react-native-calendars';
import { collection, addDoc, query, where, getDocs, deleteDoc, doc } from 'firebase/firestore';
import { auth, db } from '../../firebaseConfig';

import { Text, View } from '@/components/Themed';

const TIME_SLOTS = [
'09:00', '10:00', '11:00', '12:00', '14:00', '15:00', '16:00', '17:00'
];

export default function AppointmentsScreen() {
const [selected, setSelected] = useState('');
const [availableSlots, setAvailableSlots] = useState(TIME_SLOTS);
const [userAppointments, setUserAppointments] = useState([]);

useEffect(() => {
if (selected) {
fetchBookedSlots();
}
fetchUserAppointments();
}, [selected]);

const fetchBookedSlots = async () => {
const appointmentsRef = collection(db, 'appointments');
const q = query(appointmentsRef, where('date', '==', selected));
const querySnapshot = await getDocs(q);
const bookedSlots = querySnapshot.docs.map(doc => doc.data().time);
setAvailableSlots(TIME_SLOTS.filter(slot => !bookedSlots.includes(slot)));
};

const fetchUserAppointments = async () => {
if (auth.currentUser) {
const appointmentsRef = collection(db, 'appointments');
const q = query(appointmentsRef, where('userId', '==', auth.currentUser.uid));
const querySnapshot = await getDocs(q);
const appointments = querySnapshot.docs.map(doc => ({
id: doc.id,
...doc.data()
}));
setUserAppointments(appointments);
}
};

const bookAppointment = async (time: string) => {
try {
await addDoc(collection(db, 'appointments'), {
userId: auth.currentUser?.uid,
date: selected,
time: time,
});
Alert.alert('Success', 'Appointment booked successfully!');
fetchBookedSlots();
fetchUserAppointments();
} catch (error) {
Alert.alert('Error', 'Failed to book appointment. Please try again.');
}
};

const cancelAppointment = async (appointmentId: string) => {
try {
await deleteDoc(doc(db, 'appointments', appointmentId));
Alert.alert('Success', 'Appointment cancelled successfully!');
fetchUserAppointments();
} catch (error) {
Alert.alert('Error', 'Failed to cancel appointment. Please try again.');
}
};

const renderAppointment = ({ item }) => (
<View style={styles.appointmentItem}>
<Text>{`Date: ${item.date}, Time: ${item.time}`}</Text>
<Button title="Cancel" onPress={() => cancelAppointment(item.id)} color="red" />
</View>
);

return (
<ScrollView style={styles.container}>
<Text style={styles.title}>Book an Appointment</Text>
<Calendar
onDayPress={day => {
setSelected(day.dateString);
}}
markedDates={{
[selected]: { selected: true, disableTouchEvent: true, selectedColor: 'blue' }
}}
/>
{selected ? (
<View style={styles.selectedDate}>
<Text>Selected Date: {selected}</Text>
<Text style={styles.subtitle}>Available Time Slots:</Text>
{availableSlots.map((slot) => (
<Button
key={slot}
title={slot}
onPress={() => bookAppointment(slot)}
/>
))}
</View>
) : null}
<View style={styles.appointmentsListContainer}>
<Text style={styles.subtitle}>Your Appointments:</Text>
<FlatList
data={userAppointments}
renderItem={renderAppointment}
keyExtractor={item => item.id}
/>
</View>
</ScrollView>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
},
title: {
fontSize: 20,
fontWeight: 'bold',
textAlign: 'center',
marginVertical: 20,
},
subtitle: {
fontSize: 16,
fontWeight: 'bold',
marginTop: 10,
marginBottom: 5,
},
selectedDate: {
marginTop: 20,
padding: 20,
alignItems: 'center',
},
appointmentsListContainer: {
marginTop: 20,
padding: 20,
},
appointmentItem: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 10,
padding: 10,
borderWidth: 1,
borderColor: 'gray',
borderRadius: 5,
},
});
Loading

0 comments on commit 311e464

Please sign in to comment.