diff --git a/.env.local b/.env.local
new file mode 100644
index 0000000..a0700c8
--- /dev/null
+++ b/.env.local
@@ -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
\ No newline at end of file
diff --git a/package.json b/package.json
index eff8121..e1cad45 100644
--- a/package.json
+++ b/package.json
@@ -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",
diff --git a/src/.aws/config b/src/.aws/config
new file mode 100644
index 0000000..4e9dd40
--- /dev/null
+++ b/src/.aws/config
@@ -0,0 +1,2 @@
+[default]
+region = us-east-2
\ No newline at end of file
diff --git a/src/.aws/credentials b/src/.aws/credentials
new file mode 100644
index 0000000..e7efdf2
--- /dev/null
+++ b/src/.aws/credentials
@@ -0,0 +1,3 @@
+[default]
+aws_access_key_id = AKIAXWYG7NAVSRIQFHK2
+aws_secret_access_key = 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
diff --git a/src/components/App.tsx b/src/components/App.tsx
index e118002..1a87d9e 100644
--- a/src/components/App.tsx
+++ b/src/components/App.tsx
@@ -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 (
diff --git a/src/components/SearchBar.tsx b/src/components/SearchBar.tsx
index 4553cdf..62c41a0 100644
--- a/src/components/SearchBar.tsx
+++ b/src/components/SearchBar.tsx
@@ -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,
@@ -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];
@@ -37,29 +33,19 @@ export const SearchBar = () => {
const { vendor, useComponents } = useSearchStore((state) => {
return { vendor: state.vendor, useComponents: state.useComponents };
});
- debugger;
- const rootRef = React.useRef(null);
const fileInputRef = useRef(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) => {
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);
@@ -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,
},
};
@@ -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",
@@ -173,12 +146,10 @@ export const SearchBar = () => {
onKeyPress={handleKeyPress}
className={styles.input}
/>
- {/* The icon is positioned absolutely within the relative inputWrapper */}
-
- {/* The input is hidden with opacity 0 and position absolute. This is what actually does the uplpad image functionality */}
+ /> */}
{
onChange={getImageComponents}
/>
- {/* Add a menu dropdown here, where you have multiple options and a scroller if necessary here, that says "wayfair search" */}
>
diff --git a/src/helpers/aws.ts b/src/helpers/aws.ts
index 7de2040..a9c3c37 100644
--- a/src/helpers/aws.ts
+++ b/src/helpers/aws.ts
@@ -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 = {
@@ -45,6 +50,7 @@ const uploadToS3 = async (base64Data: string) => {
ContentType: 'image/jpeg'
};
+ console.log(s3)
try {
await s3.upload(params).promise();
return uniqueKey;
diff --git a/src/helpers/contexts.tsx b/src/helpers/contexts.tsx
new file mode 100644
index 0000000..5f41f40
--- /dev/null
+++ b/src/helpers/contexts.tsx
@@ -0,0 +1,5 @@
+import React from "react";
+
+import { createContext, useState } from "react";
+
+export const LoadingContext = createContext(false);
diff --git a/src/helpers/index.ts b/src/helpers/index.ts
index 65bd1bc..be8b9ca 100644
--- a/src/helpers/index.ts
+++ b/src/helpers/index.ts
@@ -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';
\ No newline at end of file
+export { fetchFromS3, uploadToS3 } from './aws';
+export { LoadingContext } from './contexts';
\ No newline at end of file
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index df05b52..6864d3a 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -1,4 +1,5 @@
import React from "react";
+import * as dotenv from "dotenv";
import type { AppProps } from "next/app";
import { Box } from "@mui/system";
@@ -8,6 +9,7 @@ import "../styles/global.css";
import { NavBar, Footer } from "../components";
+dotenv.config();
function MyApp({ Component, pageProps }: AppProps) {
return (
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index 9564b2b..391c917 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -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 (
+
+
+ Waking up the model...
+
+ );
+ }
return (
diff --git a/src/pages/offline.tsx b/src/pages/offline.tsx
new file mode 100644
index 0000000..fae7e7f
--- /dev/null
+++ b/src/pages/offline.tsx
@@ -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 (
+
+
+ Thank you for visiting our projects page! You can view the code for the
+ project here{" "}
+ (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.
+
+
+
+
+
+ Above is a demo of what the website looked like while online.
+
+