Skip to content

Commit

Permalink
Merge pull request #373 from TAMUSHPE/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
JasonIsAzn authored Jun 1, 2024
2 parents d48f249 + 0ff05d9 commit 12124f0
Show file tree
Hide file tree
Showing 84 changed files with 348 additions and 755 deletions.
2 changes: 1 addition & 1 deletion src/api/__tests__/firebaseUtils.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { signInAnonymously } from "firebase/auth";
import { db, auth, storage } from "../../config/firebaseConfig";
import { PrivateUserInfo, PublicUserInfo } from "../../types/User";
import { PrivateUserInfo, PublicUserInfo } from "../../types/user";
import { randomUint8Array, randomStr, randomStrRange } from "../../helpers/unitTestUtils"
import * as firebaseUtils from "../firebaseUtils";
import { deleteDoc, doc } from "firebase/firestore";
Expand Down
5 changes: 2 additions & 3 deletions src/api/fetchGoogleSheets.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { validateTamuEmail } from "../helpers/validation";
import { GoogleSheetsResponse, PointsColumnVals } from "../types/GoogleSheetsTypes";
import { GoogleSheetsResponse } from "../types/googleSheetsTypes";

/**
* Constant defining different google sheet ids used
Expand All @@ -24,7 +23,7 @@ export const queryGoogleSpreadsheet = async (sheetID: string, query: string = "s
This function queries a google spreadsheet for data given certain parameters
*/
const spreadsheetURI = `https://docs.google.com/spreadsheets/d/${sheetID}/gviz/tq?tq=${encodeURIComponent(query)}&sheet=${sheetName}`;

return await fetch(spreadsheetURI)
.then(async (res) => {
const responseText = await res.text()
Expand Down
8 changes: 4 additions & 4 deletions src/api/firebaseUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { ref, uploadBytesResumable, UploadTask, UploadMetadata, listAll, deleteO
import { doc, setDoc, getDoc, arrayUnion, collection, where, query, getDocs, orderBy, addDoc, updateDoc, deleteDoc, Timestamp, limit, startAfter, Query, DocumentData, CollectionReference, QueryDocumentSnapshot, increment, runTransaction, deleteField, GeoPoint, writeBatch, DocumentSnapshot } from "firebase/firestore";
import { HttpsCallableResult, httpsCallable } from "firebase/functions";
import { validateTamuEmail } from "../helpers/validation";
import { OfficerStatus, PrivateUserInfo, PublicUserInfo, Roles, User, UserFilter } from "../types/User";
import { Committee } from "../types/Committees";
import { SHPEEvent, EventLogStatus, UserEventData } from "../types/Events";
import { OfficerStatus, PrivateUserInfo, PublicUserInfo, Roles, User, UserFilter } from "../types/user";
import { Committee } from "../types/committees";
import { SHPEEvent, EventLogStatus, UserEventData } from "../types/events";
import * as Location from 'expo-location';
import { deleteUser } from "firebase/auth";
import { LinkData } from "../types/Links";
import { LinkData } from "../types/links";
import { getBlobFromURI } from "./fileSelection";

/**
Expand Down
142 changes: 103 additions & 39 deletions src/components/CustomDropDown.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { View, Text, TouchableOpacity, TextInput, FlatList, Animated, TouchableWithoutFeedback, Dimensions, LayoutChangeEvent, LayoutRectangle, ScrollView } from 'react-native';
import { View, Text, TouchableOpacity, TextInput, Animated, TouchableWithoutFeedback, Dimensions, LayoutChangeEvent, LayoutRectangle, ScrollView, Platform, Modal } from 'react-native';
import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
import { Octicons } from '@expo/vector-icons';
import DismissibleModal from './DismissibleModal';


/**
Expand All @@ -19,6 +20,7 @@ import { Octicons } from '@expo/vector-icons';
* @param {function} onSelect - The callback function to execute when an item is selected.
* @param {string} searchKey - The key to be used for searching items.
* @param {string} label - Default label to be shown when no item is selected.
* @param {boolean} darkMode - Defines whether to display the dropdown in darkmode colors.
* @param {function} onToggle - Function to toggle the dropdown open/closed.
* @param {boolean} isOpen - Boolean to control the visibility of the dropdown.
* @param {Object} ref - Ref object for parent component to access child methods.
Expand All @@ -31,13 +33,14 @@ import { Octicons } from '@expo/vector-icons';
* @param {string} [textClassName=""] - Additional class name for the text elements.
* @returns {React.ReactElement} The CustomDropDownMenu component.
*/
const CustomDropDownMenu = forwardRef(({ data, onSelect, isOpen, searchKey, onToggle, label, title, selectedItemProp, disableSearch, displayType = "both", containerClassName = "", dropDownClassName = "", textClassName = "", titleClassName = "" }: {
const CustomDropDownMenu = forwardRef(({ data, onSelect, isOpen, searchKey, onToggle, label, darkMode, title, selectedItemProp, disableSearch, displayType = "both", containerClassName = "", dropDownClassName = "", textClassName = "", titleClassName = "" }: {
data: Item[];
onSelect: (item: Item) => void;
searchKey: string;
isOpen: boolean;
onToggle: () => void;
label: string;
darkMode?: boolean,
title?: string;
selectedItemProp?: SelectedItem | null;
disableSearch?: boolean;
Expand All @@ -48,10 +51,10 @@ const CustomDropDownMenu = forwardRef(({ data, onSelect, isOpen, searchKey, onTo
titleClassName?: string;
textboxClassName?: string;
}, ref) => {
const [search, setSearch] = useState('');
const [filteredData, setFilteredData] = useState(data);
const [search, setSearch] = useState<string>('');
const [filteredData, setFilteredData] = useState<Item[]>(data);
const [selectedItem, setSelectedItem] = useState<SelectedItem | null>(null)
const [isFocused, setIsFocused] = useState(false);
const [isFocused, setIsFocused] = useState<boolean>(false);
const searchRef = useRef<TextInput>(null);
const moveTitle = useRef(new Animated.Value(0)).current;
const [componentLayout, setComponentLayout] = useState<LayoutRectangle | null>(null);
Expand Down Expand Up @@ -199,19 +202,19 @@ const CustomDropDownMenu = forwardRef(({ data, onSelect, isOpen, searchKey, onTo
</TouchableWithoutFeedback>
)}
{title && (
<Animated.Text className={"w-[100%] ml-3 items-center self-center border-gray-400 font-semibold text-lg text-white " + titleClassName} style={{ transform: [{ translateY: yVal }] }}>
<Animated.Text className={`w-[100%] ml-3 items-center self-center border-gray-400 font-semibold text-lg ${darkMode ? "text-white" : "text-black"} ` + titleClassName} style={{ transform: [{ translateY: yVal }] }}>
{title}
</Animated.Text>
)}
<TouchableOpacity
className='flex-row justify-between items-center self-center bg-white rounded-md w-[100%] h-12 px-3 border-gray-400 border'
className={`flex-row justify-between items-center self-center rounded-md w-[100%] h-12 px-3 border ${darkMode ? "bg-neutral-800 border-neutral-600" : "bg-white border-gray-400"}`}
activeOpacity={1}
onPress={() => {
onToggle()
setIsFocused(true)
}}>

<Text className={'font-bold text-gray-400 text-xl ' + textClassName}>
<Text className={`font-bold text-lg ${darkMode ? "text-gray-200" : "text-gray-400"}` + textClassName}>
{getDisplayText()}
</Text>
</TouchableOpacity>
Expand All @@ -225,42 +228,103 @@ const CustomDropDownMenu = forwardRef(({ data, onSelect, isOpen, searchKey, onTo
</TouchableOpacity>
)}
</View>
{isOpen ? (
<View className={"absolute top-14 self-center bg-white rounded-md h-72 w-[100%] border-gray-400 border px-1 " + dropDownClassName}>
{!disableSearch && (
<TextInput
placeholder="Search.."
value={search}
ref={searchRef}
onChangeText={txt => {
onSearch(txt);
setSearch(txt);
}}
className='w-[90%] h-12 self-center mt-6 pl-3 rounded-md border-gray-400 border'
/>
)}

<ScrollView className='mt-4'
scrollEnabled={isFocused}
>
{filteredData.map((item, index) => (
<TouchableOpacity
onPress={() => handleSelect(item)}
className='w-[85%] self-center h-12 justify-center border-b border-b-gray-400'
key={index}
>
<Text className='text-lg font-semibold'>
{getItemDisplayText(item)}
</Text>
</TouchableOpacity>
))}
</ScrollView>
</View>
) : null}
{/* Absolute Positioning of a ScrollView only works on iOS */}
{isOpen && Platform.OS == "ios" && (
<DropDown
darkMode={darkMode}
disableSearch={disableSearch}
search={search}
dropDownClassName={dropDownClassName}
isFocused={isFocused}
filteredData={filteredData}
onSearch={onSearch}
handleSelect={handleSelect}
getItemDisplayText={getItemDisplayText}
searchRef={searchRef}
setSearch={setSearch}
/>
)}

{/* Android must use a modal instead of absolute positioning of a ScrollView */}
<DismissibleModal
visible={isOpen && Platform.OS == "android"}
setVisible={() => {
onToggle()
setIsFocused(true)
}}
>
<DropDown
darkMode={darkMode}
disableSearch={disableSearch}
search={search}
dropDownClassName={dropDownClassName}
isFocused={isFocused}
filteredData={filteredData}
onSearch={onSearch}
handleSelect={handleSelect}
getItemDisplayText={getItemDisplayText}
searchRef={searchRef}
setSearch={setSearch}
/>
</DismissibleModal>
</View>
);
});

/**
* This component is used in both the iOS and Android dropdown, but in different contexts.
* This is a separate component to make it so there is consistancy between both platforms.
*/
const DropDown = ({ darkMode, disableSearch, search, searchRef, dropDownClassName, isFocused, filteredData, onSearch, setSearch, handleSelect, getItemDisplayText }: {
darkMode: boolean | undefined,
disableSearch: boolean | undefined,
search: string,
isFocused: boolean,
dropDownClassName: string,
filteredData: Item[],
searchRef: React.RefObject<TextInput>,
onSearch: (str: string) => void,
setSearch: (str: string) => void,
handleSelect: (item: Item) => void,
getItemDisplayText: (item: Item) => string,
}) => {
return (
<View className={`self-center rounded-md px-1 ${Platform.OS == "ios" ? "absolute h-72 w-[100%] top-14" : "max-h-[60%] w-[90%]"} ${darkMode ? "bg-secondary-bg-dark" : "bg-white border border-gray-400"} ` + dropDownClassName}>
{!disableSearch && (
<TextInput
placeholder="Search.."
value={search}
ref={searchRef}
onChangeText={txt => {
onSearch(txt);
setSearch(txt);
}}
className={`w-[90%] h-12 self-center mt-6 pl-3 rounded-md border ${darkMode ? "border-neutral-700 bg-neutral-800 text-white" : "border-neutral-800 bg-white text-black"}`}
placeholderTextColor={darkMode ? "#c2c2c2" : "#000"}
/>
)}
<ScrollView
className='mt-4'
scrollEnabled={isFocused}
nestedScrollEnabled
>
{filteredData.map((item, index) => (
<TouchableOpacity
onPress={() => handleSelect(item)}
className={`w-[85%] self-center min-h-12 py-2 justify-center ${index != filteredData.length - 1 ? "border-b border-b-gray-400" : ""}`}
key={index}
>
<Text className={`text-lg ${darkMode ? "text-neutral-300" : "text-black font-semibold"}`}>
{getItemDisplayText(item)}
</Text>
</TouchableOpacity>
))}
</ScrollView>
</View>
);
}

interface Item {
[key: string]: any;
iso?: string;
Expand Down
8 changes: 3 additions & 5 deletions src/components/DismissibleModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,15 @@ const DismissibleModal = ({ visible, setVisible, children }: {
visible={visible}
onRequestClose={() => setVisible(false)}
>
<TouchableOpacity
<TouchableWithoutFeedback
onPress={() => setVisible(false)}
className="h-[100%] w-[100%]"
style={{ backgroundColor: 'rgba(0,0,0,0.3)' }}
>
<View className='items-center justify-center h-full'>
<View className='items-center justify-center h-[100%] w-[100%] bg-[#0000009b]'>
<TouchableWithoutFeedback>
{children}
</TouchableWithoutFeedback>
</View>
</TouchableOpacity>
</TouchableWithoutFeedback>
</Modal>
);
};
Expand Down
4 changes: 2 additions & 2 deletions src/components/EventsList.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { View, Text, ActivityIndicator, Image, TouchableOpacity } from 'react-native'
import React from 'react'
import { Timestamp } from 'firebase/firestore';
import { Committee, getLogoComponent } from '../types/Committees';
import { SHPEEvent } from '../types/Events';
import { Committee, getLogoComponent } from '../types/committees';
import { SHPEEvent } from '../types/events';
import { Images } from '../../assets';
import { monthNames } from '../helpers/timeUtils';

Expand Down
85 changes: 0 additions & 85 deletions src/components/FeaturedItem.tsx

This file was deleted.

Loading

0 comments on commit 12124f0

Please sign in to comment.