diff --git a/package.json b/package.json
index 3d80ad5..ae9bef9 100644
--- a/package.json
+++ b/package.json
@@ -8,6 +8,7 @@
"@react-navigation/devtools": "^6.0.20",
"@react-navigation/drawer": "^6.6.6",
"@react-navigation/native": "^6.1.9",
+ "@react-navigation/stack": "^6.3.20",
"@tanstack/react-query": "^5.8.3",
"expo": "^49.0.3",
"expo-splash-screen": "~0.20.5",
diff --git a/src/components/drawer/routes.ts b/src/components/drawer/routes.ts
index c5cfa84..c31eb9f 100644
--- a/src/components/drawer/routes.ts
+++ b/src/components/drawer/routes.ts
@@ -3,6 +3,7 @@ import RestoMenu from "../../routes/resto";
import EventView from "../../routes/events";
import { DrawerEntry } from "../../types/drawer";
import SchamperView from "../../routes/schamper";
+import LibrariesView from "../../routes/libraries";
import { SchamperIcon } from "../icons/SchamperIcon";
export const routes: DrawerEntry[] = [
@@ -26,4 +27,9 @@ export const routes: DrawerEntry[] = [
element: SchamperView,
icon: SchamperIcon,
},
+ {
+ name: "Libraries",
+ element: LibrariesView,
+ icon: "book",
+ }
];
diff --git a/src/components/feed/LibraryDetailsComponent.tsx b/src/components/feed/LibraryDetailsComponent.tsx
new file mode 100644
index 0000000..4fdbeb5
--- /dev/null
+++ b/src/components/feed/LibraryDetailsComponent.tsx
@@ -0,0 +1,72 @@
+import { Surface, Text, TouchableRipple, useTheme } from "react-native-paper";
+import type { Library } from "../../types/stores";
+import { Pressable, StyleSheet, View } from "react-native";
+import * as WebBrowser from "expo-web-browser";
+export const LibraryDetailsComponent = ({ library }: { library: Library }) => {
+ const theme = useTheme();
+
+ return (
+
+
+
+
+ {library.name_nl}
+
+
+
+ {library.address.join(" ")}
+ {library.email}
+ {library.telephone}
+
+
+
+
+ WebBrowser.openBrowserAsync(library.link)}>
+ Go to site
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ display: "flex",
+ flexDirection: "column",
+ marginVertical: 5,
+ width: "95%",
+ borderRadius: 15,
+ overflow: "hidden",
+ },
+ textContainer: {
+ padding: 15,
+ color: "#ddd",
+ },
+ title: {
+ fontWeight: "600",
+ color: "#000",
+ },
+ additionalInfo: {
+ marginTop: 5,
+ display: "flex",
+ flexDirection: "row",
+ alignItems: "center",
+ justifyContent: "space-between",
+ color: "#ddd",
+ },
+ smallText: {
+ color: "#000",
+ fontWeight: "900",
+ },
+ button: {
+ alignItems: 'center',
+ justifyContent: 'center',
+ paddingVertical: 12,
+ paddingHorizontal: 32,
+ borderRadius: 4,
+ elevation: 3,
+ width: 200,
+ alignSelf: 'center',
+ marginBottom: 10,
+ },
+});
+
diff --git a/src/components/feed/LibraryListItemComponent.tsx b/src/components/feed/LibraryListItemComponent.tsx
new file mode 100644
index 0000000..2966b38
--- /dev/null
+++ b/src/components/feed/LibraryListItemComponent.tsx
@@ -0,0 +1,104 @@
+import { Surface, Text, TouchableRipple } from "react-native-paper";
+import type { Library } from "../../types/stores";
+import { GestureResponderEvent, Pressable, Image, StyleSheet, View } from "react-native";
+import { useEffect, useState } from "react";
+import * as WebBrowser from "expo-web-browser";
+
+
+export const LibraryListItemComponent = ({ library, onPress, showDetails }: { library: Library, onPress: ((event: GestureResponderEvent) => void), showDetails: boolean}) => {
+ const [imgSize, setImgSize] = useState({ width: 0, height: 1 });
+
+ useEffect(() => {
+ Image.getSize(library.image_url, (w, h) => {
+ setImgSize({
+ width: w,
+ height: h,
+ });
+ });
+ }, [library.image_url]);
+
+ return (
+
+
+ <>
+
+
+
+ {library.name_nl}
+
+
+
+ {library.address.join(" ")}
+ {
+ showDetails ?
+ <>
+ {library.email}
+ {library.telephone}
+ >
+ :
+ <>>
+ }
+
+
+
+ >
+
+ {
+ showDetails ?
+ WebBrowser.openBrowserAsync(library.link)}>
+ Go to site
+
+ :
+ <>>
+ }
+
+ );
+};
+const styles = StyleSheet.create({
+ container: {
+ display: "flex",
+ flexDirection: "column",
+ marginVertical: 5,
+ width: "95%",
+ borderRadius: 15,
+ overflow: "hidden",
+ },
+ textContainer: {
+ padding: 15,
+ color: "#ddd",
+ },
+ title: {
+ fontWeight: "600",
+ color: "#000",
+ },
+ additionalInfo: {
+ marginTop: 5,
+ display: "flex",
+ flexDirection: "row",
+ alignItems: "center",
+ justifyContent: "space-between",
+ color: "#ddd",
+ },
+ smallText: {
+ color: "#000",
+ fontWeight: "900",
+ },
+ button: {
+ alignItems: 'center',
+ justifyContent: 'center',
+ paddingVertical: 12,
+ paddingHorizontal: 32,
+ borderRadius: 4,
+ elevation: 3,
+ width: 200,
+ alignSelf: 'center',
+ marginBottom: 10,
+ },
+});
+
diff --git a/src/constant.ts b/src/constant.ts
index 7dff0af..e7377c5 100644
--- a/src/constant.ts
+++ b/src/constant.ts
@@ -1,4 +1,5 @@
export const ENDPOINTS = {
HYDRA_V1: "https://hydra.ugent.be/api/1.0/",
HYDRA_V2: "https://hydra.ugent.be/api/2.0/",
+ LIBRARIES: "https://widgets.lib.ugent.be/"
};
diff --git a/src/routes/libraries.tsx b/src/routes/libraries.tsx
new file mode 100644
index 0000000..a724815
--- /dev/null
+++ b/src/routes/libraries.tsx
@@ -0,0 +1,28 @@
+import { useLibrariesQuery } from "../stores/libraries";
+import { LibraryListItemComponent } from "../components/feed/LibraryListItemComponent";
+import { StyleSheet, ScrollView } from "react-native";
+import { useState } from "react";
+import { Library } from "../types/stores";
+
+
+const LibrariesView = () => {
+ const { data: libraryRequest } = useLibrariesQuery();
+ const [selectedLibrary, setSelectedLibrary] = useState(null);
+
+ return (
+
+ {libraryRequest.libraries.map(lib => (
+ setSelectedLibrary(lib)} showDetails={lib==selectedLibrary}/>
+ ))}
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ display: "flex",
+ alignItems: "center",
+ },
+});
+
+export default LibrariesView;
diff --git a/src/stores/libraries.ts b/src/stores/libraries.ts
new file mode 100644
index 0000000..b711d75
--- /dev/null
+++ b/src/stores/libraries.ts
@@ -0,0 +1,18 @@
+import { LibraryRequest } from "../types/stores";
+import { ENDPOINTS } from "../constant";
+import { useSuspenseQuery } from "@tanstack/react-query";
+import { useFocusNotifyOnChangeProps } from "../lib/hooks/useFocusNotifyOnChangeProps";
+
+export const useLibrariesQuery = () => {
+ const notifyOnChangeProps = useFocusNotifyOnChangeProps();
+
+ const schamperQuery = useSuspenseQuery({
+ queryKey: ["libraries"],
+ queryFn: async () => {
+ const res = await fetch(`${ENDPOINTS.LIBRARIES}/library_groups/main.json`);
+ return res.json();
+ },
+ notifyOnChangeProps,
+ });
+ return schamperQuery;
+};
diff --git a/src/types/stores.ts b/src/types/stores.ts
index 465ed64..938dfd7 100644
--- a/src/types/stores.ts
+++ b/src/types/stores.ts
@@ -14,3 +14,39 @@ export declare type Article = {
// ISO date string
pub_date: string;
};
+
+export declare type LibraryRequest = {
+ libraries: Library[];
+};
+
+export declare type Library = {
+ name_en: string;
+ has_hours: boolean;
+ lat: number;
+ image_url: string;
+ telephone: string[];
+ reading_room: string;
+ link_nl: string;
+ created_at: string;
+ door_number: string;
+ email: string;
+ department: string;
+ contact: string;
+ pickup_locations: string[];
+ updated_at: string;
+ link_en: string;
+ active: boolean;
+ email_acquisition: string;
+ cubee_id: string;
+ link: string;
+ sap_id: string;
+ shipment_library_code: string;
+ name: string;
+ faculty: string;
+ code: string;
+ thumbnail_url: string;
+ address: string[];
+ name_nl: string;
+ campus: string;
+ long: number;
+};
diff --git a/yarn.lock b/yarn.lock
index 378701c..e8ed9d6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2075,6 +2075,15 @@
dependencies:
nanoid "^3.1.23"
+"@react-navigation/stack@^6.3.20":
+ version "6.3.20"
+ resolved "https://registry.yarnpkg.com/@react-navigation/stack/-/stack-6.3.20.tgz#8eec944888f317bb1ba1ff30e7f513806bea16c2"
+ integrity sha512-vE6mgZzOgoa5Uy7ayT97Cj+ZIK7DK+JBYVuKUViILlWZy6IWK7HFDuqoChSbZ1ajTIfAxj/acVGg1jkbAKsToA==
+ dependencies:
+ "@react-navigation/elements" "^1.3.21"
+ color "^4.2.3"
+ warn-once "^0.1.0"
+
"@segment/loosely-validate-event@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@segment/loosely-validate-event/-/loosely-validate-event-2.0.0.tgz#87dfc979e5b4e7b82c5f1d8b722dfd5d77644681"