Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/mobile/notifications #214

Merged
merged 15 commits into from
Jul 17, 2024
Merged
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
21 changes: 18 additions & 3 deletions .github/workflows/deploy-golang-develop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,21 @@ jobs:
script: |
cd /home/${{ secrets.VM_USERNAME }}/occupi-backend-dev/occupi-backend
echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
DOCKER_USERNAME=${{ secrets.DOCKER_USERNAME }} docker compose -f docker-compose.dev.yml down
DOCKER_USERNAME=${{ secrets.DOCKER_USERNAME }} docker compose -f docker-compose.dev.yml pull
DOCKER_USERNAME=${{ secrets.DOCKER_USERNAME }} docker compose -f docker-compose.dev.yml up -d
MONGO_INITDB_ROOT_USERNAME=${{ secrets.MONGO_INITDB_ROOT_USERNAME }} \
MONGO_INITDB_ROOT_PASSWORD=${{ secrets.MONGO_INITDB_ROOT_PASSWORD }} \
RABBITMQ_DEFAULT_USER=${{ secrets.RABBITMQ_DEFAULT_USER }} \
RABBITMQ_DEFAULT_PASS=${{ secrets.RABBITMQ_DEFAULT_PASS }} \
DOCKER_USERNAME=${{ secrets.DOCKER_USERNAME }} \
docker compose -f docker-compose.dev.yml down
MONGO_INITDB_ROOT_USERNAME=${{ secrets.MONGO_INITDB_ROOT_USERNAME }} \
MONGO_INITDB_ROOT_PASSWORD=${{ secrets.MONGO_INITDB_ROOT_PASSWORD }} \
RABBITMQ_DEFAULT_USER=${{ secrets.RABBITMQ_DEFAULT_USER }} \
RABBITMQ_DEFAULT_PASS=${{ secrets.RABBITMQ_DEFAULT_PASS }} \
DOCKER_USERNAME=${{ secrets.DOCKER_USERNAME }} \
docker compose -f docker-compose.dev.yml pull
MONGO_INITDB_ROOT_USERNAME=${{ secrets.MONGO_INITDB_ROOT_USERNAME }} \
MONGO_INITDB_ROOT_PASSWORD=${{ secrets.MONGO_INITDB_ROOT_PASSWORD }} \
RABBITMQ_DEFAULT_USER=${{ secrets.RABBITMQ_DEFAULT_USER }} \
RABBITMQ_DEFAULT_PASS=${{ secrets.RABBITMQ_DEFAULT_PASS }} \
DOCKER_USERNAME=${{ secrets.DOCKER_USERNAME }} \
docker compose -f docker-compose.dev.yml up -d
21 changes: 18 additions & 3 deletions .github/workflows/deploy-golang-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,21 @@ jobs:
script: |
cd /home/${{ secrets.VM_USERNAME }}/occupi-backend-prod/occupi-backend
echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
DOCKER_USERNAME=${{ secrets.DOCKER_USERNAME }} docker compose -f docker-compose.prod.yml down
DOCKER_USERNAME=${{ secrets.DOCKER_USERNAME }} docker compose -f docker-compose.prod.yml pull
DOCKER_USERNAME=${{ secrets.DOCKER_USERNAME }} docker compose -f docker-compose.prod.yml up -d
MONGO_INITDB_ROOT_USERNAME=${{ secrets.MONGO_INITDB_ROOT_USERNAME }} \
MONGO_INITDB_ROOT_PASSWORD=${{ secrets.MONGO_INITDB_ROOT_PASSWORD }} \
RABBITMQ_DEFAULT_USER=${{ secrets.RABBITMQ_DEFAULT_USER }} \
RABBITMQ_DEFAULT_PASS=${{ secrets.RABBITMQ_DEFAULT_PASS }} \
DOCKER_USERNAME=${{ secrets.DOCKER_USERNAME }} \
docker compose -f docker-compose.prod.yml down
MONGO_INITDB_ROOT_USERNAME=${{ secrets.MONGO_INITDB_ROOT_USERNAME }} \
MONGO_INITDB_ROOT_PASSWORD=${{ secrets.MONGO_INITDB_ROOT_PASSWORD }} \
RABBITMQ_DEFAULT_USER=${{ secrets.RABBITMQ_DEFAULT_USER }} \
RABBITMQ_DEFAULT_PASS=${{ secrets.RABBITMQ_DEFAULT_PASS }} \
DOCKER_USERNAME=${{ secrets.DOCKER_USERNAME }} \
docker compose -f docker-compose.prod.yml pull
MONGO_INITDB_ROOT_USERNAME=${{ secrets.MONGO_INITDB_ROOT_USERNAME }} \
MONGO_INITDB_ROOT_PASSWORD=${{ secrets.MONGO_INITDB_ROOT_PASSWORD }} \
RABBITMQ_DEFAULT_USER=${{ secrets.RABBITMQ_DEFAULT_USER }} \
RABBITMQ_DEFAULT_PASS=${{ secrets.RABBITMQ_DEFAULT_PASS }} \
DOCKER_USERNAME=${{ secrets.DOCKER_USERNAME }} \
docker compose -f docker-compose.prod.yml up -d
115 changes: 103 additions & 12 deletions documentation/occupi-docs/pages/api-documentation/api-usage.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ The API also allows you to retrieve information about these resources.
- [ViewBookings](#ViewBookings)
- [CancelBooking](#CancelBooking)
- [CheckIn](#CheckIn)
- [Users](#users)
- [Roles](#roles)
- [Get Users](#Get-users)
- [Get Notifications](#Get-notifications)
- [Get push tokens](#Get-push-tokens)

## Base URL

Expand Down Expand Up @@ -984,16 +985,16 @@ If there are any errors during the process, appropriate error messages are retur
- **Code:** 500
- **Content:** `{ "status": 500, "message": "Failed to update user details", "error": {"code":"INTERNAL_SERVER_ERROR","details":null,"message":"Failed to update user details"} }`

### FilterUsers
### Get Users

This endpoint is used to filter users in the Occupi system.
The client needs to provide the filter criteria.
This endpoint is used to get users in the Occupi system.
The client can provide a filter criteria if they want to.
Upon a successful request, a list of users that match the filter criteria is returned.
If there are any errors during the process, appropriate error messages are returned.

- **URL**

`/api/filter-users`
`/api/get-users`

- **Method**

Expand All @@ -1005,30 +1006,120 @@ If there are any errors during the process, appropriate error messages are retur

```json copy
{
"operator": "eq", // eq, ne, gt, gte, lt, lte, in, nin default to eq
"filter": {
"onSite": true
"onSite": true // this is a filter to filter by
},
"projection": ["email", "role"],
"order_asc": "role", // column to sort in ascending order
"order_desc": "email", // column to sort in descending order
"projection": ["email", "role"], // this is which columns you want returned
"limit": 50, // default is 50 and is the maximum
"page": 1 // default is 1, but can be incremented to get the next page
}

```
or as a url(note that the order in which you place the parameters does not matter, place them as you please)
```copy
https://dev.occupi.tech/api/filter-users?filter={"onSite": true}&projection=email,role&limit=50&page=1
```

**Success Response**

- **Code:** 200

- **Content:** `{ "status": 200, "message": "Successfully fetched users!", "data": []"list of all users"], "meta": {"currentPage": 1,"totalPages": 20,"totalResults": 7}, }`
- **Content:** `{ "status": 200, "message": "Successfully fetched users!", "data": ["list of all users"], "meta": {"currentPage": 1,"totalPages": 20,"totalResults": 7}, }`

**Error Response**

- **Code:** 400
- **Code:** 500

- **Content:** `{ "status": 500, "message": "Failed to get users", "error": {"code":"INTERNAL_SERVER_ERROR","details":null,"message":"Failed to get users"} }`

### Get Notifications

This endpoint is used to get notifications in the Occupi system.
The client can provide a filter criteria if they want to.
Upon a successful request, a list of notifications that match the filter criteria is returned.
If there are any errors during the process, appropriate error messages are returned.

- **URL**

`/api/get-notifications`

- **Method**

`GET`

- **Request Body**

- **Content:** `{ "status": 400, "message": "Invalid request payload", "error": {"code":"BAD_REQUEST","details":null,"message":"Expected Department Number"}, }`
- **Content**

```json copy
{
"operator": "eq", // eq, ne, gt, gte, lt, lte, in, nin default to eq
"filter": {
"emails": ["test@example.com"] // this is a filter to filter by
},
"order_asc": "message", // column to sort in ascending order
"order_desc": "title", // column to sort in descending order
"projection": ["message", "title", "unreadEmails"], // this is which columns you want returned
"limit": 50, // default is 50 and is the maximum
"page": 1 // default is 1, but can be incremented to get the next page
}

```
or as a url(note that the order in which you place the parameters does not matter, place them as you please)
```copy
https://dev.occupi.tech/api/get-notifications?filter={"emails": ["test@example.com"]}&projection=message,title,unreadEmails&limit=50&page=1
```

**Success Response**

- **Code:** 200

- **Content:** `{ "status": 200, "message": "Successfully fetched notifications!", "data": ["list of all notifications"], "meta": {"currentPage": 1,"totalPages": 20,"totalResults": 7}, }`

**Error Response**

- **Code:** 500

- **Content:** `{ "status": 500, "message": "Failed to get users", "error": {"code":"INTERNAL_SERVER_ERROR","details":null,"message":"Failed to get users"} }`
- **Content:** `{ "status": 500, "message": "Failed to get notifications", "error": {"code":"INTERNAL_SERVER_ERROR","details":null,"message":"Failed to get notifications"} }`

### Get push tokens

This endpoint is used to get the expo push tokens for the given emails

- **URL**

`/api/get-push-tokens`

- **Method**

`GET`

- **Request Body**

- **Content**

```json copy
{
"emails": ["test@example.com"]
}

```
or as a url(note that the order in which you place the parameters does not matter, place them as you please)
```copy
https://dev.occupi.tech/api/get-push-tokens?emails=test@example.com,test1@example.com,test2@example.com
```

**Success Response**

- **Code:** 200

- **Content:** `{ "status": 200, "message": "Successfully fetched tokens!", "data": ["list of all tokens"] }`

**Error Response**

- **Code:** 500

- **Content:** `{ "status": 500, "message": "Failed to get tokens", "error": {"code":"INTERNAL_SERVER_ERROR","details":null,"message":"Failed to get tokens"} }`
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const ViewBookingDetails = (bookingId:string, roomName:string) => {
const [checkedIn, setCheckedIn] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const toast = useToast();
const apiUrl = process.env.EXPO_PUBLIC_LOCAL_API_URL;
const apiUrl = process.env.EXPO_PUBLIC_DEVELOP_API_URL;
const checkinendpoint = process.env.EXPO_PUBLIC_CHECK_IN;
const cancelbookingendpoint = process.env.EXPO_PUBLIC_CANCEL_BOOKING;

Expand Down
12 changes: 8 additions & 4 deletions frontend/occupi-mobile4/screens/Office/BookingDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
SafeAreaView,
useColorScheme,
Alert,
ScrollView
ScrollView,
} from "react-native";
import {
View,
Expand All @@ -21,12 +21,13 @@ import {
import { Ionicons, Feather, MaterialCommunityIcons, Octicons } from "@expo/vector-icons";
import { useNavigation } from "@react-navigation/native";
import { LinearGradient } from "expo-linear-gradient";
import { useRouter, useLocalSearchParams } from 'expo-router';
import { useRouter } from 'expo-router';
import { ActivityIndicator } from 'react-native';
import * as LocalAuthentication from "expo-local-authentication";
import * as SecureStore from 'expo-secure-store';
import GradientButton from '@/components/GradientButton';

import { sendPushNotification } from "@/utils/utils";

const BookingDetails = () => {
const navigation = useNavigation();
Expand All @@ -48,15 +49,15 @@ const BookingDetails = () => {
// console.log(attendees);
const cardBackgroundColor = isDark ? '#2C2C2E' : '#F3F3F3';
const steps = ["Booking details", "Invite attendees", "Receipt"];
const apiUrl = process.env.EXPO_PUBLIC_LOCAL_API_URL;
const apiUrl = process.env.EXPO_PUBLIC_DEVELOP_API_URL;
const bookroomendpoint = process.env.EXPO_PUBLIC_BOOK_ROOM;

useEffect(() => {
const getbookingInfo = async () => {
let userinfo = await SecureStore.getItemAsync('UserData');
// console.log(result);
// if (result !== undefined) {
let jsoninfo = JSON.parse(userinfo);
console.log("data",jsoninfo?.data.details.name);
setCreatorEmail(jsoninfo?.data?.email);
let result: string = await SecureStore.getItemAsync('BookingInfo');
console.log("CurrentRoom:", jsoninfo?.data?.email);
Expand Down Expand Up @@ -96,6 +97,8 @@ const BookingDetails = () => {
};
console.log("hereeeeee", body);
let authToken = await SecureStore.getItemAsync('Token');
let userinfo = await SecureStore.getItemAsync('UserData');
let jsoninfo = JSON.parse(userinfo);
try {
setLoading(true);
const response = await fetch(`${apiUrl}${bookroomendpoint}`, {
Expand All @@ -111,6 +114,7 @@ const BookingDetails = () => {
const data = await response.json();
console.log(data);
if (response.ok) {
sendPushNotification(['ExponentPushToken[5cpRYINQu42bhcKM5b7Vsb]','ExponentPushToken[ARLofOIiMGuJjE2EQTWQWq]'], "New Booking", `${jsoninfo?.data.details.name} has invited you to a booking.`);
setCurrentStep(2);
setLoading(false);
toast.show({
Expand Down
5 changes: 4 additions & 1 deletion frontend/occupi-mobile4/screens/Settings/NotifTester.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ Notifications.setNotificationHandler({

async function sendPushNotification(expoPushToken: string) {
const message = {
to: expoPushToken,
trigger: {
seconds: 10
},
to: "ExponentPushToken[ARLofOIiMGuJjE2EQTWQWq]",
sound: 'default',
title: 'Original Title',
body: 'And here is the body!',
Expand Down
32 changes: 32 additions & 0 deletions frontend/occupi-mobile4/utils/utils.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import * as Notifications from 'expo-notifications';


Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldShowAlert: true,
shouldPlaySound: false,
shouldSetBadge: false,
}),
});

export async function sendPushNotification(expoPushTokens: string[], title: string, body: string) {
const messages = expoPushTokens.map(token => ({
to: token,
sound: 'default',
title: title,
body: body,
data: { someData: 'goes here' },
}));

for (const message of messages) {
await fetch('https://exp.host/--/api/v2/push/send', {
method: 'POST',
headers: {
Accept: 'application/json',
'Accept-encoding': 'gzip, deflate',
'Content-Type': 'application/json',
},
body: JSON.stringify(message),
});
}
}
Loading
Loading