10 Commits

Author SHA1 Message Date
57ab55bc45 add gallery 2023-09-26 21:01:18 -05:00
691ae1e3f9 add gallery 2023-09-26 20:50:20 -05:00
6437bc7371 margin 2023-09-26 19:59:58 -05:00
251a9c7210 Merge branch 'feat/waterfallpic' 2023-09-26 19:54:04 -05:00
4695dea933 add waterfall pic wall 2023-09-26 19:50:08 -05:00
086b2087b1 Merge branch 'main' into feat/waterfallpic 2023-09-26 19:42:34 -05:00
84e7889653 add waterfall pic wall 2023-09-26 19:42:02 -05:00
2300d2bbf3 fix color 2023-09-19 20:53:38 -05:00
118c39afb8 error fixed 2023-09-19 20:43:26 -05:00
b08e0e9b4e updated projects 2023-09-19 20:29:24 -05:00
32 changed files with 444 additions and 101 deletions

108
src/assets/data/gallery.js Normal file
View File

@ -0,0 +1,108 @@
import pic0 from "../pics/gallery/IMG_0796.jpg";
import pic1 from "../pics/gallery/IMG_6390.jpg";
import pic2 from "../pics/gallery/IMG_6392.jpg";
import pic3 from "../pics/gallery/IMG_6393.jpg";
import pic4 from "../pics/gallery/IMG_8547.jpg";
import pic5 from "../pics/gallery/IMG_8548.jpg";
import pic6 from "../pics/gallery/IMG_8549.jpg";
import pic7 from "../pics/gallery/JSDC2011.jpg";
import pic8 from "../pics/gallery/JSDC2012.jpg";
import pic9 from "../pics/gallery/dsc_0001.jpg";
import pic10 from "../pics/gallery/dsc_0003.jpg";
import pic11 from "../pics/gallery/dsc_0235.jpg";
import pic12 from "../pics/gallery/dsc_0238.jpg";
import pic13 from "../pics/gallery/dsc_0243.jpg";
import pic14 from "../pics/gallery/jsdc2015_001.jpg";
import pic15 from "../pics/gallery/jsdc2015_002.jpg";
import pic16 from "../pics/gallery/jsdc2015_003.jpg";
const gallery = {
pic: [
{
title: "",
content: "",
img: pic0,
},
{
title: "",
content: "",
img: pic1,
},
{
title: "",
content: "",
img: pic2,
},
{
title: "",
content: "",
img: pic3,
},
{
title: "",
content: "",
img: pic4,
},
{
title: "",
content: "",
img: pic5,
},
{
title: "",
content: "",
img: pic6,
},
{
title: "",
content: "",
img: pic7,
},
{
title: "",
content: "",
img: pic8,
},
{
title: "",
content: "",
img: pic9,
},
{
title: "",
content: "",
img: pic10,
},
{
title: "",
content: "",
img: pic11,
},
{
title: "",
content: "",
img: pic12,
},
{
title: "",
content: "",
img: pic13,
},
{
title: "",
content: "",
img: pic14,
},
{
title: "",
content: "",
img: pic15,
},
{
title: "",
content: "",
img: pic16,
}
],
};
export default gallery;

View File

@ -14,61 +14,66 @@ import ma from "../pics/matchlock.jpg";
const projects = {
active: [
{
title: "Fenrir",
content: `Fenrir is a two-wheeled gravity-drive robot. Fenrir's unique design makes it a very fast and agile robot, but also an interesting challenge to control. You can find the current controller code at our github repo: https://github.com/illinoistechrobotics/fenrir.`,
img: fenrir,
},
{
title: "Roslund",
content: `Roslund is a simple frame robot with mechanum drive. Mechanum wheels have rollers at a 45° angle to the wheel plane, which allows the robot to have omnidirectional movement. Roslund was the winner of MRDC in 2010 and 2011. Roslund was also awarded the best design award by Grant Imahara (from the Mythbusters) a couple years back.`,
img: roslund,
},
{
title: "Goliath",
title: "⏩ Goliath",
content: `Golaith is designed to effectively compete in the annual MRDC. Goliath is based on a relatively simple drive base consisting of a basic square steel frame, 2 large drive wheels powered by 3HP Ampflow Magmotors and two steel ball casters. The simplicity of this design makes Goliath a very durable and reliable robot that is able to easily withstand encounters with other robots and course obstacles. In addition, this robot was designed such that the center of mass is low to the ground and as close as possible to the drive wheels which, when coupled with its powerful drivetrain, allows it to easily climb and descend relatively steep inclines as well as move very slowly and precisely when necessary. Overall, these design features enable Goliath to reliably perform many competition tasks with minimal impact from any obstacles encountered along the way.`,
img: goliath,
sub: "💪"
},
{
title: "Icarus",
content: `Icarus is a quadcopter (a four-rotor helicopter) that is able to lift more weight and is more agile than a standard helicopter. But these benefits come at a cost of stability and require many electronic sensors to maintain stable flight. We are currently working on an RC car to tether to Icarus toact as a manipulator. This way it can pull Icarus close to balls without blowing them away and pick them up. The manipulator will be used during competitions such as MRDC.`,
img: icarus,
title: "⏩ Modulus",
content: `Modulus uses a crab drive propulsion system and is primarily based off the FIRST robotics kit. A crab drive system consists of a 4 wheel base where each wheel can rotate independently without turning the entire body. This can be very useful for competitions where mobility is important such as MRDC.`,
img: Modulus,
sub: "🧠"
},
{
title: "C-Force",
content: `C-Force is our award winning pumpkin launcher which uses centripetal force to launch pumpkins. A 5HP, 3 phase industrial motor and variable frequency drive is used to spin up the launching arm to approximately 200 RPM and then a second custom designed control system releases the pumpkin on command from a laptop connected via WiFi. There is an optical sensor on the launcher providing input to the controller to signal when the arm is at the proper angle to release the pumpkin. This allows the launcher to consistently throw the pumpkin at the ideal launch angle to acheive the maximum possible distance.`,
img: mach2,
},
{
title: "Osiris",
content: `A full body spinner prototype design with a hexagonal pyramid shell. Used MPU-6050 Gyroscope/Accelerameter package, Yumo/Omron rotary encoders, and I2C communication between Arduino Unos for PID and translational drift control. Required a soldered interface board between Open Source Motor Controller (OSMC) and Arduino Mega consisting of a L7805 voltage regulator, line driver, and optocoupler packages to provide current and signal isolation. Each of 3 Ampflow magmotors has a peak of 4.6 horsepower and draws 150 Amps at full load. Future improvements include fabricating metal body and shell, and integrating the OSMC interface board into a PCB with motor controller components that can operate at 48 V.`,
img: osiris,
},
title: "⏩ Roslund",
content: `Roslund is a simple frame robot with mechanum drive. Mechanum wheels have rollers at a 45° angle to the wheel plane, which allows the robot to have omnidirectional movement. Roslund was the winner of MRDC in 2010 and 2011. Roslund was also awarded the best design award by Grant Imahara (from the Mythbusters) a couple years back.`,
img: roslund,
sub: "✨"
}
],
inactive: [
{
title: "Modulus",
content: `Modulus uses a crab drive propulsion system and is primarily based off the FIRST robotics kit. A crab drive system consists of a 4 wheel base where each wheel can rotate independently without turning the entire body. This can be very useful for competitions where mobility is important such as MRDC.`,
img: Modulus
title: "⏩ Fenrir",
content: `Fenrir is a two-wheeled gravity-drive robot. Fenrir's unique design makes it a very fast and agile robot, but also an interesting challenge to control. You can find the current controller code at our github repo: https://github.com/illinoistechrobotics/fenrir.`,
img: fenrir,
sub: "🔜"
},
{
title: 'Roomba',
title: "⏩ C-Force",
content: `C-Force is our award winning pumpkin launcher which uses centripetal force to launch pumpkins. A 5HP, 3 phase industrial motor and variable frequency drive is used to spin up the launching arm to approximately 200 RPM and then a second custom designed control system releases the pumpkin on command from a laptop connected via WiFi. There is an optical sensor on the launcher providing input to the controller to signal when the arm is at the proper angle to release the pumpkin. This allows the launcher to consistently throw the pumpkin at the ideal launch angle to acheive the maximum possible distance.`,
img: mach2,
sub: "🔜"
},
{
title: "⏩ Icarus",
content: `Icarus is a quadcopter (a four-rotor helicopter) that is able to lift more weight and is more agile than a standard helicopter. But these benefits come at a cost of stability and require many electronic sensors to maintain stable flight. We are currently working on an RC car to tether to Icarus toact as a manipulator. This way it can pull Icarus close to balls without blowing them away and pick them up. The manipulator will be used during competitions such as MRDC.`,
img: icarus,
sub: "🪁"
},
{
title: "⏩ Osiris",
content: `A full body spinner prototype design with a hexagonal pyramid shell. Used MPU-6050 Gyroscope/Accelerameter package, Yumo/Omron rotary encoders, and I2C communication between Arduino Unos for PID and translational drift control. Required a soldered interface board between Open Source Motor Controller (OSMC) and Arduino Mega consisting of a L7805 voltage regulator, line driver, and optocoupler packages to provide current and signal isolation. Each of 3 Ampflow magmotors has a peak of 4.6 horsepower and draws 150 Amps at full load. Future improvements include fabricating metal body and shell, and integrating the OSMC interface board into a PCB with motor controller components that can operate at 48 V.`,
img: osiris,
sub: "🤖"
},
{
title: '⏩ Roombotics',
content: `Our club received a donation of 30 Roombas. We have decided to build a robotic swarm using them. This swarm will be able to communicate with each other to work together to fulfill a task. Possible tasks that we have thought of include mapping, search and rescue, and playing sports. We are currently using Arduinos to control the Roombas through their on-board commands.`,
img: Roomba
img: Roomba,
sub: "🧼"
},
{
title: 'MRK 1',
title: '⏩ Fancy Pants',
content: `Fancy Pants is a lower extremity exoskeleton and is one of the older projects at ITR. It is currently undergoing a significant redesign with the goals of increasing precision, comfort and safety. Although this exo needs a lot of work before it will be hurling someone 15 feet into the air safely, it has potential for greatness.`,
img: MRK
img: MRK,
sub: "🦾"
},
{
title: 'Mongol',
title: 'Mongol',
content: `Mongol is designed to compete in Mech-Warfare. In Mech-Warfare, all robots must walk on 2 or 4 legs as a means of propulsion. Each robot is also equipped with airsoft cannons and impact sensor plates. Each robot is given a certain number of 'hits' and is pitted against competitors in model cityscape to where the object of the competition is to reduce each opponents hits to zero before falling to zero themselves. Meanwhile, though able to be remote controlled, each robot's pilot cannot view the robot directly and must control the robot with visual information coming only from a wireless camera on the robot itself. Mongol was designed entirely in SolidWorks. For more information about Mech-Warfare visit mech-warfare.com`,
img: Mongol
},
{
title: 'Matchlock Ashigaru',
content: `This project is a new approach to the Mech Warfare competition and legged robot design. Not only does this robot have a set of legs as opposed to wheels for travel over rough terrain, but it is also equipped with a pair of turret style airsoft guns as well as a camera to give an inside feel to the computer operated controls. During the Mech Warfare competition, it will also come prepared with a rotating turret style head which will allow for quick response which is necessity when competing against fast moving opponents. Additional objectives for this project will be planned after its first successful participation in the Mech Warfare competition later this year. For more information about Mech-Warfare visit mech-warfare.com`,
img: ma
img: Mongol,
sub: "🖐️"
}
],
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 581 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 913 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 898 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1022 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@ -0,0 +1,26 @@
const fs = require("fs");
let res = "";
let json = `const gallery = {
pic: [`;
let jsonEnd = `
],
};`;
fs.readdir("./", (err, files) => {
files.forEach((file, index) => {
if (file === "readimg.js") {
return;
}
console.log(file);
res += `import pic${index} from "../pics/gallery/${file}";\n`;
json += `{
title: "",
content: "",
img: pic${index}
},`;
});
console.log(res);
console.log(json + jsonEnd);
});

View File

@ -136,6 +136,21 @@
}
}
@media screen and (max-width: 650px) {
.about__content__main__container {
width: 90vw;
}
.about__content__blocks_block {
width: 90vw;
}
.about__content__main__container span,
.about__content__blocks_block span {
font-size: 18px;
}
}
@keyframes fade {
0% {
opacity: 0;

View File

@ -1,19 +1,26 @@
#container {
.c {
opacity: 100%;
-webkit-animation: fade 0.9s ease-in;
-moz-animation: fade 0.9s ease-in;
-ms-animation: fade 0.9s ease-in;
-o-animation: fade 0.9s ease-in;
animation: fade 0.9s ease-in;
background-color: black;
background: linear-gradient(#3b3b3b, #1a1a1a);
position: relative;
margin: 0px;
padding: 0px;
width: 100vw;
}
.error {
background-color: #232323;
background-color: #3d3d3d;
width: 100%;
overflow: hidden;
display: flex;
height: calc(100vh - 101px);
position: relative;
top: 0;
left: 0;
}
.error__photo { margin: 0px;

View File

@ -0,0 +1,40 @@
@font-face {
font-family: itrFont;
src: url(../font/LeagueSpartan-ExtraBold.ttf);
}
@font-face {
font-family: itrFontMedium;
src: url(../font/LeagueSpartan-Medium.ttf);
}
.gallery {
background-color: #232323;
width: 100%;
min-height: 100vh;
height: auto;
opacity: 100%;
overflow-x: hidden;
display: flex;
-webkit-animation: fade 0.9s ease-in;
-moz-animation: fade 0.9s ease-in;
-ms-animation: fade 0.9s ease-in;
-o-animation: fade 0.9s ease-in;
animation: fade 0.9s ease-in;
background: linear-gradient(#3b3b3b, #1a1a1a);
}
.gallery_wrap {
flex-wrap: wrap;
padding: 24px;
margin-left: 20px;
display: flex;
flex-direction: row;
justify-content: start;
}
.gallery__title {
margin: 20px 0 20px 20px;
font-family: itrFontMedium;
color: #fff;
text-align: center;
}

View File

@ -192,6 +192,7 @@ li a:hover {
.hamburger-react {
color: #fff;
display: block;
margin-right: 10px;
}
.navbar__hamburger {
display: flex;

View File

@ -27,6 +27,7 @@
.projects_wrap {
flex-wrap: wrap;
padding: 24px;
margin-left: 20px;
display: flex;
flex-direction: row;
justify-content: start;
@ -35,6 +36,7 @@
margin: 20px 0 20px 20px;
font-family: itrFontMedium;
color: #fff;
text-align: center;
}
.project__content {
position: relative;
@ -54,22 +56,30 @@
}
.project__content__main__container {
padding: 10px 10px 20px 10px;
padding: 20px;
border-radius: 10px;
background-color: rgb(66, 66, 66);
box-sizing: border-box;
// height: 400px;
display: flex;
flex-direction: column;
transition: 0.3s;
cursor: default;
overflow: hidden;
margin: 0 16px 16px 0;
}
.project_item_content {
flex-grow: 1;
overflow: scroll;
}
.project_item_content_image {
border-radius: 10px;
transition: .1s;
}
.project_item_content_image:hover {
border-radius: 0px;
}
.project__content__main__container h1,
.project__content__blocks_block h1 {
color: white;
@ -84,7 +94,7 @@
.project__content__blocks_block span {
color: rgb(238, 238, 238);
opacity: 100%;
font-size: 16px;
font-size: 18px;
font-family: itrFontMedium;
padding: 10px;
line-height: 20px;

View File

@ -1,7 +1,8 @@
.waterfallContainer {
display: flex;
flex-wrap: wrap;
justify-content: space-evenly;
.waterfallItem {
margin: 3px;
margin-bottom: 12px;
}
}

View File

@ -3,9 +3,15 @@ import DropdownContainer from "../components/DropdownContainer";
import GlobalStore from "../store/global";
import NavBar from "../components/NavBar";
import Footer from "../components/Footer";
import { useLocation } from "react-router-dom";
import { useEffect } from "react";
const AppOuter = ({ children }) => {
const { isHamburger, setIsHamburger } = useContainer(GlobalStore);
const location = useLocation();
useEffect(() => {
setIsHamburger(false);
}, [location.pathname]);
return (
<div className="container">
{isHamburger ? (

View File

@ -1,22 +1,62 @@
import React, { Component } from "react";
import backgroundVideo from "../assets/video.mp4";
import "../assets/stylesheets/home.scss";
import React, { useEffect, useMemo } from "react";
import "../assets/stylesheets/gallery.scss";
import { useContainer } from "unstated-next";
import GlobalStore from "../store/global";
import gallery from "../assets/data/gallery";
import WaterfallPosition from "./hooks/waterfall";
import { Image } from "antd";
export default class Gallery extends Component {
render() {
const Render = ({ onLoad, data, sizeRef }) => {
return (
<div className="home">
<video autoPlay loop muted className="home__video">
<source src={backgroundVideo} type="video/mp4" />
</video>
<div className="home__content">
<label className="home__content__title">
ILLINOIS TECH
<br />
ROBOTICS
</label>
<div className="gallery__content">
<Image
onLoad={() => {
setTimeout(() => {
onLoad(sizeRef.current.size);
}, 100);
}}
onError={() =>
setTimeout(() => {
onLoad(sizeRef.current.size);
}, 100)
}
width={"100%"}
src={data.img}
/>
</div>
);
};
const Gallery = () => {
useEffect(() => {
window.scrollTo(0, 0);
}, []);
const { bodySize } = useContainer(GlobalStore);
const count = useMemo(() => {
if (bodySize.width > 850) {
return 3;
}
if (bodySize.width > 650) {
return 2;
}
return 1;
}, [bodySize]);
return (
<div className="gallery">
<div className="gallery__content">
<div className="gallery__content__main">
<div>
<h1 className="gallery__title">Gallery</h1>
<WaterfallPosition
columnNumber={count}
list={gallery.pic}
Render={Render}
/>
</div>
</div>
</div>
</div>
);
}
}
};
export default Gallery;

View File

@ -1,11 +1,61 @@
import React, { forwardRef, useEffect, useMemo } from "react";
import React, { useEffect, useMemo } from "react";
import "../assets/stylesheets/project.scss";
import { useContainer } from "unstated-next";
import GlobalStore from "../store/global";
import { Image } from "antd";
import projects from "../assets/data/projects";
import WaterfallPosition from "./Waterfall";
import WaterfallPosition from "./hooks/waterfall";
import { Image } from "antd";
const Render = ({ onLoad, data, sizeRef }) => {
return (
<div className="project__content__main__container">
<div
style={{
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
}}
>
<h3
style={{
fontFamily: "itrFontMedium",
fontSize: "25px",
color: "#fff",
marginBottom: 12,
}}
>
{data.title}
</h3>
<h3
style={{
fontFamily: "itrFontMedium",
fontSize: "25px",
color: "#fff",
marginBottom: 12,
}}
>
{data.sub}
</h3>
</div>
<div className="project_item_content">
<Image
onLoad={() => {
setTimeout(() => {
onLoad(sizeRef.current.size);
}, 500);
}}
onError={() =>
setTimeout(() => {
onLoad(sizeRef.current.size);
}, 500)
}
width={"100%"}
src={data.img}
/>
<span>{data.content}</span>
</div>
</div>
);
};
const Project = () => {
useEffect(() => {
window.scrollTo(0, 0);
@ -27,11 +77,19 @@ const Project = () => {
<div className="project__content__main">
<div>
<h1 className="projects__title">Active Projects</h1>
<WaterfallPosition columnNumber={count} list={projects.active} />
<WaterfallPosition
columnNumber={count}
list={projects.active}
Render={Render}
/>
</div>
<div>
<h1 className="projects__title">Retired/Inactive Projects</h1>
<WaterfallPosition columnNumber={count} list={projects.inactive} />
<WaterfallPosition
columnNumber={count}
list={projects.inactive}
Render={Render}
/>
</div>
</div>
{/* <WaterfallPositionDemo /> */}

View File

@ -1,9 +1,8 @@
import { useSize } from "ahooks";
import { useDebounce, useSize, useThrottleFn } from "ahooks";
import React, { useRef, useEffect, useState } from "react";
import "../assets/stylesheets/waterfall.scss";
import { Image } from "antd";
import "../../assets/stylesheets/waterfall.scss";
const WaterfallItem = ({ data, onLoad }) => {
const WaterfallItem = ({ data, onLoad, Render }) => {
const ref = useRef();
const size = useSize(ref);
const sizeRef = useRef({});
@ -12,30 +11,20 @@ const WaterfallItem = ({ data, onLoad }) => {
}, [size]);
return (
<div className="waterfallItem" ref={ref}>
<div className="project__content__main__container">
<h3 style={{ color: "#fff", marginBottom: 12 }}>{data.title}</h3>
<div className="project_item_content">
<Image
<Render
onLoad={() => {
setTimeout(() => {
onLoad(sizeRef.current.size);
}, 500);
}}
alt="asd"
onError={setTimeout(() => {
onLoad(sizeRef.current.size);
}, 500)}
width={"100%"}
src={data.img}
sizeRef={sizeRef}
data={data}
/>
<span>{data.content}</span>
</div>
</div>
</div>
);
};
const WaterfallPosition = ({ columnNumber, list }) => {
const useWaterfall = ({ list, columnNumber, Render }) => {
const stateRef = useRef({
heights: [],
loadNum: 0,
@ -43,7 +32,7 @@ const WaterfallPosition = ({ columnNumber, list }) => {
const onload = (index, height) => {
stateRef.current.heights[index] = height;
stateRef.current.loadNum++;
if (stateRef.current.loadNum === list.length) {
if (stateRef.current.loadNum <= list.length) {
onSize();
}
};
@ -67,12 +56,29 @@ const WaterfallPosition = ({ columnNumber, list }) => {
};
const waterfallDOM = useRef();
const size = useSize(waterfallDOM);
const { run: onSizeThrottle } = useThrottleFn(onSize, { wait: 5e2 });
useEffect(() => {
onSize();
onSizeThrottle();
}, [size, columnNumber]);
const rendered = list.map((item, index) => (
<WaterfallItem onLoad={(size) => onload(index, size.height)} data={item} />
<WaterfallItem
onLoad={(size) => onload(index, size.height)}
data={item}
Render={Render}
/>
));
return {
waterfallDOM,
columns,
};
};
const WaterfallPosition = ({ columnNumber, list, Render }) => {
const { waterfallDOM, columns } = useWaterfall({
columnNumber,
list,
Render,
});
return (
<div ref={waterfallDOM} className="waterfallContainer">
{columns.map((column) => {

View File

@ -8,6 +8,7 @@ import reportWebVitals from "./reportWebVitals";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import ErrorRoute from "./routes/ErrorRoute";
import GlobalStore from "./store/global";
import GalleryRoute from "./routes/GalleryRoute";
const root = ReactDOM.createRoot(document.getElementById("root"));
@ -31,11 +32,18 @@ const router = createBrowserRouter([
path: "/projects",
element: <ProjectsRoute></ProjectsRoute>,
errorElement: <ErrorRoute></ErrorRoute>,
}
},
{
path: "/gallery",
element: <GalleryRoute></GalleryRoute>,
errorElement: <ErrorRoute></ErrorRoute>,
},
]);
root.render(<GlobalStore.Provider>
root.render(
<GlobalStore.Provider>
<RouterProvider router={router}></RouterProvider>
</GlobalStore.Provider>);
</GlobalStore.Provider>
);
reportWebVitals();

View File

@ -0,0 +1,12 @@
import AppOuter from "../components/AppOuter";
import Gallery from "../components/Gallery";
const GalleryRoute = () => {
return (
<AppOuter>
<Gallery />
</AppOuter>
);
};
export default GalleryRoute;