Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env.local
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
NEXT_PUBLIC_AWS_API_ENDPOINT=https://simple-api-it6x.onrender.com
OBVIOUS_AWS_KEY=AKIAXWYG7NAVSRIQFHK2
0BVIUOS_AWS_SECRET=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
OBVIOUS_AWS_REGION=us-east-2
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"private": true,
"dependencies": {
"@auth0/nextjs-auth0": "^3.1.0",
"@aws-sdk/client-s3": "^3.540.0",
"@emotion/react": "^11.11.1",
"@emotion/server": "^11.11.0",
"@emotion/styled": "^11.11.0",
Expand Down
2 changes: 2 additions & 0 deletions src/.aws/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[default]
region = us-east-2
3 changes: 3 additions & 0 deletions src/.aws/credentials
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[default]
aws_access_key_id = AKIAXWYG7NAVSRIQFHK2
aws_secret_access_key = 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
4 changes: 3 additions & 1 deletion src/components/App.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// pages/index.tsx
import React from "react";
import { RotatingCarousel, SearchBar } from "../components";

import styles from "../styles/App.module.css";

import { RotatingCarousel, SearchBar } from "../components";

const App = () => {
return (
<div className={styles.App}>
Expand Down
76 changes: 23 additions & 53 deletions src/components/SearchBar.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
import React, { use } from "react";
import React, { useState, useRef } from "react";
import AddAPhotoIcon from "@mui/icons-material/AddAPhoto";
// import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";

import { useState, useRef } from "react";
import { useRouter } from "next/router";
// import { Box, Button, Modal, Typography, Checkbox } from "@mui/material";
// import { MenuProps } from "@mui/material/Menu";

import SearchModal from "./Modal";
import styles from "../styles/SearchBar.module.css";

// import { ImageCanvas } from "./ImageUploaderCanvas";
import {
uploadToS3,
getJsonResponse,
Expand All @@ -22,7 +14,11 @@ import { useSearchStore } from "../lib/searchStore";
import VendorMenu from "./VendorMenu";
import { config } from "../../config.json";

type websiteStatus = "Online" | "Offline";

const STATUS: websiteStatus = "Offline";
const configContents: configJson = config;
// @ts-ignore
const ENDPOINT =
// @ts-ignore
configContents.api.api_endpoints[configContents.api.current_version];
Expand All @@ -37,29 +33,19 @@ export const SearchBar = () => {
const { vendor, useComponents } = useSearchStore((state) => {
return { vendor: state.vendor, useComponents: state.useComponents };
});
debugger;

const rootRef = React.useRef<HTMLDivElement>(null);
const fileInputRef = useRef<HTMLInputElement>(null);

React.useEffect(() => {
debugger;
console.log(vendor, useComponents);
// Wake up the model when we first load this page.
// dont fetch components here, just send a get request to wake up the model
// fetch(ENDPOINT + "/wakeup");
}, []);

const handleKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Enter") {
const routeObject: routeInput = {
pathname: "/results",
pathname: STATUS !== "Offline" ? "/results" : "/offline",
query: {
q: input,
q: STATUS !== "Offline" ? input : "",
imageSearch: false,
imageName: null,
component: selectedChoice,
vendor: vendor,
component: selectedChoice || "",
vendor: vendor || "",
},
};
router.push(routeObject);
Expand All @@ -68,21 +54,20 @@ export const SearchBar = () => {

const handleSubmitButton = async () => {
if (!imageSrc) return;
const base64Image = imageSrc.split(",")[1];
const key = await uploadToS3(base64Image);

// Convert to base64 actually
const encodedChoice = selectedChoice !== "All" ? selectedChoice : null;

console.log(key);
let base64Image = "";
let key: string | null = "";
if (STATUS !== "Offline") {
base64Image = imageSrc.split(",")[1];
key = await uploadToS3(base64Image);
}

const routeObject: routeInput = {
pathname: "/results",
pathname: STATUS !== "Offline" ? "/results" : "/offline",
query: {
q: null,
imageSearch: true,
imageName: config.s3_bucket_prefix + key,
component: encodedChoice,
component: selectedChoice !== "All" ? selectedChoice : null,
vendor: vendor,
},
};
Expand All @@ -91,42 +76,30 @@ export const SearchBar = () => {
};

const handleButtonClick = () => {
if (fileInputRef.current) {
if (fileInputRef.current && STATUS !== "Offline") {
fileInputRef.current.click();
}
};

const getImageComponents = async () => {
// This function loads in the image, and then also sets the imageSrc to the right src so the canvas can load the image.
// Furthermore, it obtains the image components for a given image, sending the base64 encoding of the image as part of a json payload.
// Then, we can provide the options to the users to select from.
console.log(useComponents);
useSearchStore.setState({ useComponents: !useComponents });
setUpload(true);

const fileInput = fileInputRef.current;
if (!fileInput || !fileInput.files || fileInput.files.length === 0) {
return;
}

const imageFile = fileInput.files[0];

// Convert the image to a base64 string
const reader = new FileReader();
reader.readAsDataURL(imageFile);
reader.onload = async () => {
const image = reader.result as string;
//ignore the type error here, it is a known issue
setImageSrc(image); // Set the image source for canvas
setImageSrc(image);

if (
typeof image === "string" &&
ENDPOINT !== undefined &&
useComponents &&
false
useComponents
) {
console.log(useComponents);
// Convert the image to base64 actually
const base64Image = image.split(",")[1];
const request: searchRequestPayload = {
requestType: "POST",
Expand Down Expand Up @@ -173,12 +146,10 @@ export const SearchBar = () => {
onKeyPress={handleKeyPress}
className={styles.input}
/>
{/* The icon is positioned absolutely within the relative inputWrapper */}
<AddAPhotoIcon
className={styles.AddAPhotoIcon} /* Use the class for styling */
{/* <AddAPhotoIcon
className={styles.AddAPhotoIcon}
onClick={handleButtonClick}
/>
{/* The input is hidden with opacity 0 and position absolute. This is what actually does the uplpad image functionality */}
/> */}
<input
type="file"
ref={fileInputRef}
Expand All @@ -187,7 +158,6 @@ export const SearchBar = () => {
onChange={getImageComponents}
/>
</div>
{/* Add a menu dropdown here, where you have multiple options and a scroller if necessary here, that says "wayfair search" */}
<VendorMenu />
</div>
</>
Expand Down
20 changes: 13 additions & 7 deletions src/helpers/aws.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import AWS from "aws-sdk";
import AWS from 'aws-sdk'
import * as dotenv from 'dotenv';

import { v4 as uuidv4 } from "uuid";

const s3 = new AWS.S3({
accessKeyId: "AKIAXWYG7NAVSRIQFHK2",
secretAccessKey: "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",
region: "us-east-2",
});


dotenv.config();

const s3 = new AWS.S3();

s3.config.update({
region: 'us-east-2',
accessKeyId: process.env.OBVIOUS_AWS_KEY ?? '',
secretAccessKey: process.env.OBVIOUS_AWS_SECRET ?? '',
})

const fetchFromS3 = async (key: string) => {
const params = {
Expand Down Expand Up @@ -45,6 +50,7 @@ const uploadToS3 = async (base64Data: string) => {
ContentType: 'image/jpeg'
};

console.log(s3)
try {
await s3.upload(params).promise();
return uniqueKey;
Expand Down
5 changes: 5 additions & 0 deletions src/helpers/contexts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import React from "react";

import { createContext, useState } from "react";

export const LoadingContext = createContext(false);
3 changes: 2 additions & 1 deletion src/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export type {searchRequestPayload, routeInput, configJson} from './backendTypes';
export type { Item, searchBoxInput, modalInput } from './frontendTypes';
export { getJsonResponse } from './api';
export { fetchFromS3, uploadToS3 } from './aws';
export { fetchFromS3, uploadToS3 } from './aws';
export { LoadingContext } from './contexts';
2 changes: 2 additions & 0 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from "react";
import * as dotenv from "dotenv";

import type { AppProps } from "next/app";
import { Box } from "@mui/system";
Expand All @@ -8,6 +9,7 @@ import "../styles/global.css";

import { NavBar, Footer } from "../components";

dotenv.config();
function MyApp({ Component, pageProps }: AppProps) {
return (
<UserProvider>
Expand Down
46 changes: 46 additions & 0 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,53 @@
import React from "react";
import ReactLoading from "react-loading";

import { App, Logo } from "../components";

import config from "../../config.json";
import { Typography } from "@mui/material";

const ENDPOINT =
// @ts-ignore
config.config.api.api_endpoints[config.config.api.current_version];

const Home = () => {
const [loading, setLoading] = React.useState(true);

const makeWakeUpRequest = async () => {
await fetch(ENDPOINT + "/wakeup");
};

React.useEffect(() => {
// Wake up the model when we first load this page.
// dont fetch components here, just send a get request to wake up the model
// makeWakeUpRequest();
// Wait a random amount of seconds, between 2-3 seconds.
setTimeout(() => {
setLoading(false);
}, Math.random() * 1000 + 2000);
}, []);

if (loading) {
return (
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "100vh",
flexDirection: "column",
}}
>
<ReactLoading
type="spinningBubbles"
color="#5900C9"
height={200}
width={100}
/>
<Typography variant="h3">Waking up the model...</Typography>
</div>
);
}
return (
<div>
<Logo />
Expand Down
45 changes: 45 additions & 0 deletions src/pages/offline.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Create view that just says "Thank you for visiting our page! You can view the code for the project at _______, but we have stopped working on this to cut from monthly model and hosting costs." Then add a portion with a video that shows a demo of the website, and under it say "here is a demo of what the website looked like while online."
import React from "react";

import { Link, Typography } from "@mui/material";

export default function Offline() {
return (
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
flexDirection: "column",
gap: "40px",
marginInline: "20%",
marginBlock: "10%",
}}
>
<Typography variant="h5">
Thank you for visiting our projects page! You can view the code for the
project <Link href="https://github.com/ObviousAI/website">here</Link>{" "}
(if you want to see the code for the actual models and embeddings, reach
me out on linkedin), but we have stopped working on this to cut from
monthly model and hosting costs." Then add a portion with a video that
shows a demo of the website, and under it say "here is a demo of what
the website looked like while online.
</Typography>
<div>
<iframe
style={{
width: "800px",
height: "600px",
border: "4px",
}}
allowFullScreen={true}
src="https://drive.google.com/file/d/16VNhXspVTUbQQlekmj25_BOE-ga4c1Ez/preview"
allow="autoplay"
></iframe>
</div>
<Typography variant="h5">
Above is a demo of what the website looked like while online.
</Typography>
</div>
);
}
6 changes: 0 additions & 6 deletions src/pages/results.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,6 @@ type ResultsProps = {
searchQuery: string;
};

const s3 = new AWS.S3({
accessKeyId: "AKIAXWYG7NAVSRIQFHK2",
secretAccessKey: "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",
region: "us-east-2",
});

const Results: React.FC<ResultsProps> = ({ items, searchQuery }) => {
const [validItems, setValidItems] = React.useState<Item[]>([]);
const vendor = useSearchStore((state) => state.vendor);
Expand Down