Эх сурвалжийг харах

검색영역 FIX
- 엔터키 입력으로 검색
- 검색시 키보드 숨김

jh-mac 7 сар өмнө
parent
commit
8c917d6082
3 өөрчлөгдсөн 52 нэмэгдсэн , 137 устгасан
  1. 0 137
      app/backup
  2. 4 0
      app/seach.tsx
  3. 48 0
      package-lock.json

+ 0 - 137
app/backup

@@ -1,137 +0,0 @@
-import React, { useState } from 'react';
-import {
-  View,
-  Text,
-  TextInput,
-  TouchableOpacity,
-  FlatList,
-  StyleSheet,
-} from 'react-native';
-import AsyncStorage from '@react-native-async-storage/async-storage';
-import { useRouter } from 'expo-router';
-
-interface Song {
-  id: string;
-  title: string;
-  artist: string;
-}
-
-const MOCK_SONGS: Song[] = [
-  { id: '1234', title: '좋은 날', artist: '아이유' },
-  { id: '5678', title: '취중진담', artist: '김동률' },
-  { id: '9101', title: 'LOVE DIVE', artist: 'IVE' },
-  { id: '1121', title: 'Permission to Dance', artist: 'BTS' },
-];
-
-export default function MainScreen() {
-  const [keyword, setKeyword] = useState('');
-  const [results, setResults] = useState<Song[]>([]);
-  const router = useRouter();
-
-  const handleSearch = () => {
-    const filtered = MOCK_SONGS.filter(
-      song =>
-        song.title.includes(keyword) ||
-        song.artist.includes(keyword)
-    );
-    setResults(filtered);
-  };
-
-  const handleAddToFavorites = async (song: Song) => {
-    const stored = await AsyncStorage.getItem('favorites');
-    const parsed = stored ? JSON.parse(stored) : [];
-    await AsyncStorage.setItem('favorites', JSON.stringify([...parsed, song]));
-  };
-
-  return (
-    <View style={styles.container}>
-      <View style={styles.navbar}>
-        <TouchableOpacity onPress={() => {}}>
-          <Text style={styles.icon}>👤</Text>
-        </TouchableOpacity>
-        <TouchableOpacity onPress={() => {}}>
-          <Text style={styles.icon}>⭐️</Text>
-        </TouchableOpacity>
-        <TouchableOpacity onPress={() => {}}>
-          <Text style={styles.icon}>⚙️</Text>
-        </TouchableOpacity>
-      </View>
-
-      {/* 타이틀 */}
-      <Text style={styles.title}>Sing Song</Text>
-
-      {/* 검색 영역 */}
-      <TextInput
-        placeholder="제목 또는 가수를 입력하세요"
-        value={keyword}
-        onChangeText={setKeyword}
-        style={styles.input}
-      />
-      <TouchableOpacity onPress={handleSearch} style={styles.searchButton}>
-        <Text style={styles.searchText}>검색</Text>
-      </TouchableOpacity>
-
-      {/* 검색 결과 리스트 */}
-      <FlatList
-        data={results}
-        keyExtractor={(item) => item.id}
-        renderItem={({ item }) => (
-          <TouchableOpacity onPress={() => handleAddToFavorites(item)}>
-            <View style={styles.item}>
-              <Text>{item.id} - {item.title} ({item.artist})</Text>
-            </View>
-          </TouchableOpacity>
-        )}
-        ListEmptyComponent={<Text>검색 결과가 없습니다.</Text>}
-      />
-    </View>
-  );
-}
-
-const styles = StyleSheet.create({
-  container: {
-    flex: 1,
-    padding: 20,
-    backgroundColor: '#fff',
-  },
-  navbar: {
-    flexDirection: 'row',
-    justifyContent: 'flex-end',
-    gap: 16,
-    marginBottom: 8,
-  },
-  icon: {
-    fontSize: 20,
-  },
-  title: {
-    fontSize: 24,
-    fontWeight: 'bold',
-    marginBottom: 16,
-  },
-  settings: {
-    fontSize: 20,
-  },
-  input: {
-    borderWidth: 1,
-    borderColor: '#ccc',
-    borderRadius: 8,
-    padding: 8,
-    marginBottom: 10,
-  },
-  searchButton: {
-    backgroundColor: '#007AFF',
-    padding: 10,
-    borderRadius: 8,
-    alignItems: 'center',
-    marginBottom: 16,
-  },
-  searchText: {
-    color: '#fff',
-    fontWeight: 'bold',
-  },
-  item: {
-    padding: 12,
-    borderBottomWidth: 1,
-    borderBottomColor: '#eee',
-  },
-});

+ 4 - 0
app/seach.tsx

@@ -10,6 +10,7 @@ import {
   KeyboardAvoidingView,
   Platform,
   Modal,
+  Keyboard,
 } from 'react-native';
 import { fetchSongs } from '@/service/api';
 import { addToFavoritesStorage } from '@/service/storage';
@@ -32,6 +33,7 @@ export default function SearchScreen() {
   ];
 
   const handleSearch = async (): Promise<void> => {
+    Keyboard.dismiss();
     const filtered: Song[] = await fetchSongs(criteria, keyword);
     setResults(filtered);
   };
@@ -94,7 +96,9 @@ export default function SearchScreen() {
           placeholder="검색어 입력"
           value={keyword}
           onChangeText={(text: string) => setKeyword(text)}
+          onSubmitEditing={handleSearch} // 엔터 키 입력 시 검색 실행
           style={styles.input}
+          returnKeyType="search" // 키보드의 엔터 키를 "검색" 버튼으로 표시
         />
 
         <TouchableOpacity onPress={handleSearch} style={styles.searchButton}>

+ 48 - 0
package-lock.json

@@ -9,6 +9,8 @@
       "version": "1.0.0",
       "dependencies": {
         "@expo/vector-icons": "^14.1.0",
+        "@react-native-async-storage/async-storage": "^2.1.2",
+        "@react-native-picker/picker": "^2.11.0",
         "@react-navigation/bottom-tabs": "^7.3.10",
         "@react-navigation/elements": "^2.3.8",
         "@react-navigation/native": "^7.1.6",
@@ -2775,6 +2777,31 @@
         }
       }
     },
+    "node_modules/@react-native-async-storage/async-storage": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-2.1.2.tgz",
+      "integrity": "sha512-dvlNq4AlGWC+ehtH12p65+17V0Dx7IecOWl6WanF2ja38O1Dcjjvn7jVzkUHJ5oWkQBlyASurTPlTHgKXyYiow==",
+      "license": "MIT",
+      "dependencies": {
+        "merge-options": "^3.0.4"
+      },
+      "peerDependencies": {
+        "react-native": "^0.0.0-0 || >=0.65 <1.0"
+      }
+    },
+    "node_modules/@react-native-picker/picker": {
+      "version": "2.11.0",
+      "resolved": "https://registry.npmjs.org/@react-native-picker/picker/-/picker-2.11.0.tgz",
+      "integrity": "sha512-QuZU6gbxmOID5zZgd/H90NgBnbJ3VV6qVzp6c7/dDrmWdX8S0X5YFYgDcQFjE3dRen9wB9FWnj2VVdPU64adSg==",
+      "license": "MIT",
+      "workspaces": [
+        "example"
+      ],
+      "peerDependencies": {
+        "react": "*",
+        "react-native": "*"
+      }
+    },
     "node_modules/@react-native/assets-registry": {
       "version": "0.79.2",
       "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.79.2.tgz",
@@ -7915,6 +7942,15 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/is-plain-obj": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+      "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/is-promise": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
@@ -8931,6 +8967,18 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/merge-options": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz",
+      "integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==",
+      "license": "MIT",
+      "dependencies": {
+        "is-plain-obj": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/merge-stream": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",