浏览代码

Project Refactoring

Savio Fernando 1 年之前
父节点
当前提交
a91eb86d6f
共有 100 个文件被更改,包括 745 次插入384 次删除
  1. 3 3
      App.js
  2. 7 0
      DEV_NOTES.md
  3. 0 12
      assets/images/images.js
  4. 72 0
      package-lock.json
  5. 1 0
      package.json
  6. 0 49
      screens/BookmarkPage.js
  7. 0 237
      screens/NewsDetailPage.js
  8. 11 0
      src/api/APIHandler.js
  9. 23 0
      src/api/article.js
  10. 9 0
      src/api/bookmarks.js
  11. 18 0
      src/api/constants.js
  12. 0 0
      src/assets/fonts/OFL.txt
  13. 0 0
      src/assets/fonts/Poppins-Black.ttf
  14. 0 0
      src/assets/fonts/Poppins-BlackItalic.ttf
  15. 0 0
      src/assets/fonts/Poppins-Bold.ttf
  16. 0 0
      src/assets/fonts/Poppins-BoldItalic.ttf
  17. 0 0
      src/assets/fonts/Poppins-ExtraBold.ttf
  18. 0 0
      src/assets/fonts/Poppins-ExtraBoldItalic.ttf
  19. 0 0
      src/assets/fonts/Poppins-ExtraLight.ttf
  20. 0 0
      src/assets/fonts/Poppins-ExtraLightItalic.ttf
  21. 0 0
      src/assets/fonts/Poppins-Italic.ttf
  22. 0 0
      src/assets/fonts/Poppins-Light.ttf
  23. 0 0
      src/assets/fonts/Poppins-LightItalic.ttf
  24. 0 0
      src/assets/fonts/Poppins-Medium.ttf
  25. 0 0
      src/assets/fonts/Poppins-MediumItalic.ttf
  26. 0 0
      src/assets/fonts/Poppins-Regular.ttf
  27. 0 0
      src/assets/fonts/Poppins-SemiBold.ttf
  28. 0 0
      src/assets/fonts/Poppins-SemiBoldItalic.ttf
  29. 0 0
      src/assets/fonts/Poppins-Thin.ttf
  30. 0 0
      src/assets/fonts/Poppins-ThinItalic.ttf
  31. 0 0
      src/assets/images/VertCard.png
  32. 0 0
      src/assets/images/get_started.png
  33. 0 0
      src/assets/images/hp_newscard.png
  34. 12 0
      src/assets/images/images.js
  35. 0 0
      src/assets/images/newscout_logo_dark.png
  36. 0 0
      src/assets/images/newscout_logo_light.png
  37. 0 0
      src/assets/images/newscout_text_light.png
  38. 0 0
      src/assets/images/no_bookmark.png
  39. 0 0
      src/assets/images/pubg.png
  40. 0 0
      src/components/atoms/Button.js
  41. 0 0
      src/components/atoms/ButtonWrapper.js
  42. 0 0
      src/components/atoms/Card.js
  43. 1 1
      src/components/atoms/Header.js
  44. 0 0
      src/components/molecules/FormTextInput.js
  45. 0 0
      src/components/molecules/NewscoutLogo.js
  46. 0 0
      src/components/molecules/NewscoutTextLogo.js
  47. 0 0
      src/components/molecules/SearchTextInput.js
  48. 0 0
      src/components/molecules/ThemedSwitch.js
  49. 0 0
      src/components/organisms/Buttons/BookmarkButton.js
  50. 0 0
      src/components/organisms/Buttons/CircularPrimaryBackButton.js
  51. 43 0
      src/components/organisms/Buttons/CloseButton.js
  52. 0 0
      src/components/organisms/Buttons/EditButton.js
  53. 0 0
      src/components/organisms/Buttons/PrimaryButton.js
  54. 0 0
      src/components/organisms/Buttons/PrimaryOutlineButton.js
  55. 0 0
      src/components/organisms/Buttons/SecondaryButton.js
  56. 0 0
      src/components/organisms/Buttons/SecondaryOutlineButton.js
  57. 0 0
      src/components/organisms/Buttons/SettingsButton.js
  58. 0 0
      src/components/organisms/Buttons/ShareButton.js
  59. 0 0
      src/components/organisms/Buttons/ThemedTextButton.js
  60. 0 0
      src/components/organisms/Cards/CategoryCard.js
  61. 0 0
      src/components/organisms/Cards/CommentCard.js
  62. 2 2
      src/components/organisms/Cards/HorizontalNewsCard.js
  63. 37 35
      src/components/organisms/Cards/HorizontalNewsCardVariant.js
  64. 0 0
      src/components/organisms/Cards/ImageBGCard.js
  65. 0 0
      src/components/organisms/Cards/NotificationCard.js
  66. 3 3
      src/components/organisms/Cards/VerticalNewsCard.js
  67. 0 0
      src/components/organisms/Headers/NewscoutCenteredTitleHeader.js
  68. 0 0
      src/components/organisms/Headers/NewscoutHomeHeader.js
  69. 0 0
      src/components/organisms/Headers/NewscoutTitleHeader.js
  70. 0 0
      src/components/organisms/Headers/SectionHeader.js
  71. 56 0
      src/components/organisms/Misc/ProfileImageCard.js
  72. 0 0
      src/components/organisms/Pills/FilledPill.js
  73. 0 0
      src/components/organisms/Pills/UnderlinePill.js
  74. 42 0
      src/components/organisms/Sections/BookmarkSection.js
  75. 16 2
      src/components/organisms/Sections/CategorySection.js
  76. 0 0
      src/components/organisms/Sections/CommentSection.js
  77. 24 0
      src/components/organisms/Sections/LoadingScreen.js
  78. 0 0
      src/components/organisms/Sections/NoBookmarkSection.js
  79. 0 0
      src/components/organisms/Sections/NotificationSection.js
  80. 0 0
      src/components/organisms/Sections/RecentPostsSection.js
  81. 5 5
      src/components/organisms/Sections/TrendingSection.js
  82. 0 0
      src/database/models/RecentNews.js
  83. 0 0
      src/database/schema.js
  84. 3 7
      src/navigation/BookmarkNavigator.js
  85. 0 0
      src/navigation/HelpPageNavigator.js
  86. 25 5
      src/navigation/HomePageNavigator.js
  87. 14 13
      src/navigation/LandingPageNavigator.js
  88. 0 0
      src/navigation/ProfileNavigator.js
  89. 0 0
      src/navigation/SearchPageNavigator.js
  90. 0 0
      src/navigation/SettingsPageNavigator.js
  91. 0 0
      src/screens/AboutUsPage.js
  92. 27 0
      src/screens/BookmarkPage.js
  93. 0 0
      src/screens/CategoryPage.js
  94. 0 0
      src/screens/ContactUsPage.js
  95. 0 0
      src/screens/EditProfilePage.js
  96. 0 0
      src/screens/FAQPage.js
  97. 0 0
      src/screens/HelpPage.js
  98. 3 10
      src/screens/LandingPage.js
  99. 0 0
      src/screens/LoginPage.js
  100. 288 0
      src/screens/NewsDetailPage.js

+ 3 - 3
App.js

@@ -18,10 +18,10 @@ import {
   useColorScheme,
   View,
 } from 'react-native';
-import LoginPage from './screens/LoginPage';
-import HomePageNavigator from './navigation/HomePageNavigator';
+import LoginPage from './src/screens/LoginPage';
+import HomePageNavigator from './src/navigation/HomePageNavigator';
 import { GestureHandlerRootView } from 'react-native-gesture-handler';
-import UnsignedLandingPage from './screens/UnsignedLandingPage';
+import UnsignedLandingPage from './src/screens/UnsignedLandingPage';
 
 const AppStack = createNativeStackNavigator();
 

+ 7 - 0
DEV_NOTES.md

@@ -0,0 +1,7 @@
+## 22th Aug 2023
+
+1. Moved all custom folders to a `src` folder.
+2. Created a `theme` folder to contain all global styles.
+3. Created a `api` folder to contain all server data fetching functionality
+4. Fixed the Humanize Timestamp Function
+5. 

+ 0 - 12
assets/images/images.js

@@ -1,12 +0,0 @@
-const images = {
-    newscoutDark: require("../images/newscout_logo_dark.png"),
-    newscoutLight: require("./newscout_logo_light.png"),
-    newscoutTextLight: require("../images/newscout_text_light.png"),
-    getStarted: require("../images/get_started.png"),
-    imageCard: require("../images/hp_newscard.png"),
-    horizontalCard: require("../images/pubg.png"),
-    verticalCard: require("../images/VertCard.png"),
-    noBookmark: require("../images/no_bookmark.png")
-}
-
-export default images;

+ 72 - 0
package-lock.json

@@ -13,6 +13,7 @@
         "@react-navigation/drawer": "^6.6.3",
         "@react-navigation/native": "^6.1.6",
         "@react-navigation/native-stack": "^6.9.12",
+        "axios": "^1.5.0",
         "react": "18.2.0",
         "react-native": "^0.72.1",
         "react-native-gesture-handler": "^2.12.0",
@@ -4465,6 +4466,11 @@
       "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
       "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
     },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+    },
     "node_modules/at-least-node": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
@@ -4485,6 +4491,16 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/axios": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.0.tgz",
+      "integrity": "sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==",
+      "dependencies": {
+        "follow-redirects": "^1.15.0",
+        "form-data": "^4.0.0",
+        "proxy-from-env": "^1.1.0"
+      }
+    },
     "node_modules/babel-core": {
       "version": "7.0.0-bridge.0",
       "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz",
@@ -5015,6 +5031,17 @@
       "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz",
       "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g=="
     },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
     "node_modules/command-exists": {
       "version": "1.2.9",
       "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz",
@@ -5221,6 +5248,14 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
     "node_modules/denodeify": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz",
@@ -6362,6 +6397,25 @@
         "node": ">=0.4.0"
       }
     },
+    "node_modules/follow-redirects": {
+      "version": "1.15.2",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
+      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://github.com/sponsors/RubenVerborgh"
+        }
+      ],
+      "engines": {
+        "node": ">=4.0"
+      },
+      "peerDependenciesMeta": {
+        "debug": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/for-each": {
       "version": "0.3.3",
       "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
@@ -6371,6 +6425,19 @@
         "is-callable": "^1.1.3"
       }
     },
+    "node_modules/form-data": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+      "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/fresh": {
       "version": "0.5.2",
       "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
@@ -10498,6 +10565,11 @@
         "react-is": "^16.13.1"
       }
     },
+    "node_modules/proxy-from-env": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+    },
     "node_modules/punycode": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",

+ 1 - 0
package.json

@@ -15,6 +15,7 @@
     "@react-navigation/drawer": "^6.6.3",
     "@react-navigation/native": "^6.1.6",
     "@react-navigation/native-stack": "^6.9.12",
+    "axios": "^1.5.0",
     "react": "18.2.0",
     "react-native": "^0.72.1",
     "react-native-gesture-handler": "^2.12.0",

+ 0 - 49
screens/BookmarkPage.js

@@ -1,49 +0,0 @@
-import { FlatList, StyleSheet, Text, View } from 'react-native'
-import React from 'react'
-import NoBookmarkSection from '../components/organisms/Sections/NoBookmarkSection'
-import HorizontalNewsCardVariant from '../components/organisms/Cards/HorizontalNewsCardVariant';
-import fonts from '../theme/fonts';
-import SearchTextInput from '../components/molecules/SearchTextInput';
-
-const BookmarkPage = ({navigation}) => {
-  const data = ["1", "2", "3", "4", "5"];
-  //const data = []
-
-  const detailPageNavigation = () => {
-    navigation.navigate("Landing",{'screen':'NewsDetailPage'})
-  }
-
-  return (
-    <View>
-      {data.length <= 0 ? <NoBookmarkSection /> :
-
-        <View style={styles.container}>
-          <View >
-            <SearchTextInput/>
-            <FlatList
-            showsVerticalScrollIndicator={false}
-              ItemSeparatorComponent={() => <View style={{height: fonts.getSize(8)}}></View>}
-              // ListFooterComponent={() => <View style={{height: fonts.getSize(16)}}></View>}
-              ListHeaderComponent={() => <View style={{height: fonts.getSize(16)}}></View>}
-              data={data}
-              renderItem={(item) => <HorizontalNewsCardVariant onPress={detailPageNavigation}/>}
-              keyExtractor={item => data.indexOf(item)}
-
-            />
-          </View>
-
-        </View>
-      }
-
-    </View>
-  )
-}
-
-export default BookmarkPage
-
-const styles = StyleSheet.create({
-  container: {
-    paddingHorizontal: fonts.getSize(16),
-    
-  }
-})

+ 0 - 237
screens/NewsDetailPage.js

@@ -1,237 +0,0 @@
-import { StyleSheet, Text, View, TouchableWithoutFeedback, ScrollView, Image } from 'react-native'
-import React, { useRef, useCallback, useMemo } from 'react'
-import Header from '../components/atoms/Header'
-import FeatherIcon from 'react-native-vector-icons/Feather'
-import MaterialIcon from 'react-native-vector-icons/MaterialIcons'
-import colors from '../theme/colors'
-import fonts from '../theme/fonts'
-import images from '../assets/images/images'
-import IonIcon from 'react-native-vector-icons/Ionicons'
-import BookmarkButton from '../components/organisms/Buttons/BookmarkButton'
-import ShareButton from '../components/organisms/Buttons/ShareButton'
-import {
-    BottomSheetModal,
-    BottomSheetModalProvider,
-    BottomSheetView,
-    BottomSheetScrollView
-} from '@gorhom/bottom-sheet';
-import ButtonWrapper from '../components/atoms/ButtonWrapper'
-import CommentCard from '../components/organisms/Cards/CommentCard'
-
-
-
-
-const NewsDetailPage = ({ navigation, headline, tagline, timestamp, author, newsText, image, comments }) => {
-
-    const commentsData = [{},{},{},{},{}]
-    const bottomSheetModalRef = useRef('');
-
-    // Variables
-    const snapPoints = useMemo(() => ['70%', '100%'], []);
-
-
-    // Callbacks
-    const handlePresentModalPress = useCallback(() => {
-        bottomSheetModalRef.current?.present();
-    }, []);
-
-    const handleCloseModalPress = () => bottomSheetModalRef.current.close();
-
-    const handleSheetChanges = useCallback((index) => {
-        console.log('handleSheetChanges', index);
-    }, []);
-
-
-    return (
-
-        <BottomSheetModalProvider>
-            <ScrollView>
-                <View style={styles.container}>
-                    <Header>
-                        <TouchableWithoutFeedback onPress={() => { navigation.goBack() }}>
-                            <FeatherIcon name={'chevron-left'} size={24} color={colors.black} />
-                        </TouchableWithoutFeedback>
-                        <TouchableWithoutFeedback onPress={() => navigation.toggleDrawer()}>
-                            <MaterialIcon name='list' color={colors.topColor} size={30} />
-                        </TouchableWithoutFeedback>
-                    </Header>
-                    <View style={styles.newsContainer}>
-                        <Text style={styles.headline}>
-                            {headline ?? "ICICI Securities sees over 49% upside potential on this chemical stock"}
-                        </Text>
-                        <Text style={styles.tagline}>
-                            {tagline ?? "The reason behind theirent is that iPhone users have been The reason behind theirent is that iPhone.."}
-                        </Text>
-                        <View style={styles.descriptors}>
-                            <Text style={styles.descriptorText}>{timestamp ?? "15 min ago"}</Text>
-                            <Text style={styles.descriptorText}>{author ?? "By Lucy Hiddleston"}</Text>
-                        </View>
-                        {/* Test Card */}
-                        <View style={styles.imagesContainer}>
-                            <Image source={image ?? images.verticalCard} style={styles.image} />
-                        </View>
-                        <View style={styles.utilButtons}>
-                            <TouchableWithoutFeedback onPress={handlePresentModalPress}>
-                                <View style={styles.commentSection}>
-                                    <IonIcon name="chatbubble-outline" size={fonts.getSize(20)} color={colors.topColor} />
-                                    <Text style={styles.commentText}>{comments ?? 123} COMMENTS</Text>
-                                </View>
-                            </TouchableWithoutFeedback>
-                            <View style={{ flexDirection: 'row' }}>
-                                <BookmarkButton
-                                    buttonStyle={styles.buttonStyle}
-                                    iconSize={20}
-                                    onPress={true}
-                                />
-                                <ShareButton
-                                    buttonStyle={styles.buttonStyle}
-                                    iconSize={20}
-                                    onPress={true}
-                                />
-                            </View>
-                        </View>
-                        <Text style={styles.newsText}>
-                            {newsText ?? "Samsung had a pretty quiet Mobile World Congress event, but it did tell us we’d learn more about its upcoming Google-approved smartwatch at its next Unpacked event. Unfortunately, the company didn’t tell us when exactly that would be, but a new report from Korean publication DigitalDaily News (via 9to5Google) claims the next Unpacked will take place on August 11, at 10 AM ET."}
-                        </Text>
-                        <TouchableWithoutFeedback onPress={true}>
-                            <Text style={styles.backToTopText}>Back to Top</Text>
-                        </TouchableWithoutFeedback>
-                    </View>
-
-                    <>
-                        <BottomSheetModal
-                            ref={bottomSheetModalRef}
-                            index={1}
-                            snapPoints={snapPoints}
-                            onChange={handleSheetChanges}
-                        >
-                            <BottomSheetScrollView>
-                                <BottomSheetView style={{ paddingHorizontal: fonts.getSize(24) }}>
-                                    <BottomSheetView style={styles.commentInputContainer}>
-                                        <Text style={{ fontFamily: fonts.type.semibold, color: colors.black, fontSize: fonts.getSize(16) }}>
-                                            Comments
-                                        </Text>
-                                        <ButtonWrapper onPress={handleCloseModalPress}>
-                                            <IonIcon name='close-sharp' size={fonts.getSize(20)} color={colors.black} />
-                                        </ButtonWrapper>
-                                    </BottomSheetView>
-                                    <View style={styles.commentInput}>
-                                        <Image source={images.imageCard} style={[styles.profileImage]} />
-                                        <Text >Comment Text Input</Text>
-                                    </View>
-                                    <>
-                                        <Text style={{fontFamily:fonts.type.medium, color: colors.black,paddingBottom: fonts.getSize(8)}}>View all Comments(04)</Text>
-                                    </>
-                                    <BottomSheetView style={{gap:fonts.getSize(16)}}>
-                                       {commentsData.map(() => <CommentCard />)}
-                                    </BottomSheetView>
-
-                                </BottomSheetView>
-                            </BottomSheetScrollView>
-
-                        </BottomSheetModal>
-                    </>
-                </View>
-            </ScrollView>
-        </BottomSheetModalProvider>
-
-
-
-    )
-}
-
-export default NewsDetailPage
-
-const styles = StyleSheet.create({
-    newsContainer: {
-        paddingHorizontal: fonts.getSize(24)
-    },
-    headline: {
-        fontFamily: fonts.type.semibold,
-        fontSize: fonts.getSize(18),
-        paddingVertical: fonts.getSize(8),
-        color: colors.black,
-
-    },
-    tagline: {
-        fontFamily: fonts.type.regular,
-        color: colors.gray
-    },
-    descriptors: {
-        flexDirection: 'row',
-        gap: fonts.getSize(16),
-    },
-    descriptorText: {
-        fontFamily: fonts.type.semibold,
-        fontSize: fonts.getSize(10),
-        color: colors.black,
-        paddingTop: fonts.getSize(8),
-        paddingBottom: fonts.getSize(16)
-    },
-    newsText: {
-        color: colors.gray,
-        fontFamily: fonts.type.regular,
-        lineHeight: fonts.getSize(24),
-        paddingVertical: fonts.getSize(4)
-    },
-    backToTopText: {
-        color: colors.topColor,
-        alignSelf: 'center',
-        justifyContent: 'center',
-        paddingVertical: fonts.getSize(16),
-        fontSize: fonts.getSize(16),
-        fontFamily: fonts.type.regular,
-        textDecorationStyle: 'solid',
-        textDecorationLine: 'underline'
-    },
-    imagesContainer: {
-        width: "auto",
-        height: fonts.getSize(196),
-        paddingHorizontal: 0
-    },
-    image: {
-        borderRadius: fonts.getSize(4),
-        width: '100%',
-        height: '100%'
-    },
-    utilButtons: {
-        flexDirection: 'row',
-        justifyContent: 'space-between',
-        paddingVertical: fonts.getSize(4)
-    },
-    buttonStyle: {
-        padding: fonts.getSize(8)
-    },
-    commentSection: {
-        alignItems: 'center',
-        justifyContent: 'center',
-        flexDirection: 'row',
-        gap: fonts.getSize(8),
-        paddingLeft: fonts.getSize(4)
-    },
-    commentText: {
-        fontFamily: fonts.type.regular,
-        color: colors.gray
-    },
-    commentInputContainer: {
-        flexDirection: 'row',
-        justifyContent: 'space-between',
-        alignItems: 'center', 
-        paddingVertical: fonts.getSize(4)
-
-    },
-    profileImage: {
-        height: 42,
-        width: 42,
-        borderRadius: 32,
-        marginRight: fonts.getSize(16)
-
-    },
-    commentInput: {
-        paddingVertical: fonts.getSize(16),
-        alignItems: 'center',
-        justifyContent: 'flex-start',
-        flexDirection: 'row'
-    },
-
-})

+ 11 - 0
src/api/APIHandler.js

@@ -0,0 +1,11 @@
+import axios from 'axios';
+import { CURRENT_URL } from './constants';
+
+const APIHandler = axios.create({
+    baseURL: CURRENT_URL,
+    timeout: 1000,
+    headers: {}
+});
+
+
+export default APIHandler

+ 23 - 0
src/api/article.js

@@ -0,0 +1,23 @@
+import APIHandler from './APIHandler'
+
+/** 
+* Brief description of the function here.
+* @summary If the description is long, write your summary here. Otherwise, feel free to remove this.
+* @param {ParamDataTypeHere} parameterNameHere - Brief description of the parameter here. Note: For other notations of data types, please refer to JSDocs: DataTypes command.
+* @return {ReturnValueDataTypeHere} Brief description of the returning value here.
+*/
+const getArticle = (slug) => {
+    APIHandler.get(`${ARTICLES_URL(slug)}`)
+    .then((response) => {
+        
+        console.log(response.results)
+        console.log(`Article ${slug} has been fetched`)
+        return response.results
+    })
+    .catch((err) => {
+        console.error(err)
+    })
+    .finally(() => {
+        console.log("getArticle has been called")
+    })
+}

+ 9 - 0
src/api/bookmarks.js

@@ -0,0 +1,9 @@
+/** 
+* Brief description of the function here.
+* @summary If the description is long, write your summary here. Otherwise, feel free to remove this.
+* @param {ParamDataTypeHere} parameterNameHere - Brief description of the parameter here. Note: For other notations of data types, please refer to JSDocs: DataTypes command.
+* @return {ReturnValueDataTypeHere} Brief description of the returning value here.
+*/
+const getBookmarks = () => {
+    
+}

+ 18 - 0
src/api/constants.js

@@ -0,0 +1,18 @@
+export const BASE_URL = `http://newscout.in`;
+export const API_VERSION = `api/v1`
+export const DOMAIN = `newscout`
+export const DOMAIN_PARAM = `?domain=${DOMAIN}`
+export const API_TIMEOUT = 1000
+
+export const CURRENT_URL =  `${BASE_URL}/${API_VERSION}`
+
+export const MENUS_URL = `/menus/${DOMAIN_PARAM}`
+export const TRENDING_URL = `/trending/${DOMAIN_PARAM}`
+export const ARTICLE_SEARCH_URL = `/article/search/${DOMAIN_PARAM}`
+export const ARTICLE_SUGGEST_URL = `/suggest/${DOMAIN_PARAM}`
+export const CATEGORY_URL = `/categories/${DOMAIN_PARAM}`
+export const NOTIFICATIONS_URL = `/notification/${DOMAIN_PARAM}`
+export const USER_PROFILE_URL = `/userprofile/${DOMAIN_PARAM}`
+export const BOOKMARK_ARTICLE_URL = `/bookmark-articles/bookmark-news-list/${DOMAIN_PARAM}`
+export const ARTICLES_URL = (slug) =>  `/articles/${slug}/${DOMAIN_PARAM}`
+export const COMMENTS_URL = (articleId) => `/comment/$article_id=${articleId}`

+ 0 - 0
assets/fonts/OFL.txt → src/assets/fonts/OFL.txt


+ 0 - 0
assets/fonts/Poppins-Black.ttf → src/assets/fonts/Poppins-Black.ttf


+ 0 - 0
assets/fonts/Poppins-BlackItalic.ttf → src/assets/fonts/Poppins-BlackItalic.ttf


+ 0 - 0
assets/fonts/Poppins-Bold.ttf → src/assets/fonts/Poppins-Bold.ttf


+ 0 - 0
assets/fonts/Poppins-BoldItalic.ttf → src/assets/fonts/Poppins-BoldItalic.ttf


+ 0 - 0
assets/fonts/Poppins-ExtraBold.ttf → src/assets/fonts/Poppins-ExtraBold.ttf


+ 0 - 0
assets/fonts/Poppins-ExtraBoldItalic.ttf → src/assets/fonts/Poppins-ExtraBoldItalic.ttf


+ 0 - 0
assets/fonts/Poppins-ExtraLight.ttf → src/assets/fonts/Poppins-ExtraLight.ttf


+ 0 - 0
assets/fonts/Poppins-ExtraLightItalic.ttf → src/assets/fonts/Poppins-ExtraLightItalic.ttf


+ 0 - 0
assets/fonts/Poppins-Italic.ttf → src/assets/fonts/Poppins-Italic.ttf


+ 0 - 0
assets/fonts/Poppins-Light.ttf → src/assets/fonts/Poppins-Light.ttf


+ 0 - 0
assets/fonts/Poppins-LightItalic.ttf → src/assets/fonts/Poppins-LightItalic.ttf


+ 0 - 0
assets/fonts/Poppins-Medium.ttf → src/assets/fonts/Poppins-Medium.ttf


+ 0 - 0
assets/fonts/Poppins-MediumItalic.ttf → src/assets/fonts/Poppins-MediumItalic.ttf


+ 0 - 0
assets/fonts/Poppins-Regular.ttf → src/assets/fonts/Poppins-Regular.ttf


+ 0 - 0
assets/fonts/Poppins-SemiBold.ttf → src/assets/fonts/Poppins-SemiBold.ttf


+ 0 - 0
assets/fonts/Poppins-SemiBoldItalic.ttf → src/assets/fonts/Poppins-SemiBoldItalic.ttf


+ 0 - 0
assets/fonts/Poppins-Thin.ttf → src/assets/fonts/Poppins-Thin.ttf


+ 0 - 0
assets/fonts/Poppins-ThinItalic.ttf → src/assets/fonts/Poppins-ThinItalic.ttf


+ 0 - 0
assets/images/VertCard.png → src/assets/images/VertCard.png


+ 0 - 0
assets/images/get_started.png → src/assets/images/get_started.png


+ 0 - 0
assets/images/hp_newscard.png → src/assets/images/hp_newscard.png


+ 12 - 0
src/assets/images/images.js

@@ -0,0 +1,12 @@
+const images = {
+    newscoutDark: require("./newscout_logo_dark.png"),
+    newscoutLight: require("./newscout_logo_light.png"),
+    newscoutTextLight: require("./newscout_text_light.png"),
+    getStarted: require("./get_started.png"),
+    imageCard: require("./hp_newscard.png"),
+    horizontalCard: require("./pubg.png"),
+    verticalCard: require("./VertCard.png"),
+    noBookmark: require("./no_bookmark.png")
+}
+
+export default images;

+ 0 - 0
assets/images/newscout_logo_dark.png → src/assets/images/newscout_logo_dark.png


+ 0 - 0
assets/images/newscout_logo_light.png → src/assets/images/newscout_logo_light.png


+ 0 - 0
assets/images/newscout_text_light.png → src/assets/images/newscout_text_light.png


+ 0 - 0
assets/images/no_bookmark.png → src/assets/images/no_bookmark.png


+ 0 - 0
assets/images/pubg.png → src/assets/images/pubg.png


+ 0 - 0
components/atoms/Button.js → src/components/atoms/Button.js


+ 0 - 0
components/atoms/ButtonWrapper.js → src/components/atoms/ButtonWrapper.js


+ 0 - 0
components/atoms/Card.js → src/components/atoms/Card.js


+ 1 - 1
components/atoms/Header.js → src/components/atoms/Header.js

@@ -25,6 +25,6 @@ const styles = StyleSheet.create({
     justifyContent: 'space-between',
     height: 60,
     maxHeight: 60,
-    backgroundColor: colors.white
+    // backgroundColor: colors.white
   }
 })

+ 0 - 0
components/molecules/FormTextInput.js → src/components/molecules/FormTextInput.js


+ 0 - 0
components/molecules/NewscoutLogo.js → src/components/molecules/NewscoutLogo.js


+ 0 - 0
components/molecules/NewscoutTextLogo.js → src/components/molecules/NewscoutTextLogo.js


+ 0 - 0
components/molecules/SearchTextInput.js → src/components/molecules/SearchTextInput.js


+ 0 - 0
components/molecules/ThemedSwitch.js → src/components/molecules/ThemedSwitch.js


+ 0 - 0
components/organisms/Buttons/BookmarkButton.js → src/components/organisms/Buttons/BookmarkButton.js


+ 0 - 0
components/organisms/Buttons/CircularPrimaryBackButton.js → src/components/organisms/Buttons/CircularPrimaryBackButton.js


+ 43 - 0
src/components/organisms/Buttons/CloseButton.js

@@ -0,0 +1,43 @@
+import { StyleSheet, Text, View } from 'react-native'
+import React from 'react'
+import MaterialIcon from 'react-native-vector-icons/MaterialIcons'
+import colors from '../../../theme/colors'
+import ButtonWrapper from '../../atoms/ButtonWrapper'
+
+const CloseButton = (props) => {
+
+    const {
+        onPress,
+        buttonStyle,
+        iconColor,
+        iconSize
+    } = props
+    
+    let finalIconColor;
+    switch (iconColor) {
+        case "primary":
+            finalIconColor = colors.primaryColor
+            break;
+        case "secondary":
+            finalIconColor = colors.secondaryColor
+            break
+        default:
+            finalIconColor = colors.black
+            break;
+    }
+
+  return (
+    <ButtonWrapper onPress={onPress} buttonStyle={buttonStyle}>
+      <MaterialIcon name='close' color={finalIconColor} size={iconSize ? iconSize : styles.icon.fontSize} />
+    </ButtonWrapper>
+  )
+}
+
+export default CloseButton
+
+const styles = StyleSheet.create({
+    icon:{
+        fontSize: 20,
+        color: colors.primaryColor
+    }
+})

+ 0 - 0
components/organisms/Buttons/EditButton.js → src/components/organisms/Buttons/EditButton.js


+ 0 - 0
components/organisms/Buttons/PrimaryButton.js → src/components/organisms/Buttons/PrimaryButton.js


+ 0 - 0
components/organisms/Buttons/PrimaryOutlineButton.js → src/components/organisms/Buttons/PrimaryOutlineButton.js


+ 0 - 0
components/organisms/Buttons/SecondaryButton.js → src/components/organisms/Buttons/SecondaryButton.js


+ 0 - 0
components/organisms/Buttons/SecondaryOutlineButton.js → src/components/organisms/Buttons/SecondaryOutlineButton.js


+ 0 - 0
components/organisms/Buttons/SettingsButton.js → src/components/organisms/Buttons/SettingsButton.js


+ 0 - 0
components/organisms/Buttons/ShareButton.js → src/components/organisms/Buttons/ShareButton.js


+ 0 - 0
components/organisms/Buttons/ThemedTextButton.js → src/components/organisms/Buttons/ThemedTextButton.js


+ 0 - 0
components/organisms/Cards/CategoryCard.js → src/components/organisms/Cards/CategoryCard.js


+ 0 - 0
components/organisms/Cards/CommentCard.js → src/components/organisms/Cards/CommentCard.js


+ 2 - 2
components/organisms/Cards/HorizontalNewsCard.js → src/components/organisms/Cards/HorizontalNewsCard.js

@@ -13,7 +13,7 @@ const HorizontalNewsCard = ({ style, headline, tagline, category, timestamp, ima
     return (
         <TouchableWithoutFeedback onPress={onPress}>
             <View style={[styles.cardContainer, style]}>
-                <>
+                <View>
                     <View style={styles.textContainer}>
                         <View>
                             <Text style={styles.headline}> {headline ?? "Battlegrounds Mobile India iOS release date"}</Text>
@@ -27,7 +27,7 @@ const HorizontalNewsCard = ({ style, headline, tagline, category, timestamp, ima
                         </View>
 
                     </View>
-                </>
+                </View>
                 <View>
                     <View style={styles.descriptors}>
                         <Text style={styles.categoryDescriptor}>{category ?? "Sports"}</Text>

+ 37 - 35
components/organisms/Cards/HorizontalNewsCardVariant.js → src/components/organisms/Cards/HorizontalNewsCardVariant.js

@@ -1,4 +1,4 @@
-import { StyleSheet, Text, View, TouchableWithoutFeedback, Image } from 'react-native'
+import { StyleSheet, Text, View, TouchableOpacity, TouchableWithoutFeedback, Image } from 'react-native'
 import React from 'react'
 import metrics from '../../../theme/metrics'
 import fonts from '../../../theme/fonts'
@@ -11,32 +11,34 @@ import { getTimestamp } from '../../../utils/Constants/functions'
 
 const HorizontalNewsCardVariant = ({ headline, image, category, timestamp, tagline, onPress }) => {
   return (
-    <View style={styles.cardContainer}>
-      <View style={styles.topSection}>
-        <View style={styles.textContainer}>
-          <TouchableWithoutFeedback onPress={onPress}>
-            <Text style={styles.headline}>{headline ?? "Battlegrounds Mobile India iOS release date"}</Text>
-          </TouchableWithoutFeedback>
-        </View>
-        <View style={styles.imageContainer}>
-          <View style={styles.imageSub}>
-            <Image source={image ?? images.horizontalCard} style={styles.image} />
+    <TouchableOpacity onPress={onPress}>
+      <View style={styles.cardContainer}>
+        <View style={styles.topSection}>
+          <View style={styles.textContainer}>
+            <TouchableWithoutFeedback onPress={onPress}>
+              <Text style={styles.headline}>{headline ?? "Battlegrounds Mobile India iOS release date"}</Text>
+            </TouchableWithoutFeedback>
+          </View>
+          <View style={styles.imageContainer}>
+            <View style={styles.imageSub}>
+              <Image source={image ?? images.horizontalCard} style={styles.image} />
+            </View>
           </View>
         </View>
-      </View>
-      <View style={styles.middleSection}>
-        <View style={styles.descriptors}>
-          <Text style={styles.timeDescriptor}>{getTimestamp(timestamp) ?? "27 mins ago"}</Text>
+        <View style={styles.middleSection}>
+          <View style={styles.descriptors}>
+            <Text style={styles.timeDescriptor}>{getTimestamp(timestamp) ?? "27 mins ago"}</Text>
+          </View>
+          <View style={styles.utilButtons}>
+            <BookmarkButton size={20} onPress={true} />
+            <ShareButton size={20} onPress={true} />
+          </View>
         </View>
-        <View style={styles.utilButtons}>
-          <BookmarkButton size={20} onPress={true} />
-          <ShareButton size={20} onPress={true} />
+        <View style={styles.bottomSection}>
+          <Text style={styles.tagline}>{tagline ?? "government is the people, for the people, by the people but the people are retarded "}</Text>
         </View>
       </View>
-      <View style={styles.bottomSection}>
-      <Text style={styles.tagline}>{tagline ?? "government is the people, for the people, by the people but the people are retarded "}</Text>
-      </View>
-    </View>
+    </TouchableOpacity>
   )
 }
 
@@ -54,20 +56,20 @@ const styles = StyleSheet.create({
   },
   topSection: {
 
-    height: "55%",
+    height: "65%",
     flexDirection: 'row',
     width: '100%',
     maxWidth: '100%',
     justifyContent: 'space-between'
 
   },
-  middleSection:{
-    flexDirection:'row',
-   
-    justifyContent:'space-between'
+  middleSection: {
+    flexDirection: 'row',
+
+    justifyContent: 'space-between'
   },
   bottomSection: {
-    
+
   },
   imageContainer: {
     width: "35%",
@@ -77,23 +79,23 @@ const styles = StyleSheet.create({
     width: "60%",
     height: '100%',
 
-    justifyContent: 'center',
+    // justifyContent: 'center',
     gap: fonts.getSize(12),
-    marginRight:"5%"
+    marginRight: "5%"
   },
   headline: {
     fontFamily: fonts.type.semibold,
-    fontSize: fonts.getSize(18),
+    fontSize: fonts.getSize(16),
     color: colors.black,
 
   },
   tagline: {
     fontSize: fonts.getSize(12),
     fontFamily: fonts.type.regular,
-    overflow:'hidden'
+    overflow: 'hidden'
   },
   descriptors: {
-    justifyContent:'center'
+    justifyContent: 'center'
   },
   categoryDescriptor: {
     fontFamily: fonts.type.light
@@ -113,8 +115,8 @@ const styles = StyleSheet.create({
   utilButtons: {
     flexDirection: 'row',
     padding: fonts.getSize(8),
-    width:64,
-    justifyContent:'space-between'
+    width: 64,
+    justifyContent: 'space-between'
     //  padding:0
     // alignItems: 'flex-start',
     // justifyContent: 'flex-end',

+ 0 - 0
components/organisms/Cards/ImageBGCard.js → src/components/organisms/Cards/ImageBGCard.js


+ 0 - 0
components/organisms/Cards/NotificationCard.js → src/components/organisms/Cards/NotificationCard.js


+ 3 - 3
components/organisms/Cards/VerticalNewsCard.js → src/components/organisms/Cards/VerticalNewsCard.js

@@ -54,12 +54,12 @@ const styles = StyleSheet.create({
     headline: {
         fontFamily: fonts.type.medium,
         textDecorationLine: 'underline',
-        fontSize: fonts.getSize(16),
+        fontSize: 14,
         color: colors.black,
-        paddingBottom: fonts.getSize(8)
+        paddingBottom: 8
     },
     tagline: {
-        fontSize: fonts.getSize(12),
+        fontSize: 12,
         fontFamily: fonts.type.regular,
         maxHeight: '40%',
         overflow: 'hidden',

+ 0 - 0
components/organisms/Headers/NewscoutCenteredTitleHeader.js → src/components/organisms/Headers/NewscoutCenteredTitleHeader.js


+ 0 - 0
components/organisms/Headers/NewscoutHomeHeader.js → src/components/organisms/Headers/NewscoutHomeHeader.js


+ 0 - 0
components/organisms/Headers/NewscoutTitleHeader.js → src/components/organisms/Headers/NewscoutTitleHeader.js


+ 0 - 0
components/organisms/Headers/SectionHeader.js → src/components/organisms/Headers/SectionHeader.js


+ 56 - 0
src/components/organisms/Misc/ProfileImageCard.js

@@ -0,0 +1,56 @@
+import { StyleSheet, Text, View, ImageBackground, TouchableOpacity } from 'react-native'
+import React from 'react'
+import images from '../../../assets/images/images'
+import EditButton from '../Buttons/EditButton';
+import colors from '../../../theme/colors';
+
+const PROFILE_SIZE = 128;
+const EDIT_ICON_SIZE = 14
+
+const ProfileImageCard = (props) => {
+    const {
+        source,
+        onEdit
+    } = props
+
+    return (
+        <View style={styles.profileImageContainer}>
+            <ImageBackground source={source ?? images.imageCard} style={styles.profileImageView} imageStyle={styles.profileImage}>
+                <TouchableOpacity onPress={true}>
+                    <View style={styles.editIcon}>
+                        <EditButton iconSize={EDIT_ICON_SIZE} iconColor={colors.white} onPress={onEdit}/>
+                    </View>
+                </TouchableOpacity>
+            </ImageBackground>
+        </View>
+    )
+}
+
+export default ProfileImageCard
+
+const styles = StyleSheet.create({
+    profileImageContainer: {
+        paddingVertical: 16,
+        alignItems: 'center',
+    },
+    profileImage: {
+        height: PROFILE_SIZE,
+        width: PROFILE_SIZE,
+        borderRadius: PROFILE_SIZE
+    },
+    profileImageView: {
+        height: PROFILE_SIZE,
+        width: PROFILE_SIZE,
+        borderRadius: PROFILE_SIZE,
+        alignItems: 'flex-end',
+        justifyContent: 'flex-end',
+        padding: 8
+    },
+    editIcon:{
+        alignSelf: 'flex-end',
+        justifyContent: 'flex-end',
+        backgroundColor: colors.primaryColor,
+        padding: 4,
+        borderRadius: 32
+    }
+})

+ 0 - 0
components/organisms/Pills/FilledPill.js → src/components/organisms/Pills/FilledPill.js


+ 0 - 0
components/organisms/Pills/UnderlinePill.js → src/components/organisms/Pills/UnderlinePill.js


+ 42 - 0
src/components/organisms/Sections/BookmarkSection.js

@@ -0,0 +1,42 @@
+import { StyleSheet, Text, View, FlatList } from 'react-native'
+import React from 'react'
+import SearchTextInput from '../../molecules/SearchTextInput'
+import { } from 'react-native-gesture-handler'
+import fonts from '../../../theme/fonts'
+import HorizontalNewsCardVariant from '../Cards/HorizontalNewsCardVariant'
+
+const BookmarkSection = ({ navigation, data }) => {
+
+    //const data = []
+    const detailPageNavigation = (slug, id) => {
+        navigation.navigate("Landing", { 'screen': 'NewsDetailPage', params: {articleId: id, articleSlug: slug} })
+    }
+
+    return (
+        <View style={styles.container}>
+            <View >
+                <SearchTextInput />
+                <FlatList
+                    showsVerticalScrollIndicator={false}
+                    ItemSeparatorComponent={() => <View style={{ height: fonts.getSize(8) }}></View>}
+                    // ListFooterComponent={() => <View style={{height: fonts.getSize(16)}}></View>}
+                    ListHeaderComponent={() => <View style={{ height: fonts.getSize(16) }}></View>}
+                    data={data}
+                    renderItem={(item) => <HorizontalNewsCardVariant onPress={() => detailPageNavigation("fox-news-hosts-own-words-come-back-to-haunt-trump-in-brutal-msnbc-supercut-2057347", "2057175")} />}
+                    keyExtractor={item => data.indexOf(item)}
+
+                />
+            </View>
+
+        </View>
+    )
+}
+
+export default BookmarkSection
+
+const styles = StyleSheet.create({
+    container: {
+        paddingHorizontal: fonts.getSize(16),
+    }
+
+})

+ 16 - 2
components/organisms/Sections/CategorySection.js → src/components/organisms/Sections/CategorySection.js

@@ -11,10 +11,15 @@ import {
   PAGINATE_BY,
 } from '../../../utils/Constants/constants';
 import {useConstructor} from '../../../utils/Constants/functions';
+import { useNavigation } from '@react-navigation/native';
+import metrics from '../../../theme/metrics';
+import { WINDOW_WIDTH } from '@gorhom/bottom-sheet';
+
 
 // * API Handling
 
-const CategorySection = () => {
+const CategorySection = ({navigation}) => {
+  
   const [news, setNews] = React.useState({all: []});
   const updateNewsByCategories = (key, value) => {
     setNews(prevObject => ({
@@ -70,6 +75,7 @@ const CategorySection = () => {
             timestamp: article.published_on,
             tagline: 'Bruh Momento Oi Lorem Ipsum di rubi rabbi',
             id: article.id,
+            slug: article.slug
           }));
         updateNewsByCategories(category, finalNewsData);
         // categories.forEach((category) => {setNews((prev) => ({...prev,[category]:json.body.results}))})
@@ -79,6 +85,11 @@ const CategorySection = () => {
       .finally(() => console.log('Fetch Category News Executed'));
   };
 
+  const detailPageNavigation = (slug, id) => {
+    navigation.push('NewsDetailPage',{articleId: id, articleSlug: slug})
+}
+
+
   useConstructor(() => {
     const cat_data = fetchCategories();
     //console.log(`construct ${categories}`)
@@ -138,6 +149,7 @@ const CategorySection = () => {
                 image={item.image}
                 timestamp={item.timestamp}
                 tagline={item.tagline}
+                onPress={() => detailPageNavigation(item.slug,item.id)}
               />
             ))
           ) : (
@@ -196,6 +208,8 @@ const styles = StyleSheet.create({
   categoriesNewsContainer: {
     paddingHorizontal: fonts.getSize(16),
     paddingTop: fonts.getSize(10),
-    gap: 8,
+  
+    gap: 4,
+  
   },
 });

+ 0 - 0
components/organisms/Sections/CommentSection.js → src/components/organisms/Sections/CommentSection.js


+ 24 - 0
src/components/organisms/Sections/LoadingScreen.js

@@ -0,0 +1,24 @@
+import { StyleSheet, Text, View } from 'react-native'
+import React from 'react'
+import { ActivityIndicator } from 'react-native-paper'
+import colors from '../../../theme/colors'
+
+const LoadingScreen = () => {
+
+  return (
+    <View style={styles.container}>
+      <ActivityIndicator animating color={colors.primaryColor} size="large"/>
+    </View>
+  )
+}
+
+export default LoadingScreen
+
+const styles = StyleSheet.create({
+    container:{
+        height: '100%',
+        width:"100%",
+        justifyContent: 'center',
+        alignItems: 'center'
+    }
+})

+ 0 - 0
components/organisms/Sections/NoBookmarkSection.js → src/components/organisms/Sections/NoBookmarkSection.js


+ 0 - 0
components/organisms/Sections/NotificationSection.js → src/components/organisms/Sections/NotificationSection.js


+ 0 - 0
components/organisms/Sections/RecentPostsSection.js → src/components/organisms/Sections/RecentPostsSection.js


+ 5 - 5
components/organisms/Sections/RecentNewsSection.js → src/components/organisms/Sections/TrendingSection.js

@@ -27,7 +27,7 @@ const ITEM_HEIGHT = Math.round(ITEM_WIDTH * 3 / 4);
 // }))(ImageBGCard);
 
 
-const RecentNewsSection = () => {
+const TrendingSection = () => {
 
   const [currentCardIndex, setCurrentCardIndex] = React.useState(0)
   const updateCurrentIndex = (index) => {
@@ -85,7 +85,7 @@ const RecentNewsSection = () => {
           style={styles.recentCardContainer}
           autoPlay={true}
           data={posts}
-          scrollAnimationDuration={1000}
+          scrollAnimationDuration={2000}
           mode="parallax"
           modeConfig={{
             parallaxScrollingScale: 1,
@@ -113,7 +113,7 @@ const RecentNewsSection = () => {
   )
 }
 
-export default RecentNewsSection
+export default TrendingSection
 
 const styles = StyleSheet.create({
   recentHeader: {
@@ -140,11 +140,11 @@ const styles = StyleSheet.create({
     width: metrics.screenWidth
   },
   paginationContainer:{
-    justifyContent:'flex-end',
+    justifyContent:'center',
     alignItems:'center',
     paddingHorizontal: 16,
     paddingTop:8,
-    paddingBottom:4,
+    paddingBottom:8,
     flexDirection:'row',
     gap:2}
 })

+ 0 - 0
database/models/RecentNews.js → src/database/models/RecentNews.js


+ 0 - 0
database/schema.js → src/database/schema.js


+ 3 - 7
navigation/BookmarkNavigator.js → src/navigation/BookmarkNavigator.js

@@ -17,18 +17,14 @@ const BookmarkNavigator = ({ route, navigation }) => {
         >
             <Stack.Screen
                 name="BookmarkLanding"
-                options={(navigation) => ({
+                options={({navigation}) => ({
                     header: () => <NewscoutTitleHeader title={"My Bookmarks"}>
-                        <TouchableWithoutFeedback onPress={() => {navigation.navigate('Details')}}>
+                        <TouchableWithoutFeedback onPress={() => {navigation.toggleDrawer()}}>
                             <OctiIcon name='three-bars' size={24} color={colors.topColor} />
                         </TouchableWithoutFeedback>
                     </NewscoutTitleHeader>
                 })}
-                component={BookmarkPage} />
-            
-            {/* <Stack.Screen name="Notifications" component={Notifications} />
-        <Stack.Screen name="Profile" component={Profile} />
-        <Stack.Screen name="Settings" component={Settings} /> */}
+                component={(props) => <BookmarkPage {...props}/>} />
         </Stack.Navigator>
     )
 }

+ 0 - 0
navigation/HelpPageNavigator.js → src/navigation/HelpPageNavigator.js


+ 25 - 5
navigation/HomePageNavigator.js → src/navigation/HomePageNavigator.js

@@ -4,15 +4,35 @@ import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"
 import IonIcon from 'react-native-vector-icons/dist/Ionicons';
 import colors from '../theme/colors';
 import fonts from '../theme/fonts';
-import NewscoutTitleHeader from '../components/organisms/Headers/NewscoutTitleHeader';
 import BookmarkNavigator from './BookmarkNavigator';
 import LandingPageNavigator from './LandingPageNavigator';
 import ProfileNavigator from './ProfileNavigator';
+import { createDrawerNavigator } from '@react-navigation/drawer';
+import metrics from '../theme/metrics';
+import SidebarPage from '../screens/SidebarPage';
+
 
 const Tab = createBottomTabNavigator();
+const Drawer = createDrawerNavigator();
+
+const HomePageNavigator = ({ route, navigation}) => {
+    const isLargeScreen = metrics.screenWidth >= 768;
+    return (
+        <Drawer.Navigator
+            initialRouteName="LandingPage"
+            screenOptions={{
+                drawerType: 'front',
+                drawerStyle: isLargeScreen ? null : { width: '100%' },
+            }}
+            drawerContent={({ navigation }) => <SidebarPage navigation={navigation} />}>
+                <Drawer.Screen name="HomePageTabs" component={HomePageTabsNavigator} options={(navigation) => ({
+                    headerShown: false
+                })}/>
+        </Drawer.Navigator>
+    )
+}
 
-// tabBar={props => <BottomTabBar {...props}/>}
-const HomePageNavigator = ({ route, navigation }) => {
+const HomePageTabsNavigator = ({ route, navigation }) => {
     return (
         <Tab.Navigator
             screenOptions={({ route }) => ({
@@ -53,7 +73,7 @@ const HomePageNavigator = ({ route, navigation }) => {
                 component={LandingPageNavigator}
                 options={(navigation) => ({
                     headerShown: false
-                })}/>
+                })} />
             <Tab.Screen
                 name="Search"
                 component={SearchPage}
@@ -71,7 +91,7 @@ const HomePageNavigator = ({ route, navigation }) => {
                 name="Profile"
                 component={ProfileNavigator}
                 options={() => ({
-                   headerShown: false
+                    headerShown: false
                 })}
             />
         </Tab.Navigator>

+ 14 - 13
navigation/LandingPageNavigator.js → src/navigation/LandingPageNavigator.js

@@ -1,6 +1,6 @@
 import { View, Text, UIManager, Platform } from 'react-native';
 import React from 'react';
-import { createDrawerNavigator } from '@react-navigation/drawer';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
 import LandingPage from '../screens/LandingPage';
 import NewscoutHomeHeader from '../components/organisms/Headers/NewscoutHomeHeader';
 import metrics from '../theme/metrics';
@@ -13,7 +13,7 @@ import NotificationsPage from '../screens/NotificationsPage';
 import CategoryPage from '../screens/CategoryPage';
 
 
-const Drawer = createDrawerNavigator();
+const Stack = createNativeStackNavigator();
 
 const LandingPageNavigator = () => {
     const isLargeScreen = metrics.screenWidth >= 768;
@@ -25,14 +25,15 @@ const LandingPageNavigator = () => {
         UIManager.setLayoutAnimationEnabledExperimental(true);
     }
     return (
-        <Drawer.Navigator
+        <Stack.Navigator
             initialRouteName="LandingPage"
-            screenOptions={{
-                drawerType: 'front',
-                drawerStyle: isLargeScreen ? null : { width: '100%' },
-            }}
-            drawerContent={({ navigation }) => <SidebarPage navigation={navigation} />}>
-            <Drawer.Screen
+            // screenOptions={{
+            //     drawerType: 'front',
+            //     drawerStyle: isLargeScreen ? null : { width: '100%' },
+            // }}
+            // drawerContent={({ navigation }) => <SidebarPage navigation={navigation} />}>
+            >
+            <Stack.Screen
                 name="LandingPage"
                 component={LandingPage}
                 options={({ navigation }) => ({
@@ -51,28 +52,28 @@ const LandingPageNavigator = () => {
                     ),
                 })}
             />
-            <Drawer.Screen
+            <Stack.Screen
                 name="NewsDetailPage"
                 component={NewsDetailPage}
                 options={() =>({
                     headerShown: false
                 })}
             />
-            <Drawer.Screen
+            <Stack.Screen
                 name="Notifications"
                 component={NotificationsPage}
                 options={() =>({
                     headerShown: false
                 })}
             />
-            <Drawer.Screen
+            <Stack.Screen
                 name="CategoryPage"
                 component={CategoryPage}
                 options={() => ({
                     headerShown: false
                 })}
             />
-        </Drawer.Navigator>
+        </Stack.Navigator>
     );
 };
 

+ 0 - 0
navigation/ProfileNavigator.js → src/navigation/ProfileNavigator.js


+ 0 - 0
navigation/SearchPageNavigator.js → src/navigation/SearchPageNavigator.js


+ 0 - 0
navigation/SettingsPageNavigator.js → src/navigation/SettingsPageNavigator.js


+ 0 - 0
screens/AboutUsPage.js → src/screens/AboutUsPage.js


+ 27 - 0
src/screens/BookmarkPage.js

@@ -0,0 +1,27 @@
+import { FlatList, StyleSheet, Text, View } from 'react-native'
+import React, { useEffect } from 'react'
+import NoBookmarkSection from '../components/organisms/Sections/NoBookmarkSection'
+import BookmarkSection from '../components/organisms/Sections/BookmarkSection';
+
+const BookmarkPage = ({navigation}) => {
+  
+  const [bookmarks,setBookmarks] = React.useState([0,0,0,0,0])
+
+
+
+  useEffect(() => {
+  },[])
+
+  return (
+    <View>
+      {bookmarks.length <= 0 ? <NoBookmarkSection /> :
+
+        <BookmarkSection navigation={navigation} data={data}/>
+      }
+
+    </View>
+  )
+}
+
+export default BookmarkPage
+

+ 0 - 0
screens/CategoryPage.js → src/screens/CategoryPage.js


+ 0 - 0
screens/ContactUsPage.js → src/screens/ContactUsPage.js


+ 0 - 0
screens/EditProfilePage.js → src/screens/EditProfilePage.js


+ 0 - 0
screens/FAQPage.js → src/screens/FAQPage.js


+ 0 - 0
screens/HelpPage.js → src/screens/HelpPage.js


+ 3 - 10
screens/LandingPage.js → src/screens/LandingPage.js

@@ -1,17 +1,10 @@
 import { StyleSheet, Text, TouchableOpacity, View, ScrollView } from 'react-native'
 import React, { useState } from 'react'
-import Header from '../components/atoms/Header'
-import { List, ToggleButton } from 'react-native-paper'
-import colors from '../theme/colors'
-import fonts from '../theme/fonts'
-import ImageBGCard from '../components/organisms/Cards/ImageBGCard'
-import FilledPill from '../components/organisms/Pills/FilledPill'
 import CategorySection from '../components/organisms/Sections/CategorySection'
-import images from '../assets/images/images'
-import RecentNewsSection from '../components/organisms/Sections/RecentNewsSection'
+import RecentNewsSection from '../components/organisms/Sections/TrendingSection'
 import RecentPostsSection from '../components/organisms/Sections/RecentPostsSection'
 
-const LandingPage = () => {
+const LandingPage = ({navigation, route}) => {
 
   
   const [categoryPillState, setcategoryPillState] = useState("all")
@@ -26,7 +19,7 @@ const LandingPage = () => {
         {/* 
           Categories
         */}
-        <CategorySection/>
+        <CategorySection navigation={navigation}/>
         {/* 
           Recent Posts
         */}

+ 0 - 0
screens/LoginPage.js → src/screens/LoginPage.js


+ 288 - 0
src/screens/NewsDetailPage.js

@@ -0,0 +1,288 @@
+import { StyleSheet, Text, View, TouchableWithoutFeedback, ScrollView, Image } from 'react-native'
+import React, { useRef, useCallback, useMemo, useEffect } from 'react'
+import Header from '../components/atoms/Header'
+import FeatherIcon from 'react-native-vector-icons/Feather'
+import MaterialIcon from 'react-native-vector-icons/MaterialIcons'
+import colors from '../theme/colors'
+import fonts from '../theme/fonts'
+import images from '../assets/images/images'
+import IonIcon from 'react-native-vector-icons/Ionicons'
+import BookmarkButton from '../components/organisms/Buttons/BookmarkButton'
+import ShareButton from '../components/organisms/Buttons/ShareButton'
+import {
+    BottomSheetModal,
+    BottomSheetModalProvider,
+    BottomSheetView,
+    BottomSheetScrollView
+} from '@gorhom/bottom-sheet';
+import ButtonWrapper from '../components/atoms/ButtonWrapper'
+import CommentCard from '../components/organisms/Cards/CommentCard'
+import { useNavigation } from '@react-navigation/native'
+import { ARTICLES_URL, COMMENTS_URL } from '../api/constants'
+import { getTimestamp, useConstructor } from '../utils/Constants/functions'
+import LoadingScreen from '../components/organisms/Sections/LoadingScreen'
+import APIHandler from '../api/APIHandler'
+
+
+
+const NewsDetailPage = ({ route, navigation, }) => {
+
+    const [articleData, setArticleData] = React.useState(undefined)
+    const [commentsData, setCommentsData] = React.useState(undefined)
+
+    const {articleSlug,articleId} = route.params
+    const getArticle = (slug) => {
+        // APIHandler.get(ARTICLES_URL)
+        console.debug(slug)
+        APIHandler.get(ARTICLES_URL(slug))
+        .then((response) => {
+                let data = response.data.body
+                console.log(data)
+                console.log(`Article ${slug} has been fetched`)
+                console.log
+                setArticleData(data)
+            })
+            .catch((err) => {
+                console.error(err)
+            })
+            .finally(() => {
+                console.log("getArticle has been called")
+            })
+    }
+
+    const getComments = (id) => {
+        APIHandler.get(COMMENTS_URL(id))
+        .then((response) => {
+                let data = response.data.body
+                console.log(`Comments for article ${slug} has been fetched`)
+                setCommentsData(data)
+            })
+            .catch((err) => {
+                console.error(err)
+            })
+            .finally(() => {
+                console.log("getComments has been called")
+            })
+    }
+
+
+    const bottomSheetModalRef = useRef('');
+    const snapPoints = useMemo(() => ['70%', '100%'], []);
+    const handlePresentModalPress = useCallback(() => {
+        bottomSheetModalRef.current?.present();
+    }, []);
+
+    const handleCloseModalPress = () => bottomSheetModalRef.current.close();
+
+    const handleSheetChanges = useCallback((index) => {
+        console.log('handleSheetChanges', index);
+    }, []);
+
+    useEffect(() => {
+        getArticle(articleSlug);
+        // getComments(articleId)
+        //console.log(`construct ${categories}`)
+        // for (let category in cat_data) {
+        //     updateNewsByCategories(category,fetchNews(category))
+
+        // }
+    },[]);
+
+    return (
+        <View>
+            {/* {Object.keys(articleData).length === 0 ? <LoadingScreen /> : */}
+            {articleData === undefined ? <LoadingScreen /> :
+                <BottomSheetModalProvider>
+                    <ScrollView>
+                        <View style={styles.container}>
+                            <Header>
+                                <TouchableWithoutFeedback onPress={() => { navigation.goBack() }}>
+                                    <FeatherIcon name={'chevron-left'} size={24} color={colors.black} />
+                                </TouchableWithoutFeedback>
+                                <TouchableWithoutFeedback onPress={() => navigation.toggleDrawer()}>
+                                    <MaterialIcon name='list' color={colors.topColor} size={30} />
+                                </TouchableWithoutFeedback>
+                            </Header>
+                            <View style={styles.newsContainer}>
+                                <Text style={styles.headline}>
+                                    {articleData.article.title ?? "ICICI Securities sees over 49% upside potential on this chemical stock"}
+                                </Text>
+                                {/* <Text style={styles.tagline}>
+                                    {articleData.article.tagline ?? "The reason behind theirent is that iPhone users have been The reason behind theirent is that iPhone.."}
+                                </Text> */}
+                                <View style={styles.descriptors}>
+                                    <Text style={styles.descriptorText}>{getTimestamp(articleData.article.published_on  ) ?? "15 min ago"}</Text>
+                                    <Text style={styles.descriptorText}>{articleData.article.author ?? "By Lucy Hiddleston"}</Text>
+                                </View>
+                                {/* Test Card */}
+                                <View style={styles.imagesContainer}>
+                                    <Image source={{uri: articleData.article.cover_image} ?? images.verticalCard} style={styles.image} />
+                                </View>
+                                <View style={styles.utilButtons}>
+                                    <TouchableWithoutFeedback onPress={handlePresentModalPress}>
+                                        <View style={styles.commentSection}>
+                                            <IonIcon name="chatbubble-outline" size={fonts.getSize(20)} color={colors.topColor} />
+                                            <Text style={styles.commentText}>{123 ?? 123} COMMENTS</Text>
+                                        </View>
+                                    </TouchableWithoutFeedback>
+                                    <View style={{ flexDirection: 'row' }}>
+                                        <BookmarkButton
+                                            buttonStyle={styles.buttonStyle}
+                                            iconSize={20}
+                                            onPress={true}
+                                        />
+                                        <ShareButton
+                                            buttonStyle={styles.buttonStyle}
+                                            iconSize={20}
+                                            onPress={true}
+                                        />
+                                    </View>
+                                </View>
+                                <Text style={styles.newsText}>
+                                    {articleData.article.blurb ?? "Samsung had a pretty quiet Mobile World Congress event, but it did tell us we’d learn more about its upcoming Google-approved smartwatch at its next Unpacked event. Unfortunately, the company didn’t tell us when exactly that would be, but a new report from Korean publication DigitalDaily News (via 9to5Google) claims the next Unpacked will take place on August 11, at 10 AM ET."}
+                                </Text>
+                                <TouchableWithoutFeedback onPress={true}>
+                                    <Text style={styles.backToTopText}>Back to Top</Text>
+                                </TouchableWithoutFeedback>
+                            </View>
+                            <>
+                                <BottomSheetModal
+                                    ref={bottomSheetModalRef}
+                                    index={1}
+                                    snapPoints={snapPoints}
+                                    onChange={handleSheetChanges}
+                                >
+                                    <BottomSheetScrollView>
+                                        <BottomSheetView style={{ paddingHorizontal: fonts.getSize(24) }}>
+                                            <BottomSheetView style={styles.commentInputContainer}>
+                                                <Text style={{ fontFamily: fonts.type.semibold, color: colors.black, fontSize: fonts.getSize(16) }}>
+                                                    Comments
+                                                </Text>
+                                                <ButtonWrapper onPress={handleCloseModalPress}>
+                                                    <IonIcon name='close-sharp' size={fonts.getSize(20)} color={colors.black} />
+                                                </ButtonWrapper>
+                                            </BottomSheetView>
+                                            <View style={styles.commentInput}>
+                                                <Image source={images.imageCard} style={[styles.profileImage]} />
+                                                <Text >Comment Text Input</Text>
+                                            </View>
+                                            <>{commentsData === undefined ? <></> :
+                                            <Text style={{ fontFamily: fonts.type.medium, color: colors.black, paddingBottom: fonts.getSize(8) }}>View all Comments({commentsData.results.length})</Text>  }
+                                                
+                                            </>
+                                            <BottomSheetView style={{ gap: fonts.getSize(16) }}>
+                                                {commentsData === undefined ? <LoadingScreen/>:commentsData.results.map((item) => <CommentCard />)}
+                                            </BottomSheetView>
+
+                                        </BottomSheetView>
+                                    </BottomSheetScrollView>
+
+                                </BottomSheetModal>
+                            </>
+                        </View>
+                    </ScrollView>
+                </BottomSheetModalProvider>
+            }
+        </View>
+
+
+
+
+    )
+}
+
+export default NewsDetailPage
+
+const styles = StyleSheet.create({
+    newsContainer: {
+        paddingHorizontal: fonts.getSize(24)
+    },
+    headline: {
+        fontFamily: fonts.type.semibold,
+        fontSize: fonts.getSize(18),
+        paddingVertical: fonts.getSize(8),
+        color: colors.black,
+
+    },
+    tagline: {
+        fontFamily: fonts.type.regular,
+        color: colors.gray
+    },
+    descriptors: {
+        flexDirection: 'row',
+        gap: fonts.getSize(16),
+    },
+    descriptorText: {
+        fontFamily: fonts.type.semibold,
+        fontSize: fonts.getSize(10),
+        color: colors.black,
+        paddingTop: fonts.getSize(8),
+        paddingBottom: fonts.getSize(16)
+    },
+    newsText: {
+        color: colors.gray,
+        fontFamily: fonts.type.regular,
+        lineHeight: fonts.getSize(24),
+        paddingVertical: fonts.getSize(4)
+    },
+    backToTopText: {
+        color: colors.topColor,
+        alignSelf: 'center',
+        justifyContent: 'center',
+        paddingVertical: fonts.getSize(16),
+        fontSize: fonts.getSize(16),
+        fontFamily: fonts.type.regular,
+        textDecorationStyle: 'solid',
+        textDecorationLine: 'underline'
+    },
+    imagesContainer: {
+        width: "auto",
+        height: fonts.getSize(196),
+        paddingHorizontal: 0
+    },
+    image: {
+        borderRadius: fonts.getSize(4),
+        width: '100%',
+        height: '100%'
+    },
+    utilButtons: {
+        flexDirection: 'row',
+        justifyContent: 'space-between',
+        paddingVertical: fonts.getSize(4)
+    },
+    buttonStyle: {
+        padding: fonts.getSize(8)
+    },
+    commentSection: {
+        alignItems: 'center',
+        justifyContent: 'center',
+        flexDirection: 'row',
+        gap: fonts.getSize(8),
+        paddingLeft: fonts.getSize(4)
+    },
+    commentText: {
+        fontFamily: fonts.type.regular,
+        color: colors.gray
+    },
+    commentInputContainer: {
+        flexDirection: 'row',
+        justifyContent: 'space-between',
+        alignItems: 'center',
+        paddingVertical: fonts.getSize(4)
+
+    },
+    profileImage: {
+        height: 42,
+        width: 42,
+        borderRadius: 32,
+        marginRight: fonts.getSize(16)
+
+    },
+    commentInput: {
+        paddingVertical: fonts.getSize(16),
+        alignItems: 'center',
+        justifyContent: 'flex-start',
+        flexDirection: 'row'
+    },
+
+})

部分文件因为文件数量过多而无法显示