Skip to content

Commit 3eba01c

Browse files
authored
Merge pull request #2 from LikeKNU/develop
v1.0.3
2 parents 9485c28 + 7893f80 commit 3eba01c

File tree

143 files changed

+8536
-1557
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

143 files changed

+8536
-1557
lines changed

.gitignore

+8
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,11 @@ yarn-error.*
3535
*.tsbuildinfo
3636

3737
.idea/
38+
39+
secrets/
40+
41+
*.ipa
42+
*.aab
43+
44+
ios/
45+
android/

App.tsx

-20
This file was deleted.

README.md

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# 공주대처럼 | 공주대학교 학생들의 필수 앱
2+
3+
> 공주대학교 학생들을 위한 정보 제공 서비스
4+
5+
공지사항, 시내버스와 셔틀버스 시간, 식단메뉴, 학사일정을 하나의 앱에서 확인하세요!
6+
7+
<img src="https://github.com/FREEWAYseoul/.github/assets/69714701/39e1ddf2-9947-4dc2-884a-c80bdf6e4b85" width="20px" alt="#"/>**[iOS 다운로드](https://apps.apple.com/kr/app/id6499512208)**
8+
<img src="https://github.com/FREEWAYseoul/.github/assets/69714701/0dfec54f-81d6-4f9b-97ee-8c17e142189e" width="20px" alt="#"/>**[Android 다운로드](https://play.google.com/store/apps/details?id=ac.knu.likeknu)**
9+
10+
![앱 클립](https://github.com/LikeKNU/.github/assets/69714701/e16bfaa6-dc3e-471b-b3b6-158237affeab)
11+
12+
## 프로젝트 소개
13+
14+
### 🗓️ 기간
15+
16+
23.09.1 ~ 계속
17+
18+
### ⚙️ 기술 스택
19+
20+
#### App
21+
22+
<img src="https://img.shields.io/badge/React Native-222222?style=flat&logo=React&logoColor=61DAFB" alt="#"/> <img src="https://img.shields.io/badge/TypeScript-3178C6?style=flat&logo=TypeScript&logoColor=white" alt="#"/> <img src="https://img.shields.io/badge/Expo-000020?style=flat&logo=Expo&logoColor=white" alt="#"/>
23+
24+
#### Back-end
25+
26+
<img src="https://img.shields.io/badge/Spring Boot-6DB33F?style=flat&logo=SpringBoot&logoColor=white" alt="#"/> <img src="https://img.shields.io/badge/Hibernate-59666C?style=flat&logo=Hibernate&logoColor=white" alt="#"/> <img src="https://img.shields.io/badge/MySQL-4479A1?style=flat&logo=MySQL&logoColor=white" alt="#"/>
27+
<br>
28+
<img src="https://img.shields.io/badge/RabbitMQ-FF6600?style=flat&logo=RabbitMQ&logoColor=white" alt="#"/> <img src="https://img.shields.io/badge/Redis-DC382D?style=flat&logo=Redis&logoColor=white" alt="#"/> <img src="https://img.shields.io/badge/OpenAI-412991?style=flat&logo=OpenAI&logoColor=white" alt="#"/>
29+
30+
### 📱 소개
31+
32+
<img src="https://github.com/LikeKNU/LikeKNU/assets/69714701/a0a54400-0639-461e-941c-f5c82844a89a" width="280px" alt="#">
33+
34+
<img src="https://github.com/LikeKNU/LikeKNU/assets/69714701/063b1f83-7475-488b-a041-db05466d2f96" width="280px" alt="#">
35+
36+
<img src="https://github.com/LikeKNU/LikeKNU/assets/69714701/cd693dd4-2103-492b-b37d-6d9fb1550efb" width="280px" alt="#">
37+
38+
<img src="https://github.com/LikeKNU/LikeKNU/assets/69714701/1ac568aa-13eb-4b04-9992-36a09c831c26" width="280px" alt="#">
39+
40+
<img src="https://github.com/LikeKNU/LikeKNU/assets/69714701/0369570f-661d-4336-8912-d35173a12200" width="280px" alt="#">
41+
42+
<img src="https://github.com/LikeKNU/LikeKNU/assets/69714701/bc2ce7dc-9b49-42a9-8b90-bbb404633eca" width="280px" alt="#">
43+
44+
45+
### System Architecture
46+
47+
![System Architecture](https://github.com/LikeKNU/.github/assets/69714701/0fe21330-7475-4d55-a4a7-f8bd8fec8cdd)

api/announcement.ts

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { useCampus } from '@/common/contexts/CampusContext';
2+
import { campusName } from '@/constants/campus';
3+
import { AnnouncementProps } from '@/types/announcementType';
4+
import { useDeviceId } from '@/utils/device';
5+
import http, { extractBodyFromResponse, extractMessageFromResponse } from '@/utils/http';
6+
import useSWR from 'swr';
7+
import useSWRInfinite from 'swr/infinite';
8+
9+
export const useAnnouncements = (category: string) => {
10+
const { campus } = useCampus();
11+
const { deviceId } = useDeviceId();
12+
const getKey = (index: number, previousPageData: any) => {
13+
if (previousPageData && !previousPageData.length) {
14+
return null;
15+
}
16+
if (campus && deviceId) {
17+
return `/api/announcements/${category}?campus=${campusName[campus].value}&page=${index + 1}&deviceId=${deviceId}`;
18+
}
19+
};
20+
21+
const getAnnouncements = async (uri: string) => {
22+
const response = await http.get<AnnouncementProps[]>(uri);
23+
return extractBodyFromResponse<AnnouncementProps[]>(response) ?? [];
24+
};
25+
26+
return useSWRInfinite(getKey, getAnnouncements, { initialSize: 1, revalidateFirstPage: false });
27+
};
28+
29+
export const useAnnouncementsSearch = (keyword: string) => {
30+
const { campus } = useCampus();
31+
const { deviceId } = useDeviceId();
32+
const getKey = (index: number, previousPageData: any) => {
33+
if (previousPageData && !previousPageData.length) {
34+
return null;
35+
}
36+
if (campus && deviceId) {
37+
return `/api/announcements?campus=${campusName[campus].value}&page=${index + 1}&keyword=${keyword}&deviceId=${deviceId}`;
38+
}
39+
};
40+
41+
const searchAnnouncements = async (uri: string) => {
42+
const response = await http.get<AnnouncementProps[]>(uri);
43+
return extractBodyFromResponse<AnnouncementProps[]>(response) ?? [];
44+
};
45+
46+
return useSWRInfinite(getKey, searchAnnouncements, { initialSize: 1, revalidateFirstPage: false });
47+
};
48+
49+
export const useBookmarkAnnouncements = () => {
50+
const { deviceId } = useDeviceId();
51+
const getBookmarkAnnouncements = async (uri: string, deviceId: string | null) => {
52+
if (deviceId) {
53+
const response = await http.get<AnnouncementProps[]>(`${uri}/${deviceId}`);
54+
return extractBodyFromResponse<AnnouncementProps[]>(response) ?? [];
55+
}
56+
};
57+
58+
return useSWR(['/api/bookmarks', deviceId], ([uri, deviceId]) => getBookmarkAnnouncements(uri, deviceId));
59+
};
60+
61+
export const addBookmark = async (announcementId: string, deviceId: string) => {
62+
const response = await http.post<string, any>(`/api/bookmarks/${deviceId}`, { announcementId: announcementId });
63+
return extractMessageFromResponse(response);
64+
};
65+
66+
export const removeBookmark = async (announcementId: string, deviceId: string) => {
67+
const response = await http.delete<string>(`/api/bookmarks/${deviceId}/${announcementId}`);
68+
return extractMessageFromResponse(response);
69+
};

api/bus.ts

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { useCampus } from '@/common/contexts/CampusContext';
2+
import { Campuses, campusName } from '@/constants/campus';
3+
import { CityBusProps, ShuttleBusProps, ShuttleRouteProps } from '@/types/busTypes';
4+
import { ValueNameType } from '@/types/common';
5+
import http, { extractBodyFromResponse } from '@/utils/http';
6+
import useSWR from 'swr';
7+
8+
export const useCityBuses = (routeType: ValueNameType) => {
9+
const { campus } = useCampus();
10+
const getCityBuses = async (uri: string, campus: Campuses | null) => {
11+
if (campus) {
12+
const response = await http.getWithParams<CityBusProps[]>(uri, { campus: campusName[campus].value });
13+
return extractBodyFromResponse<CityBusProps[]>(response) ?? [];
14+
}
15+
};
16+
17+
return useSWR([`/api/buses/city-bus/${routeType.value}`, campus], ([uri, campus]) => getCityBuses(uri, campus));
18+
};
19+
20+
export const useShuttleRoutes = () => {
21+
const { campus } = useCampus();
22+
const getShuttleRoutes = async (uri: string, campus: Campuses | null) => {
23+
if (campus) {
24+
const response = await http.getWithParams<ShuttleRouteProps[]>(uri, { campus: campusName[campus].value });
25+
return extractBodyFromResponse<ShuttleRouteProps[]>(response) ?? [];
26+
}
27+
};
28+
29+
return useSWR(['/api/buses/shuttle-bus/routes', campus], ([uri, campus]) => getShuttleRoutes(uri, campus));
30+
};
31+
32+
export const useShuttleBuses = (shuttleId: string) => {
33+
const getShuttleBuses = async (uri: string) => {
34+
const response = await http.get<ShuttleBusProps[]>(uri);
35+
return extractBodyFromResponse<ShuttleBusProps[]>(response) ?? [];
36+
};
37+
38+
return useSWR(`/api/buses/shuttle-bus/${shuttleId}`, getShuttleBuses);
39+
};

api/calendar.ts

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { CalendarProps } from '@/types/calendarTypes';
2+
import http, { extractBodyFromResponse } from '@/utils/http';
3+
import useSWR from 'swr';
4+
5+
export const useCalendar = () => {
6+
const getCalendar = async (uri: string) => {
7+
const response = await http.get<CalendarProps[]>(uri);
8+
return extractBodyFromResponse<CalendarProps[]>(response) ?? [];
9+
};
10+
11+
return useSWR('/api/schedule', getCalendar);
12+
};

api/home.ts

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { useCampus } from '@/common/contexts/CampusContext';
2+
import { Campuses, campusName } from '@/constants/campus';
3+
import { HomeAnnouncementProps, HomeBusProps, HomeCalendarProps, HomeMealProps } from '@/types/homeType';
4+
import http, { extractBodyFromResponse } from '@/utils/http';
5+
import useSWR from 'swr';
6+
7+
export const useHomeAnnouncements = () => {
8+
const { campus } = useCampus();
9+
const getHomeAnnouncements = async (uri: string, campus: Campuses | null) => {
10+
if (campus) {
11+
const response = await http.getWithParams<HomeAnnouncementProps[]>(uri, { campus: campusName[campus].value });
12+
return extractBodyFromResponse<HomeAnnouncementProps[]>(response) ?? [];
13+
}
14+
};
15+
16+
return useSWR(['/api/main/announcements', campus], ([uri, campus]) => getHomeAnnouncements(uri, campus));
17+
};
18+
19+
export const useHomeBuses = () => {
20+
const { campus } = useCampus();
21+
const getHomeBuses = async (uri: string, campus: Campuses | null) => {
22+
if (campus) {
23+
const response = await http.getWithParams<HomeBusProps[]>(uri, { campus: campusName[campus].value });
24+
return extractBodyFromResponse<HomeBusProps[]>(response) ?? [];
25+
}
26+
};
27+
28+
return useSWR(['/api/main/buses', campus], ([uri, campus]) => getHomeBuses(uri, campus));
29+
};
30+
31+
export const useHomeMeal = () => {
32+
const { campus } = useCampus();
33+
const getHomeMeals = async (uri: string, campus: Campuses | null) => {
34+
if (campus) {
35+
const response = await http.getWithParams<HomeMealProps[]>(uri, { campus: campusName[campus].value });
36+
return extractBodyFromResponse<HomeMealProps[]>(response) ?? [];
37+
}
38+
};
39+
40+
return useSWR(['/api/main/menu', campus], ([uri, campus]) => getHomeMeals(uri, campus));
41+
};
42+
43+
export const useHomeCalendar = () => {
44+
const getHomeCalendar = async (uri: string) => {
45+
const response = await http.get<HomeCalendarProps[]>(uri);
46+
return extractBodyFromResponse<HomeCalendarProps[]>(response) ?? [];
47+
};
48+
49+
return useSWR('/api/main/schedule', getHomeCalendar);
50+
};

api/meal.ts

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { useCampus } from '@/common/contexts/CampusContext';
2+
import { Campuses, campusName } from '@/constants/campus';
3+
import { cafeterias, Cafeterias } from '@/constants/meal';
4+
import { MealProps } from '@/types/mealTypes';
5+
import http, { extractBodyFromResponse } from '@/utils/http';
6+
import useSWR from 'swr';
7+
8+
export const useMeals = (cafeteria: Cafeterias) => {
9+
const { campus } = useCampus();
10+
const getMeals = async (uri: string, campus: Campuses | null, cafeteria: Cafeterias) => {
11+
if (campus && cafeterias[campus].includes(cafeteria)) {
12+
const response = await http.getWithParams<MealProps[]>(uri, {
13+
campus: campusName[campus].value,
14+
cafeteriaName: cafeteria
15+
});
16+
return extractBodyFromResponse<MealProps[]>(response) ?? [];
17+
}
18+
};
19+
20+
return useSWR(['/api/menus', campus, cafeteria], ([uri, campus, cafeteria]) => getMeals(uri, campus, cafeteria));
21+
};

api/suggestion.ts

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { useDeviceId } from '@/utils/device';
2+
import http, { extractMessageFromResponse } from '@/utils/http';
3+
4+
export const sendSuggestion = async (deviceId: string, content: string) => {
5+
if (deviceId) {
6+
const response = await http.post<string, any>(`/api/suggestions`, { deviceId: deviceId, content: content });
7+
return extractMessageFromResponse(response);
8+
}
9+
};

app.config.js

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export default ({ config }) => {
2+
return {
3+
...config,
4+
android: {
5+
...config.android,
6+
googleServicesFile: process.env.GOOGLE_SERVICES_JSON
7+
},
8+
ios: {
9+
...config.ios,
10+
googleServicesFile: process.env.GOOGLE_SERVICE_INFO_PLIST
11+
}
12+
};
13+
};

0 commit comments

Comments
 (0)