diff --git a/App.js b/App.js
index 9263190..febe8e7 100644
--- a/App.js
+++ b/App.js
@@ -1,5 +1,5 @@
import React, { useCallback, useEffect, useState } from "react";
-import { Image } from "react-native";
+import { Image, View } from "react-native";
import * as SplashScreen from "expo-splash-screen";
import * as Font from "expo-font";
import { Asset } from "expo-asset";
@@ -46,7 +46,7 @@ export default function App() {
await _loadResourcesAsync();
// Pre-load fonts, make any API calls you need to do here
await Font.loadAsync({
- ArgonExtra: require("./assets/font/argon.ttf"),
+ ArgonExtra: require("./assets/font/Orbit-Regular.ttf"),
});
} catch (e) {
console.warn(e);
@@ -73,12 +73,13 @@ export default function App() {
}
return (
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
);
}
diff --git a/app.json b/app.json
index b1702aa..14032d9 100644
--- a/app.json
+++ b/app.json
@@ -3,10 +3,7 @@
"name": "Argon FREE React Native",
"slug": "argon-free-react-native",
"privacy": "public",
- "platforms": [
- "ios",
- "android"
- ],
+ "platforms": ["ios", "android", "web"],
"version": "1.7.1",
"orientation": "portrait",
"icon": "./assets/icon.png",
@@ -18,9 +15,7 @@
"updates": {
"fallbackToCacheTimeout": 0
},
- "assetBundlePatterns": [
- "**/*"
- ],
+ "assetBundlePatterns": ["**/*"],
"ios": {
"supportsTablet": true
},
diff --git a/assets/.DS_Store b/assets/.DS_Store
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and b/assets/.DS_Store differ
diff --git a/assets/font/Orbit-Regular.ttf b/assets/font/Orbit-Regular.ttf
new file mode 100644
index 0000000..db9562d
Binary files /dev/null and b/assets/font/Orbit-Regular.ttf differ
diff --git a/assets/font/argon.ttf b/assets/font/argon.ttf
deleted file mode 100755
index 4240bc9..0000000
Binary files a/assets/font/argon.ttf and /dev/null differ
diff --git a/assets/imgs/argon-logo-onboarding.png b/assets/imgs/argon-logo-onboarding.png
index 4350b4e..53ca2e9 100644
Binary files a/assets/imgs/argon-logo-onboarding.png and b/assets/imgs/argon-logo-onboarding.png differ
diff --git a/assets/imgs/argon-logo-onboarding@2x.png b/assets/imgs/argon-logo-onboarding@2x.png
index a59cc29..53ca2e9 100644
Binary files a/assets/imgs/argon-logo-onboarding@2x.png and b/assets/imgs/argon-logo-onboarding@2x.png differ
diff --git a/assets/imgs/argon-logo.png b/assets/imgs/argon-logo.png
index 2ca2750..0bd08a9 100644
Binary files a/assets/imgs/argon-logo.png and b/assets/imgs/argon-logo.png differ
diff --git a/assets/imgs/argon-logo@2x.png b/assets/imgs/argon-logo@2x.png
deleted file mode 100644
index 82e3fa8..0000000
Binary files a/assets/imgs/argon-logo@2x.png and /dev/null differ
diff --git a/assets/imgs/backg1.png b/assets/imgs/backg1.png
new file mode 100644
index 0000000..65ffb22
Binary files /dev/null and b/assets/imgs/backg1.png differ
diff --git a/assets/imgs/backg2.png b/assets/imgs/backg2.png
new file mode 100644
index 0000000..277858e
Binary files /dev/null and b/assets/imgs/backg2.png differ
diff --git a/assets/imgs/kakao.png b/assets/imgs/kakao.png
new file mode 100644
index 0000000..c882acc
Binary files /dev/null and b/assets/imgs/kakao.png differ
diff --git a/assets/imgs/logo_sub.png b/assets/imgs/logo_sub.png
new file mode 100644
index 0000000..66847de
Binary files /dev/null and b/assets/imgs/logo_sub.png differ
diff --git a/assets/splash.png b/assets/splash.png
index 89a8eaf..62230fd 100644
Binary files a/assets/splash.png and b/assets/splash.png differ
diff --git a/babel.config.js b/babel.config.js
index c0d6e65..d69299a 100644
--- a/babel.config.js
+++ b/babel.config.js
@@ -9,7 +9,7 @@ module.exports = function (api) {
extensions: [".tsx", ".ts", ".js", ".json"],
},
],
- "react-native-reanimated/plugin",
+ ["react-native-reanimated/plugin"],
],
};
};
diff --git a/components/DrawerItem.js b/components/DrawerItem.js
index 36ba698..aedf237 100644
--- a/components/DrawerItem.js
+++ b/components/DrawerItem.js
@@ -10,7 +10,7 @@ class DrawerItem extends React.Component {
const { title, focused } = this.props;
switch (title) {
- case "Home":
+ case "홈":
return (
);
- case "Elements":
+ case "복용기록확인":
return (
);
- case "Articles":
+ case "복용알람":
return (
);
- case "Profile":
+ case "중독위험도":
return (
);
- case "Account":
+ case "프로필":
return (
",
+ "&": "&",
+ """: '"',
+ "'": "'",
+ " ": " ",
+ "©": "©",
+ "®": "®",
+ // 필요한 추가 HTML 엔티티를 여기에 추가하세요.
+ };
+
+ let decodedString = Object.keys(entities).reduce((acc, entity) => {
+ const regex = new RegExp(entity, "g");
+ return acc.replace(regex, entities[entity]);
+ }, str);
+
+ // 문자열의 시작과 끝에 있는 따옴표 제거
+ decodedString = decodedString.replace(/^"|"$/g, "");
+ // 이스케이프된 줄바꿈 문자 처리
+ decodedString = decodedString.replace(/\\n/g, "\n");
+
+ return decodedString;
+}
+
+const DrugCard = ({ item }) => {
+ const { itemName, efficiency, warn, sideEffect, image, typeName } = item;
+
+ // decodeHtmlEntity 함수를 적용하여 출력
+ const renderTextWithNewLines = (text) => {
+ const formattedText = decodeHtmlEntity(text);
+ return formattedText.split("\n").map((line, index) => (
+
+ {line}
+
+ ));
+ };
+
+ return (
+
+ {itemName}
+ {image && }
+ {efficiency && (
+ <>
+ 효능
+ {renderTextWithNewLines(efficiency)}
+ >
+ )}
+ {warn && (
+ <>
+ 주의
+ {renderTextWithNewLines(warn)}
+ >
+ )}
+ {sideEffect && (
+ <>
+ 부작용
+ {renderTextWithNewLines(sideEffect)}
+ >
+ )}
+ {typeName && (
+ <>
+ 위험분류
+ {renderTextWithNewLines(typeName)}
+ >
+ )}
+
+ );
+};
+
+const styles = StyleSheet.create({
+ card: {
+ backgroundColor: "#fff",
+ borderRadius: 8,
+ padding: 20,
+ marginBottom: 20,
+ shadowColor: "#000",
+ shadowOffset: {
+ width: 0,
+ height: 2,
+ },
+ shadowOpacity: 0.25,
+ shadowRadius: 3.84,
+ elevation: 5,
+ },
+ title: {
+ fontSize: 18,
+ fontWeight: "bold",
+ marginBottom: 10,
+ },
+ subtitle: {
+ fontSize: 16,
+ fontWeight: "bold",
+ marginTop: 10,
+ },
+ text: {
+ fontSize: 14,
+ marginTop: 5,
+ },
+ image: {
+ width: 100,
+ height: 100,
+ resizeMode: "cover",
+ marginBottom: 10,
+ },
+});
+
+export default DrugCard;
diff --git a/components/DrugRecordCard.js b/components/DrugRecordCard.js
new file mode 100644
index 0000000..f12f135
--- /dev/null
+++ b/components/DrugRecordCard.js
@@ -0,0 +1,104 @@
+import React from "react";
+import { View, Text, Image, StyleSheet } from "react-native";
+import { FontAwesome } from '@expo/vector-icons';
+
+const DrugRecordCard = ({ item }) => {
+ const { medicineName, dailyFrequency, duration, startDate, endDate, isActive, image, typeName } = item;
+
+ const calculateDrugIntakeDates = (startDate, duration) => {
+ const intakeDates = [];
+ const start = new Date(startDate);
+
+ for (let day = 0; day < duration; day++) {
+ const date = new Date(start);
+ date.setDate(start.getDate() + day);
+
+ intakeDates.push(date.toLocaleDateString("ko-KR"));
+ }
+
+ return intakeDates;
+ };
+
+ const drugIntakeDates = calculateDrugIntakeDates(startDate, duration);
+
+ return (
+
+
+
+ {image && }
+
+
+ 이름 {medicineName}
+
+
+ {startDate} ~ {endDate} | 총{duration}일
+
+ 위험 분류 {typeName}
+
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ card: {
+ padding: 20,
+ elevation: 5,
+ flexDirection: 'row',
+ alignItems: 'center',
+ },
+ contentContainer: {
+ flexDirection: 'row',
+ alignItems: 'flex-start'
+ },
+ imageContainer: {
+ marginRight: 10,
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ image: {
+ width: 80,
+ height: 60,
+ resizeMode: "cover",
+ borderRadius: 5
+ },
+ icon: {
+ width: 68,
+ height: 19,
+ marginTop: 5
+ },
+ statusText: {
+ marginTop: 8,
+ },
+ textContainer: {
+ flex: 1,
+ alignItems: 'flex-start'
+ },
+ title: {
+ fontSize: 18,
+ fontWeight: "bold",
+ marginBottom: 5,
+ },
+ periodContainer: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ marginBottom: 5,
+ },
+ calendarIcon: {
+ marginRight: 5,
+ },
+ period: {
+ fontSize: 12,
+ marginBottom: 5,
+ },
+ lightText: {
+ color: '#6a6c6c',
+ fontSize: 12,
+ },
+ boldText: {
+ fontWeight: 'bold',
+ color: '#171717',
+ }
+});
+
+export default DrugRecordCard;
\ No newline at end of file
diff --git a/components/Header.js b/components/Header.js
index 207c7e8..abc3885 100644
--- a/components/Header.js
+++ b/components/Header.js
@@ -3,6 +3,10 @@ import { withNavigation } from '@react-navigation/compat';
import { TouchableOpacity, StyleSheet, Platform, Dimensions } from 'react-native';
import { Button, Block, NavBar, Text, theme } from 'galio-framework';
+import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
+
+const Tab = createBottomTabNavigator();
+
import Icon from './Icon';
import Input from './Input';
import Tabs from './Tabs';
@@ -11,134 +15,14 @@ import argonTheme from '../constants/Theme';
const { height, width } = Dimensions.get('window');
const iPhoneX = () => Platform.OS === 'ios' && (height === 812 || width === 812 || height === 896 || width === 896);
-const BellButton = ({isWhite, style, navigation}) => (
- navigation.navigate('Pro')}>
-
-
-
-);
-
-const BasketButton = ({isWhite, style, navigation}) => (
- navigation.navigate('Pro')}>
-
-
-);
-
-const SearchButton = ({isWhite, style, navigation}) => (
- navigation.navigate('Pro')}>
-
-
-);
class Header extends React.Component {
handleLeftPress = () => {
const { back, navigation } = this.props;
return (back ? navigation.goBack() : navigation.openDrawer());
}
- renderRight = () => {
- const { white, title, navigation } = this.props;
-
- if (title === 'Title') {
- return [
- ,
-
- ]
- }
-
- switch (title) {
- case 'Home':
- return ([
- ,
-
- ]);
- case 'Deals':
- return ([
- ,
-
- ]);
- case 'Categories':
- return ([
- ,
-
- ]);
- case 'Category':
- return ([
- ,
-
- ]);
- case 'Profile':
- return ([
- ,
-
- ]);
- case 'Product':
- return ([
- ,
-
- ]);
- case 'Search':
- return ([
- ,
-
- ]);
- case 'Settings':
- return ([
- ,
-
- ]);
- default:
- break;
- }
- }
- renderSearch = () => {
- const { navigation } = this.props;
- return (
- navigation.navigate('Pro')}
- iconContent={}
- />
- );
- }
- renderOptions = () => {
- const { navigation, optionLeft, optionRight } = this.props;
- return (
-
-
-
-
- );
- }
+
renderTabs = () => {
const { tabs, tabIndex, navigation } = this.props;
const defaultTab = tabs && tabs[0] && tabs[0].id;
@@ -157,8 +41,6 @@ class Header extends React.Component {
if (search || tabs || options) {
return (
- {search ? this.renderSearch() : null}
- {options ? this.renderOptions() : null}
{tabs ? this.renderTabs() : null}
);
@@ -185,7 +67,6 @@ class Header extends React.Component {
title={title}
style={navbarStyles}
transparent={transparent}
- right={this.renderRight()}
rightStyle={{ alignItems: 'center' }}
left={
;
}
return ;
diff --git a/components/ImagePickerComponent.js b/components/ImagePickerComponent.js
new file mode 100644
index 0000000..8fb2a4a
--- /dev/null
+++ b/components/ImagePickerComponent.js
@@ -0,0 +1,121 @@
+import React, { useState, useEffect } from "react";
+import { TouchableOpacity, Text, View } from "react-native";
+import * as ImagePicker from "expo-image-picker";
+import Constants from "expo-constants";
+import axios from "axios";
+import { withNavigation } from "@react-navigation/compat";
+
+const ImagePickerComponent = ({ navigation }) => {
+ const [selectedImage, setSelectedImage] = useState(null);
+ const [selectedImageData, setSelectedImageData] = useState(null);
+
+ useEffect(() => {
+ (async () => {
+ if (Constants.platform.ios) {
+ const { status } =
+ await ImagePicker.requestMediaLibraryPermissionsAsync();
+ if (status !== "granted") {
+ alert(
+ "죄송합니다. 이 기능을 사용하려면 카메라 롤 권한이 필요합니다!"
+ );
+ }
+ }
+ })();
+ }, []);
+
+ // ImagePickerComponent
+ useEffect(() => {
+ if (selectedImageData) {
+ navigation.push("NewStackScreen", {
+ selectedImageData: selectedImageData,
+ });
+ }
+ }, [selectedImageData]);
+
+ const pickImageAndSend = async () => {
+ let result = await ImagePicker.launchImageLibraryAsync({
+ mediaTypes: ImagePicker.MediaTypeOptions.Images,
+ allowsEditing: true,
+ aspect: [4, 3],
+ quality: 1,
+ });
+
+ if (!result.cancelled) {
+ setSelectedImage({ uri: result.uri });
+ sendImageToBackend(result.uri);
+ }
+ };
+
+ const sendImageToBackend = async (imageUri) => {
+ const formData = new FormData();
+ formData.append("imageFile", {
+ uri: imageUri,
+ type: "image/jpeg",
+ name: "photo.jpg",
+ });
+
+ try {
+ const response = await axios.post(
+ "http://34.64.161.34:8080/medicine",
+ formData,
+ {
+ headers: {
+ "Content-Type": "multipart/form-data",
+ },
+ timeout: 1000000000, // 10초 시간 제한 설정
+ }
+ );
+
+
+ // Handle response from backend
+ console.log(response.data);
+ setSelectedImageData(response.data);
+
+ // Open a new stack screen after image selection
+ navigation.push("NewStackScreen", {
+ selectedImageData: response.data,
+ });
+ } catch (error) {
+ console.error(error);
+ }
+ };
+
+ return (
+
+ 이미지로
+ 분석하기
+
+ );
+};
+
+const styles = {
+ buttonContainer: {
+ flex: 1,
+ marginHorizontal: 5, // Adjust margin as needed
+ borderRadius: 15, // Add border radius for rounded corners
+ overflow: "hidden", // Ensure content stays within rounded borders
+ elevation: 5, // Add shadow elevation
+ },
+ cameraButton: {
+ justifyContent: "center",
+ alignItems: "center",
+ paddingVertical: 15, // Adjust this value as needed to control the button height
+ borderRadius: 15, // Make it round
+ backgroundColor: "purple",
+ marginVertical: 20,
+ height: 100, // Fixed height for the button
+ },
+ greenButton: {
+ backgroundColor: "#67B779"
+ },
+ buttonText: {
+ fontSize: 25,
+ color: "white",
+ fontFamily: "ArgonExtra",
+ },
+};
+
+export default withNavigation(ImagePickerComponent);
diff --git a/components/KakaoLogin.js b/components/KakaoLogin.js
new file mode 100644
index 0000000..b1c9b1c
--- /dev/null
+++ b/components/KakaoLogin.js
@@ -0,0 +1,102 @@
+import React, { useState } from "react";
+import {
+ View,
+ Button,
+ Modal,
+ TouchableOpacity,
+ Text,
+ Image,
+} from "react-native";
+import { WebView } from "react-native-webview";
+import axios from "axios";
+
+const runFirst = `window.ReactNativeWebView.postMessage("this is message from web");`;
+
+const KakaoLogin = ({ navigation, onLoginSuccess }) => {
+ const [modalVisible, setModalVisible] = useState(false);
+
+ const handleLoginButton = () => {
+ setModalVisible(true);
+ };
+
+ function LogInProgress(data) {
+ const exp = "code=";
+ var condition = data.indexOf(exp);
+
+ if (condition !== -1) {
+ var request_code = data.substring(condition + exp.length);
+ console.log("Authorization Code:", request_code);
+ sendAuthCodeToBackend(request_code);
+ }
+ }
+
+ const sendAuthCodeToBackend = async (authorizationCode) => {
+ var backend_url = "http://34.64.161.34:8080/login/kakao";
+
+ axios({
+ method: "post",
+ url: backend_url,
+ data: {
+ authorizationCode: authorizationCode,
+ },
+ })
+ .then(function (response) {
+ console.log("Backend Response:", response);
+ // 카카오 로그인이 성공했을 때 콜백 함수 호출
+ onLoginSuccess();
+ })
+ .catch(function (error) {
+ console.log("Backend Error:", error);
+ });
+ };
+
+ return (
+
+
+
+
+ {
+ setModalVisible(false);
+ }}
+ >
+ {
+ if (
+ event.nativeEvent["url"].startsWith(
+ "http://34.64.161.34:8080/login/kakao"
+ )
+ ) {
+ LogInProgress(event.nativeEvent["url"]);
+ setModalVisible(false);
+ }
+ }}
+ />
+
+
+ );
+};
+
+export default KakaoLogin;
diff --git a/components/ModalComponent.js b/components/ModalComponent.js
new file mode 100644
index 0000000..1b97cc7
--- /dev/null
+++ b/components/ModalComponent.js
@@ -0,0 +1,151 @@
+import React from "react";
+import {
+ View,
+ Text,
+ StyleSheet,
+ Modal,
+ Button,
+ TouchableOpacity,
+} from "react-native";
+import RadioButton from "react-native-radio-button";
+import { Picker } from "@react-native-picker/picker";
+import DateTimePicker from "@react-native-community/datetimepicker";
+
+const ModalComponent = (props) => {
+ return (
+
+
+
+ 복용 정보 입력
+ {props.drugName}
+
+
+ 복용시작일:
+
+
+
+
+ 복용마감일:
+
+
+
+
+ 현재 복용중 여부:
+
+
+ Yes
+
+ No
+
+
+
+
+ 하루 복용 횟수:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ centeredView: {
+ flex: 1,
+ justifyContent: "center",
+ alignItems: "center",
+ marginTop: 22,
+ },
+ modalView: {
+ margin: 30,
+ backgroundColor: "white",
+ borderRadius: 20,
+ padding: 30,
+ alignItems: "center",
+ shadowColor: "#000",
+ shadowOffset: {
+ width: 0,
+ height: 2,
+ },
+ shadowOpacity: 0.25,
+ shadowRadius: 4,
+ elevation: 5,
+ },
+ modalTitle: {
+ marginBottom: 15,
+ textAlign: "center",
+ fontSize: 20,
+ fontWeight: "bold",
+ },
+ modalSubtitle: {
+ fontSize: 16,
+ fontWeight: "600",
+ marginRight: 10,
+ },
+ modalText: {
+ fontSize: 14,
+ marginBottom: 15,
+ },
+ datePicker: {
+ flexDirection: "row",
+ alignItems: "center",
+ marginBottom: 20,
+ },
+ rowContainer: {
+ flexDirection: "row",
+ alignItems: "center",
+ justifyContent: "space-between",
+ marginBottom: 20,
+ },
+ row: {
+ flexDirection: "row",
+ alignItems: "center",
+ },
+ radioText: {
+ fontSize: 14,
+ },
+ pickerContainer: {
+ flexDirection: "row",
+ alignItems: "center",
+ marginBottom: 10,
+ },
+ picker: {
+ height: 40,
+ width: 100,
+ fontSize: 16,
+ },
+});
+
+export default ModalComponent;
diff --git a/components/SubTitle.js b/components/SubTitle.js
new file mode 100644
index 0000000..8fdb37c
--- /dev/null
+++ b/components/SubTitle.js
@@ -0,0 +1,45 @@
+import { Block, Text, theme } from "galio-framework";
+import {
+ StyleSheet,
+ View
+} from "react-native";
+
+import React from 'react';
+import { FontAwesome } from '@expo/vector-icons';
+
+const SubTitle = ({ title, description, iconName }) => {
+ return (
+
+ {iconName && }
+
+ {title}
+ {description && {description}}
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ },
+ icon: {
+ marginRight: 10,
+ marginLeft: 10
+ },
+ textContainer: {
+ flex: 1,
+ },
+ title: {
+ marginBottom: 3,
+ fontSize: 20,
+ fontWeight: 'bold',
+ },
+ description: {
+ fontSize: 14,
+ color: 'gray',
+ },
+});
+
+export default SubTitle;
diff --git a/log.txt b/log.txt
new file mode 100644
index 0000000..b1dbd51
Binary files /dev/null and b/log.txt differ
diff --git a/navigation/Menu.js b/navigation/Menu.js
index fda94f7..c4580ee 100644
--- a/navigation/Menu.js
+++ b/navigation/Menu.js
@@ -13,14 +13,14 @@ function CustomDrawerContent({
state,
...rest
}) {
- const screens = ["Home", "Profile", "Account", "Elements", "Articles"];
+ const screens = ["홈", "복용 기록 확인", "복용 알람", "중독 위험도", "프로필"];
return (
-
+
diff --git a/navigation/Screens.js b/navigation/Screens.js
index db91d65..3b35bb5 100644
--- a/navigation/Screens.js
+++ b/navigation/Screens.js
@@ -9,6 +9,7 @@ import { Block } from "galio-framework";
import CustomDrawerContent from "./Menu";
import Elements from "../screens/Elements";
// screens
+import Description from "../screens/Description";
import Home from "../screens/Home";
import Onboarding from "../screens/Onboarding";
import Pro from "../screens/Pro";
@@ -150,6 +151,51 @@ function ProfileStack(props) {
);
}
+function DescriptionStack(props) {
+ return (
+
+ (
+
+ ),
+ cardStyle: { backgroundColor: "#F8F9FE" },
+ }}
+ />
+ (
+
+ ),
+ headerTransparent: true,
+ }}
+ />
+
+ );
+}
+
+
function HomeStack(props) {
return (
+
);
@@ -247,35 +294,35 @@ function AppStack(props) {
initialRouteName="Home"
>
{
+// const grouped = {};
+
+// articles.forEach((article) => {
+// const { startDate, duration } = article;
+// const start = new Date(startDate);
+
+// for (let day = 0; day < duration; day++) {
+// const date = new Date(start);
+// date.setDate(start.getDate() + day);
+// const dateString = date.toLocaleDateString("ko-KR");
+
+// if (!grouped[dateString]) {
+// grouped[dateString] = [];
+// }
+
+// grouped[dateString].push(article);
+// }
+// });
+// return grouped;
+// };
+
+class Description extends React.Component {
+ renderProduct = (item, index) => {
+ const { navigation } = this.props;
+
+ return (
+ navigation.navigate("Pro", { product: item })}
+ >
+
+
+
+
+ {item.price}
+
+
+ {item.title}
+
+
+ {item.description}
+
+
+
+
+ );
+ };
+
+ renderCards = () => {
+ // const groupedArticles = groupByIntakeDate(articles);
+
+ return (
+
+
+
+
+ {/* 위험 약물로 변경 */}
+ {articles &&
+ articles.map((item, index) =>
+ this.renderProduct(item, index)
+ )}
+
+
+
+
+ {/*
+
+
+ {Object.entries(groupedArticles).map(([date, articlesForDate], index) => (
+
+ {date}
+ {articlesForDate.map((article, articleIndex) => (
+
+ ))}
+
+ ))}
+
+ */}
+
+
+
+ {articles.map((article, index) => (
+
+ ))}
+
+
+
+ );
+};
+
+ render() {
+ return (
+
+
+ {this.renderCards()}
+
+
+ );
+ }
+}
+
+const styles = StyleSheet.create({
+ title: {
+ paddingBottom: theme.SIZES.BASE,
+ paddingHorizontal: theme.SIZES.BASE * 2,
+ marginTop: 22,
+ color: argonTheme.COLORS.HEADER,
+ },
+ group: {
+ paddingTop: theme.SIZES.BASE,
+ },
+ albumThumb: {
+ borderRadius: 4,
+ marginVertical: 4,
+ alignSelf: "center",
+ width: thumbMeasure,
+ height: thumbMeasure,
+ },
+ category: {
+ backgroundColor: theme.COLORS.WHITE,
+ marginVertical: theme.SIZES.BASE / 2,
+ borderWidth: 0,
+ },
+ categoryTitle: {
+ height: "100%",
+ paddingHorizontal: theme.SIZES.BASE,
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
+ justifyContent: "center",
+ alignItems: "center",
+ },
+ imageBlock: {
+ overflow: "hidden",
+ borderRadius: 4,
+ },
+ productItem: {
+ width: cardWidth - theme.SIZES.BASE * 2,
+ marginHorizontal: theme.SIZES.BASE,
+ shadowColor: "black",
+ shadowOffset: { width: 0, height: 7 },
+ shadowRadius: 10,
+ shadowOpacity: 0.2,
+ },
+ productImage: {
+ width: cardWidth - theme.SIZES.BASE,
+ height: cardWidth - theme.SIZES.BASE,
+ borderRadius: 3,
+ },
+ productPrice: {
+ paddingTop: theme.SIZES.BASE,
+ paddingBottom: theme.SIZES.BASE / 2,
+ },
+ productDescription: {
+ paddingTop: theme.SIZES.BASE,
+ // paddingBottom: theme.SIZES.BASE * 2,
+ },
+});
+
+export default Description;
\ No newline at end of file
diff --git a/screens/Elements.js b/screens/Elements.js
index 7a73d80..c91718f 100644
--- a/screens/Elements.js
+++ b/screens/Elements.js
@@ -363,10 +363,10 @@ class Elements extends React.Component {
Navigation
-
+
-
+
{
+ const { status } = await Camera.requestPermissionsAsync();
+ this.setState({ hasPermission: status === "granted" });
+ };
+
+ openCamera = () => {
+ this.setState({ isCameraVisible: true });
+ };
+
+ closeCamera = () => {
+ this.setState({ isCameraVisible: false });
+ };
+
+ setType = () => {
+ this.setState((prevState) => ({
+ type:
+ prevState.type === Camera.Constants.Type.back
+ ? Camera.Constants.Type.front
+ : Camera.Constants.Type.back,
+ }));
+ };
+
+ takePicture = async () => {
+ if (this.camera) {
+ const options = { quality: 0.5, base64: true };
+ const photo = await this.camera.takePictureAsync(options);
+ this.setState({ photo, isCameraVisible: true });
+ }
+ };
+
+ savePhoto = async () => {
+ if (!this.state.photo) {
+ console.error("No photo to save.");
+ return;
+ }
+
+ console.log("Photo saved:", this.state.photo.base64);
+
+ const formData = new FormData();
+ formData.append("imageFile", {
+ uri: this.state.photo.uri,
+ type: "image/jpeg",
+ name: "photo.jpg",
+ });
+
+ try {
+ const response = await fetch("http://34.64.161.34:8080/medicine", {
+ method: "POST",
+ body: formData,
+ headers: {
+ "Content-Type": "multipart/form-data",
+ },
+ });
+
+ if (response.ok) {
+ console.log("Photo successfully sent to backend!", response);
+ const data = await response.json();
+ this.props.navigation.push("NewStackScreen", { data });
+ } else {
+ console.error("Failed to send photo to backend.", response);
+ throw new Error("No response received from the backend.");
+ }
+ } catch (error) {
+ console.error("Error while sending photo to backend:", error);
+
+ // Even if backend submission fails, move to NewStackScreen with error message.
+ this.props.navigation.push("NewStackScreen", {
+ error: "Backend submission failed",
+ });
+ }
+
+ this.setState({ photo: null, isCameraVisible: false });
+ };
+
+ retakePicture = () => {
+ this.setState({ photo: null });
+ };
+
+ pickImageAndSend = async () => {
+ this.props.navigation.push("NewStackScreen", { data });
+ };
+
+ renderCameraModal = () => {
+ return (
+
+ {this.state.photo ? (
+
+
+
+
+ 다시찍기
+
+
+ 저장
+
+
+
+ ) : (
+ {
+ this.camera = ref;
+ }}
+ >
+
+
+
+ Flip
+
+
+
+
+
+ SNAP
+
+
+
+
+ )}
+
+ );
+ };
+
renderArticles = () => {
return (
-
-
-
-
-
-
-
-
+ contentContainerStyle={styles.articles}
+ >
+
+ {this.state.hasPermission && (
+
+
+
+ 사진으로
+ 분석하기
+
+
+
+
+ {
+ this.setState({ selectedImage });
+ this.props.navigation.push("NewStackScreen", {
+ selectedImage,
+ });
+ }}
+ />
+
+
+ {this.state.selectedImage && (
+
+ )}
+ {this.renderCameraModal()}
+
+ )}
+
+
+
+ 이 약 먹어도 될까?
+
- )
- }
+ );
+ };
render() {
+ const { navigation } = this.props;
+
return (
-
- {this.renderArticles()}
-
+
+
+ {() => (
+
+
+ {this.renderArticles()}
+
+
+ )}
+
+
+
);
}
}
const styles = StyleSheet.create({
home: {
- width: width,
+ width,
},
articles: {
width: width - theme.SIZES.BASE * 2,
paddingVertical: theme.SIZES.BASE,
+ justifyContent: "flex-end"
+ },
+ bottomButtonsContainer: {
+ flexDirection: "row",
+ justifyContent: "space-around",
+ alignItems: "center",
+ marginVertical: 20,
+ },
+ buttonContainer: {
+ flex: 1,
+ marginHorizontal: 5, // Adjust margin as needed
+ borderRadius: 15, // Add border radius for rounded corners
+ overflow: "hidden", // Ensure content stays within rounded borders
+ shadowColor: "#000", // Shadow color
+ shadowOffset: {
+ width: 0,
+ height: 2,
+ },
+ shadowOpacity: 0.25, // Shadow opacity
+ shadowRadius: 3.84, // Shadow radius
+ elevation: 5, // Add shadow elevation for Android
+ },
+ cameraButton: {
+ justifyContent: "center",
+ alignItems: "center",
+ paddingVertical: 15, // Adjust this value as needed to control the button height
+ borderRadius: 10, // Make it round
+ backgroundColor: "purple",
+ marginVertical: 20,
+ height: 150, // Fixed height for the button
+ },
+ greenButton: {
+ backgroundColor: "#67B779"
+ },
+ buttonText: {
+ fontSize: 25,
+ color: "white",
+ fontFamily: "ArgonExtra",
},
});
diff --git a/screens/NewStackScreen.js b/screens/NewStackScreen.js
new file mode 100644
index 0000000..765a7ea
--- /dev/null
+++ b/screens/NewStackScreen.js
@@ -0,0 +1,95 @@
+import React, { useState, useLayoutEffect } from "react";
+import { useNavigation, useRoute } from "@react-navigation/native";
+
+import {
+ StyleSheet,
+ Dimensions,
+ ScrollView,
+ Text,
+ Button,
+ View,
+} from "react-native";
+import { Block, theme } from "galio-framework";
+import { Card } from "../components/Card";
+import ModalComponent from "../components/ModalComponent";
+import DrugCard from "../components/DrugCard"; // DrugCard import 추가
+
+const { width } = Dimensions.get("screen");
+
+const NewStackScreen = () => {
+ const navigation = useNavigation(); // useNavigation hook 사용
+ const route = useRoute(); // useRoute hook 사용
+ const selectedImageData = route.params.selectedImageData;
+
+ const [modalVisible, setModalVisible] = useState(false);
+ const [drugName, setDrugName] = useState("약물 이름");
+ const [startDate, setStartDate] = useState(new Date());
+ const [endDate, setEndDate] = useState(new Date());
+ const [isTaking, setIsTaking] = useState(true);
+ const [timesPerDay, setTimesPerDay] = useState(1);
+
+ useLayoutEffect(() => {
+ navigation.setOptions({
+ headerRight: () => (
+
- {/*
-
-
-
-
-
-
-
- CONNECT
-
-
- MESSAGE
-
-
-
-
-
-
- 2K
-
- Orders
-
-
-
- 10
-
- Photos
-
-
-
- 89
-
- Comments
-
-
-
-
-
-
- Jessica Jones, 27
-
-
- San Francisco, USA
-
-
-
-
-
-
-
- An artist of considerable range, Jessica name taken by
- Melbourne …
-
-
- Show more
-
-
-
-
- Album
-
-
-
-
- View all
-
-
-
-
- {Images.Viewed.map((img, imgIndex) => (
-
- ))}
-
-
-
-
- */}
);
}
@@ -283,17 +127,17 @@ const styles = StyleSheet.create({
profile: {
marginTop: Platform.OS === "android" ? -HeaderHeight : 0,
// marginBottom: -HeaderHeight * 2,
- flex: 1
+ flex: 1,
},
profileContainer: {
width: width,
height: height,
padding: 0,
- zIndex: 1
+ zIndex: 1,
},
profileBackground: {
width: width,
- height: height / 2
+ height: height / 2,
},
profileCard: {
// position: "relative",
@@ -307,36 +151,36 @@ const styles = StyleSheet.create({
shadowOffset: { width: 0, height: 0 },
shadowRadius: 8,
shadowOpacity: 0.2,
- zIndex: 2
+ zIndex: 2,
},
info: {
- paddingHorizontal: 40
+ paddingHorizontal: 40,
},
avatarContainer: {
position: "relative",
- marginTop: -80
+ marginTop: -80,
},
avatar: {
width: 124,
height: 124,
borderRadius: 62,
- borderWidth: 0
+ borderWidth: 0,
},
nameInfo: {
- marginTop: 35
+ marginTop: 35,
},
divider: {
width: "90%",
borderWidth: 1,
- borderColor: "#E9ECEF"
+ borderColor: "#E9ECEF",
},
thumb: {
borderRadius: 4,
marginVertical: 4,
alignSelf: "center",
width: thumbMeasure,
- height: thumbMeasure
- }
+ height: thumbMeasure,
+ },
});
export default Profile;