업데이트
This commit is contained in:
parent
91e77526b4
commit
c1bca972f5
2
package-lock.json
generated
2
package-lock.json
generated
@ -26,7 +26,7 @@
|
||||
"axios": "^1.6.7",
|
||||
"bcrypt": "^5.1.1",
|
||||
"change-case": "^5.2.0",
|
||||
"cloudinary": "^1.41.0",
|
||||
"cloudinary": "^1.41.3",
|
||||
"date-fns": "^2.30.0",
|
||||
"eslint": "latest",
|
||||
"eslint-config-next": "latest",
|
||||
|
@ -28,7 +28,7 @@
|
||||
"axios": "^1.6.7",
|
||||
"bcrypt": "^5.1.1",
|
||||
"change-case": "^5.2.0",
|
||||
"cloudinary": "^1.41.0",
|
||||
"cloudinary": "^1.41.3",
|
||||
"date-fns": "^2.30.0",
|
||||
"eslint": "latest",
|
||||
"eslint-config-next": "latest",
|
||||
|
1
public/images/KakaoTalk_logo.svg
Normal file
1
public/images/KakaoTalk_logo.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="2500" height="2500" viewBox="0 0 256 256"><path fill="#FFE812" d="M256 236c0 11.046-8.954 20-20 20H20c-11.046 0-20-8.954-20-20V20C0 8.954 8.954 0 20 0h216c11.046 0 20 8.954 20 20v216z"/><path d="M128 36C70.562 36 24 72.713 24 118c0 29.279 19.466 54.97 48.748 69.477-1.593 5.494-10.237 35.344-10.581 37.689 0 0-.207 1.762.934 2.434s2.483.15 2.483.15c3.272-.457 37.943-24.811 43.944-29.04 5.995.849 12.168 1.29 18.472 1.29 57.438 0 104-36.712 104-82 0-45.287-46.562-82-104-82z"/><path fill="#FFE812" d="M70.5 146.625c-3.309 0-6-2.57-6-5.73V105.25h-9.362c-3.247 0-5.888-2.636-5.888-5.875s2.642-5.875 5.888-5.875h30.724c3.247 0 5.888 2.636 5.888 5.875s-2.642 5.875-5.888 5.875H76.5v35.645c0 3.16-2.691 5.73-6 5.73zM123.112 146.547c-2.502 0-4.416-1.016-4.993-2.65l-2.971-7.778-18.296-.001-2.973 7.783c-.575 1.631-2.488 2.646-4.99 2.646a9.155 9.155 0 0 1-3.814-.828c-1.654-.763-3.244-2.861-1.422-8.52l14.352-37.776c1.011-2.873 4.082-5.833 7.99-5.922 3.919.088 6.99 3.049 8.003 5.928l14.346 37.759c1.826 5.672.236 7.771-1.418 8.532a9.176 9.176 0 0 1-3.814.827c-.001 0 0 0 0 0zm-11.119-21.056L106 108.466l-5.993 17.025h11.986zM138 145.75c-3.171 0-5.75-2.468-5.75-5.5V99.5c0-3.309 2.748-6 6.125-6s6.125 2.691 6.125 6v35.25h12.75c3.171 0 5.75 2.468 5.75 5.5s-2.579 5.5-5.75 5.5H138zM171.334 146.547c-3.309 0-6-2.691-6-6V99.5c0-3.309 2.691-6 6-6s6 2.691 6 6v12.896l16.74-16.74c.861-.861 2.044-1.335 3.328-1.335 1.498 0 3.002.646 4.129 1.772 1.051 1.05 1.678 2.401 1.764 3.804.087 1.415-.384 2.712-1.324 3.653l-13.673 13.671 14.769 19.566a5.951 5.951 0 0 1 1.152 4.445 5.956 5.956 0 0 1-2.328 3.957 5.94 5.94 0 0 1-3.609 1.211 5.953 5.953 0 0 1-4.793-2.385l-14.071-18.644-2.082 2.082v13.091a6.01 6.01 0 0 1-6.002 6.003z"/></svg>
|
After Width: | Height: | Size: 1.7 KiB |
@ -17,7 +17,7 @@ import {
|
||||
Rating,
|
||||
Tooltip,
|
||||
Grid,
|
||||
Card,
|
||||
Card
|
||||
// alpha,
|
||||
// Divider
|
||||
} from '@mui/material';
|
||||
@ -52,6 +52,8 @@ import { MdContentCopy } from 'react-icons/md';
|
||||
import { LiaShippingFastSolid } from 'react-icons/lia';
|
||||
import { MdLockOutline } from 'react-icons/md';
|
||||
import { FaRegStar } from 'react-icons/fa';
|
||||
import Image from 'next/image';
|
||||
import Kakao from '../../../../../public/images/KakaoTalk_logo.svg';
|
||||
// import { TbMessage } from 'react-icons/tb';
|
||||
// import { MdOutlineShoppingBasket } from 'react-icons/md';
|
||||
// import { FiShoppingCart } from 'react-icons/fi';
|
||||
@ -411,7 +413,7 @@ export default function ProductDetailsSumary({ ...props }) {
|
||||
</Button>
|
||||
)} */}
|
||||
|
||||
<Stack direction="row" spacing={0.5} justifyContent={'center'}>
|
||||
<Stack direction="row" spacing={0.5} justifyContent={'center'} alignItems={'center'}>
|
||||
<Tooltip title="Copy Prooduct URL">
|
||||
<IconButton
|
||||
aria-label="copy"
|
||||
@ -432,6 +434,16 @@ export default function ProductDetailsSumary({ ...props }) {
|
||||
</IconButton>
|
||||
</WhatsappShareButton>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
title="카카오톡"
|
||||
onClick={() => {
|
||||
window?.open('http://pf.kakao.com/_xlxhIxbn/chat');
|
||||
}}
|
||||
>
|
||||
<IconButton sx={{ p: '8px' }}>
|
||||
<Image src={Kakao} alt="카카오톡" width={24} height={24} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
{/* <Tooltip title="Share on Facebook">
|
||||
<FacebookShareButton url={window?.location.href || ''}>
|
||||
<IconButton sx={{ color: '#1373EC' }} aria-label="facebook">
|
||||
|
@ -10,13 +10,12 @@ import Typography from '@mui/material/Typography';
|
||||
import SearchIcon from '@mui/icons-material/Search';
|
||||
import TextField from '@mui/material/TextField';
|
||||
import Skeleton from '@mui/material/Skeleton';
|
||||
import { InputAdornment, Stack, Button, Modal, IconButton } from '@mui/material';
|
||||
import { InputAdornment, Stack, Button } from '@mui/material';
|
||||
import MenuList from '@mui/material/MenuList';
|
||||
import MenuItem from '@mui/material/MenuItem';
|
||||
import ListItemIcon from '@mui/material/ListItemIcon';
|
||||
import CircularProgress from '@mui/material/CircularProgress';
|
||||
import Divider from '@mui/material/Divider';
|
||||
import CloseRoundedIcon from '@mui/icons-material/CloseRounded';
|
||||
|
||||
// components
|
||||
import NoDataFound from 'src/illustrations/dataNotFound';
|
||||
@ -26,68 +25,12 @@ import FormControl from '@mui/material/FormControl';
|
||||
import Select from '@mui/material/Select';
|
||||
import { useCurrencyConvert } from 'src/hooks/convertCurrency';
|
||||
import { useCurrencyFormatter } from 'src/hooks/formatCurrency';
|
||||
const axios = require("axios");
|
||||
const fs = require("fs");
|
||||
const FormData = require('form-data');
|
||||
// api
|
||||
import * as api from 'src/services';
|
||||
|
||||
const axios = require('axios');
|
||||
|
||||
const getImageUrl = async (ids) => {
|
||||
const requestOptions = {
|
||||
method: 'GET',
|
||||
redirect: 'follow'
|
||||
};
|
||||
|
||||
try {
|
||||
const responses = await Promise.all(
|
||||
ids.map(async (id) => {
|
||||
const response = await fetch(
|
||||
`https://api.roboflow.com/picup/picup/images/${id}?api_key=s9OJq0UPljSqkPsJY6xP`,
|
||||
requestOptions
|
||||
);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error fetching image for ID: ${id}, Status: ${response.status}`);
|
||||
}
|
||||
return response.json(); // JSON 응답 반환
|
||||
})
|
||||
);
|
||||
|
||||
return responses; // 모든 이미지 정보를 배열로 반환
|
||||
} catch (error) {
|
||||
console.error('Error fetching image URLs:', error);
|
||||
return null; // 오류 발생 시 null 반환
|
||||
}
|
||||
};
|
||||
|
||||
const searchImages = async (imageBase64) => {
|
||||
const myHeaders = new Headers();
|
||||
myHeaders.append('Content-Type', 'application/json');
|
||||
|
||||
const raw = JSON.stringify({
|
||||
like_image: 'MV09CPgMSn9uhQ5D2nl5',
|
||||
limit: 3,
|
||||
in_dataset: true
|
||||
});
|
||||
|
||||
const requestOptions = {
|
||||
method: 'POST',
|
||||
headers: myHeaders,
|
||||
body: raw,
|
||||
redirect: 'follow'
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
'https://api.roboflow.com/picup/picup/search?api_key=s9OJq0UPljSqkPsJY6xP',
|
||||
requestOptions
|
||||
);
|
||||
const result = await response.json();
|
||||
return result; // 반환 추가
|
||||
} catch (error) {
|
||||
console.error('Error fetching images:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
Search.propTypes = {
|
||||
onClose: PropTypes.func.isRequired,
|
||||
mobile: PropTypes.bool.isRequired
|
||||
@ -116,9 +59,6 @@ export default function Search({ ...props }) {
|
||||
|
||||
const router = useRouter();
|
||||
const [search, setSearch] = React.useState('');
|
||||
const [image, setImage] = React.useState(null);
|
||||
const [imagesResultID, setImagesResultID] = React.useState(null);
|
||||
const [roboFlowUrlLists, setRoboFlowUrlLists] = React.useState([]);
|
||||
|
||||
const { data: filters, isLoading: filtersLoading } = useQuery(['get-search-filters'], () => api.getSearchFilters());
|
||||
const { mutate, isLoading } = useMutation('search', api.search, {
|
||||
@ -171,44 +111,57 @@ export default function Search({ ...props }) {
|
||||
}
|
||||
};
|
||||
|
||||
// 파일 선택 시 호출되는 함수
|
||||
// const handleFileChange = (event) => {
|
||||
// const file = event.target.files?.[0];
|
||||
// if (file) {
|
||||
// console.log('Selected File:', file);
|
||||
|
||||
// // 예: 파일을 서버에 업로드하거나 처리
|
||||
// const reader = new FileReader();
|
||||
// reader.onload = () => {
|
||||
// console.log('Image Preview URL:', reader.result);
|
||||
// };
|
||||
// reader.readAsDataURL(file);
|
||||
// }
|
||||
// };
|
||||
|
||||
const handleFileChange = async (event) => {
|
||||
const file = event.target.files?.[0];
|
||||
const file = event.target.files[0];
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onloadend = async () => {
|
||||
const base64Image = reader.result.split(',')[1]; // base64 변환 후 접두사 제거
|
||||
setImage(reader.result);
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
const formData = new FormData();
|
||||
formData.append('name', file.name);
|
||||
formData.append('file', file);
|
||||
formData.append('split', 'train');
|
||||
|
||||
console.log(formData)
|
||||
|
||||
axios({
|
||||
method: 'POST',
|
||||
url: 'https://api.roboflow.com/dataset/picup/upload',
|
||||
params: {
|
||||
api_key: 's9OJq0UPljSqkPsJY6xP'
|
||||
},
|
||||
data: formData,
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data"
|
||||
}
|
||||
};
|
||||
|
||||
const objectDetect = async (image) => {
|
||||
try {
|
||||
const result = await searchImages(image);
|
||||
|
||||
// id 배열 추출
|
||||
const imageIds = result.results.map((r) => r.id);
|
||||
|
||||
// 배열을 한 번에 저장
|
||||
setImagesResultID(imageIds);
|
||||
|
||||
console.log('Image IDs:', imageIds); // 디버깅 출력
|
||||
} catch (error) {
|
||||
console.error('Error in image search:', error);
|
||||
}
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
if (imagesResultID && imagesResultID.length > 0) {
|
||||
getImageUrl(imagesResultID).then((url) => {
|
||||
setRoboFlowUrlLists(url);
|
||||
}).finally(() => {
|
||||
setImage(null)
|
||||
})
|
||||
.then(function (response) {
|
||||
console.log(response.data);
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error.message);
|
||||
});
|
||||
}
|
||||
}, [imagesResultID]);
|
||||
};
|
||||
|
||||
const handleSubmit = (event) => {
|
||||
event.preventDefault();
|
||||
if (fileInputRef.current && fileInputRef.current.files.length > 0) {
|
||||
handleFileChange({ target: { files: fileInputRef.current.files } });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
@ -255,8 +208,9 @@ export default function Search({ ...props }) {
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Button variant="contained" sx={{ width: '100%', borderRadius: 0 }} onClick={handleImageSearch}>
|
||||
이미지 검색
|
||||
<form style={{ display: 'flex' }} onSubmit={handleSubmit}>
|
||||
<Button variant="contained" sx={{ width: '80%', borderRadius: 0 }} onClick={handleImageSearch}>
|
||||
이미지 찾기
|
||||
</Button>
|
||||
<input
|
||||
type="file"
|
||||
@ -266,6 +220,10 @@ export default function Search({ ...props }) {
|
||||
onChange={handleFileChange}
|
||||
style={{ display: 'none' }}
|
||||
/>
|
||||
<button type="submit" style={{ width: '20%', height: '40px', border: '0' }}>
|
||||
검색
|
||||
</button>
|
||||
</form>
|
||||
<Stack gap={1} direction="row" p={1}>
|
||||
<FormControl fullWidth>
|
||||
<LabelStyle component={'label'} htmlFor="shops">
|
||||
@ -422,13 +380,13 @@ export default function Search({ ...props }) {
|
||||
{isLoading ? <Skeleton variant="text" width="200px" /> : product.category}
|
||||
</Typography>
|
||||
</div>
|
||||
{/* <Typography variant="subtitle1" color="text.primary" noWrap>
|
||||
<Typography variant="subtitle1" color="text.primary" noWrap>
|
||||
{isLoading ? (
|
||||
<Skeleton variant="text" width="100px" />
|
||||
) : (
|
||||
fCurrency(cCurrency(product.priceSale))
|
||||
)}
|
||||
</Typography> */}
|
||||
</Typography>
|
||||
</Stack>
|
||||
</ListItemText>
|
||||
</MenuItem>
|
||||
@ -437,63 +395,6 @@ export default function Search({ ...props }) {
|
||||
</>
|
||||
)}
|
||||
</Box>{' '}
|
||||
{roboFlowUrlLists &&
|
||||
roboFlowUrlLists.map((i, index) => (
|
||||
<MenuList
|
||||
key={`search-by-images-${i.image.annotation.key}-${index.toString()}`}
|
||||
sx={{
|
||||
pt: 0,
|
||||
mt: 1,
|
||||
overflow: 'auto',
|
||||
px: 1,
|
||||
li: {
|
||||
borderRadius: '8px',
|
||||
border: `1px solid transparent`,
|
||||
'&:hover, &.Mui-focusVisible, &.Mui-selected ': {
|
||||
border: (theme) => `1px solid ${theme.palette.primary.main}`,
|
||||
bgcolor: (theme) => alpha(theme.palette.primary.main, 0.16),
|
||||
h6: {
|
||||
color: 'primary.main'
|
||||
}
|
||||
},
|
||||
'&.active': {
|
||||
border: (theme) => `1px solid ${theme.palette.primary.main}`,
|
||||
bgcolor: (theme) => alpha(theme.palette.primary.main, 0.16),
|
||||
h6: {
|
||||
color: 'primary.main'
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
autoFocusItem={!focus}
|
||||
>
|
||||
<MenuItem>
|
||||
<ListItemIcon>
|
||||
<img
|
||||
alt="이미지"
|
||||
src={i.image.urls.original}
|
||||
style={{ width: '40px', height: '40px', borderRadius: '100%' }}
|
||||
/>
|
||||
</ListItemIcon>
|
||||
<ListItemText>
|
||||
<Stack direction="row" gap={1} alignItems={'center'} justifyContent={'space-between'}>
|
||||
<div>
|
||||
<Typography variant="subtitle1" color="text.primary" noWrap>
|
||||
Object Data Set {index}
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary" noWrap>
|
||||
{i.image.tags.map((i) => {
|
||||
return i;
|
||||
})}
|
||||
{` `}
|
||||
<span>{i.image.r * 100}%</span>
|
||||
</Typography>
|
||||
</div>
|
||||
</Stack>
|
||||
</ListItemText>
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
))}
|
||||
{multiSelect && (
|
||||
<Stack gap={1} direction={'row'} p={1} justifyContent={'end'}>
|
||||
<Button variant="outlined" color="primary" onClick={() => handleSave(selectedProducts)}>
|
||||
@ -505,42 +406,6 @@ export default function Search({ ...props }) {
|
||||
</Stack>
|
||||
)}
|
||||
</Box>
|
||||
{/* 이미지 미리보기 렌더링 */}
|
||||
{image && (
|
||||
<Modal
|
||||
open={image}
|
||||
sx={{ height: '100vh', width: '100vw', display: 'flex', justifyContent: 'center', alignItems: 'center' }}
|
||||
>
|
||||
<Box sx={{ position: 'relative' }}>
|
||||
<Box mt={2} display="flex" justifyContent="center">
|
||||
<IconButton
|
||||
sx={{ position: 'absolute;', right: 0, top: 10, mixBlendMode: 'difference' }}
|
||||
onClick={() => {
|
||||
setImage(null);
|
||||
}}
|
||||
>
|
||||
<CloseRoundedIcon fontSize="small" />
|
||||
</IconButton>
|
||||
<img
|
||||
src={image}
|
||||
style={{
|
||||
maxWidth: '100%',
|
||||
maxHeight: '300px',
|
||||
borderRadius: '8px',
|
||||
border: '1px solid #ddd'
|
||||
}}
|
||||
/>
|
||||
|
||||
<Button
|
||||
sx={{ position: 'absolute', bottom: 0, left: '50%', transform: 'translate(-50%, 0px)' }}
|
||||
onClick={() => objectDetect(image)}
|
||||
>
|
||||
이미지 상품 검색
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</Modal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user