diff --git a/react-frontend/package.json b/react-frontend/package.json
new file mode 100644
index 0000000..2101dc3
--- /dev/null
+++ b/react-frontend/package.json
@@ -0,0 +1,38 @@
+{
+ "name": "sdt-veryfinal",
+ "version": "0.1.0",
+ "private": true,
+ "dependencies": {
+ "@testing-library/jest-dom": "^5.17.0",
+ "@testing-library/react": "^13.4.0",
+ "@testing-library/user-event": "^13.5.0",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-scripts": "5.0.1",
+ "web-vitals": "^2.1.4"
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test",
+ "eject": "react-scripts eject"
+ },
+ "eslintConfig": {
+ "extends": [
+ "react-app",
+ "react-app/jest"
+ ]
+ },
+ "browserslist": {
+ "production": [
+ ">0.2%",
+ "not dead",
+ "not op_mini all"
+ ],
+ "development": [
+ "last 1 chrome version",
+ "last 1 firefox version",
+ "last 1 safari version"
+ ]
+ }
+}
diff --git a/react-frontend/public/index.html b/react-frontend/public/index.html
new file mode 100644
index 0000000..aa069f2
--- /dev/null
+++ b/react-frontend/public/index.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ React App
+
+
+
+
+
+
+
diff --git a/react-frontend/src/App.js b/react-frontend/src/App.js
new file mode 100644
index 0000000..4d4dcac
--- /dev/null
+++ b/react-frontend/src/App.js
@@ -0,0 +1,9 @@
+import "./app.css";
+import LandingPage from "./screens/LandingPage";
+function App() {
+ return (
+
+ );
+}
+
+export default App;
diff --git a/react-frontend/src/app.css b/react-frontend/src/app.css
new file mode 100644
index 0000000..cd0cf77
--- /dev/null
+++ b/react-frontend/src/app.css
@@ -0,0 +1,587 @@
+@import url("https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css");
+
+@import url("https://fonts.googleapis.com/css?family=Poppins:700|Outfit:700");
+
+:root {
+ --black: #000000;
+ --font-size-xxxs: 20px;
+ --font-size-m: 68px;
+ --font-size-s: 31px;
+ --font-size-xxs: 26px;
+ --font-size-xs: 27px;
+ --font-family-poppins: "Poppins", Helvetica;
+ --font-family-outfit: "Outfit", Helvetica;
+}
+
+* {
+ box-sizing: border-box;
+}
+body::-webkit-scrollbar{
+ display: none;
+}
+
+/* .search-list-container::-webkit-scrollbar{
+ display: none;
+} */
+
+.hidden,
+.hidden * {
+ pointer-events: none;
+ visibility: hidden;
+}
+
+.landing-page {
+ align-items: center;
+ background-color: #f5f5f5;
+ /* border: 1px solid; */
+ /* border-color: var(--black); */
+ display: flex;
+ flex-direction: column;
+ gap: 31px;
+ height: auto;
+ min-width: 1440px;
+ padding: 50px 30px;
+ position: relative;
+}
+
+.hero-section {
+ align-items: center;
+ display: flex;
+ flex: 0 0 auto;
+ justify-content: center;
+ padding: 40px 0px;
+ position: relative;
+ width: 1179px;
+}
+
+.hero-image {
+ align-self: stretch;
+ flex: 1;
+ flex-grow: 1;
+ position: relative;
+ margin-top: 10px;
+}
+
+.headline {
+ align-items: flex-start;
+ align-self: stretch;
+ display: flex;
+ flex: 1;
+ flex-direction: column;
+ flex-grow: 1;
+ gap: 5px;
+ padding: 10px 0px;
+ position: relative;
+}
+
+.medium-length-display {
+ align-self: stretch;
+ letter-spacing: 0;
+ line-height: 85px;
+ margin-top: -1px;
+ position: relative;
+}
+
+.outfit-bold-black-68px {
+ color: var(--black);
+ font-family: var(--font-family-outfit);
+ font-size: var(--font-size-m);
+ font-style: normal;
+ font-weight: 700;
+}
+
+.discover-open-source {
+ color: var(--black);
+ font-family: var(--font-family-outfit);
+ font-size: var(--font-size-xxs);
+ font-weight: 700;
+ letter-spacing: 0;
+ line-height: 27.5px;
+ position: relative;
+ width: fit-content;
+}
+
+.nav-section {
+ align-items: center;
+ display: flex;
+ flex: 0 0 auto;
+ flex-direction: column;
+ gap: 20px;
+ justify-content: center;
+ position: relative;
+ width: 1181px;
+}
+
+.search-bar-wrapper {
+ align-items: center;
+ display: flex;
+ flex: 0 0 auto;
+ gap: 15px;
+ justify-content: center;
+ position: relative;
+ width: 1181px;
+}
+
+.search-button-container {
+ align-items: center;
+ display: inline-flex;
+ flex: 0 0 auto;
+ gap: 20px;
+ position: relative;
+}
+
+.search-button-container-item {
+ cursor: pointer;
+ height: 43px;
+ position: relative;
+ background-color: #000000;
+ border-radius: 10px;
+ transition: all 0.2s ease;
+ width: 170px;
+}
+
+.search-button-container-item:hover {
+ box-shadow: 0px 0px 10px 2px rgba(0, 0, 0, 0.2);
+}
+
+.text-inside-button {
+ color: #ffffff;
+ padding: 5px;
+ font-weight: bold;
+ font-family: var(--font-family-outfit);
+}
+
+.omf-logo {
+ align-items: center;
+ display: inline-flex;
+ flex: 0 0 auto;
+ gap: 10px;
+ position: relative;
+}
+
+.image-11 {
+ height: 96px;
+ object-fit: cover;
+ position: relative;
+ width: 88px;
+}
+
+.searchbox {
+ align-items: center;
+ display: flex;
+ flex: 1;
+ flex-grow: 1;
+ gap: 10px;
+ position: relative;
+ padding: 10px;
+ border-radius: 10px;
+ background-color: #ffffff;
+}
+
+input:focus {
+ outline: none;
+}
+
+.searchbox-input {
+ background-color: transparent;
+ border: 0;
+ color: var(--black);
+ flex: 1;
+ flex-grow: 1;
+ font-family: var(--font-family-poppins);
+ font-size: var(--font-size-xxxs);
+ font-weight: 700;
+ letter-spacing: 0;
+ line-height: 27.5px;
+ margin-top: -1px;
+ padding: 0;
+ position: relative;
+}
+
+.searchbox-input::placeholder {
+ color: #00000099;
+}
+
+.navbar-wrapper {
+ align-items: center;
+ display: flex;
+ flex: 0 0 auto;
+ gap: 38px;
+ justify-content: center;
+ position: relative;
+ width: 1181px;
+}
+
+.landing-page .sdt {
+ gap: 10px;
+ position: relative;
+}
+
+.sdt-logo {
+ align-items: flex-start;
+ display: inline-flex;
+ flex: 0 0 auto;
+ flex-direction: column;
+}
+
+.image-12 {
+ height: 83px;
+ position: relative;
+ width: 300px;
+}
+
+.navbar {
+ align-items: center;
+ align-self: stretch;
+ display: flex;
+ flex: 1;
+ flex-grow: 1;
+ gap: 38px;
+ justify-content: flex-end;
+ position: relative;
+}
+
+.navbar-link {
+ letter-spacing: 0;
+ line-height: 27.5px;
+ position: relative;
+ white-space: nowrap;
+ width: fit-content;
+}
+
+.poppins-bold-black-20px {
+ color: var(--black);
+ font-family: var(--font-family-poppins);
+ font-size: var(--font-size-xxxs);
+ font-style: normal;
+ font-weight: 700;
+}
+
+.support-section {
+ align-items: center;
+ display: flex;
+ flex: 0 0 auto;
+ flex-direction: column;
+ gap: 10px;
+ justify-content: center;
+ margin-bottom: -12.48px;
+ position: relative;
+ width: 1179px;
+}
+
+.supported-for {
+ align-items: center;
+ display: inline-flex;
+ flex: 0 0 auto;
+ position: relative;
+}
+
+.supported-for-1 {
+ color: var(--black);
+ font-family: var(--font-family-outfit);
+ font-size: var(--font-size-xs);
+ font-weight: 700;
+ letter-spacing: 0;
+ line-height: 27.5px;
+ margin-top: -1px;
+ position: relative;
+ width: 1179px;
+}
+
+.os-logos {
+ align-items: center;
+ display: flex;
+ flex-direction: row;
+ gap: 32px;
+ height: 136px;
+ position: relative;
+ width: 1179px;
+}
+
+.open-suse_-logo-1 {
+ align-self: center;
+ flex: 1;
+ flex-grow: 1;
+ position: relative;
+}
+
+.red_-hat_logo-1 {
+ align-self: center;
+ flex: 1;
+ flex-grow: 1;
+ position: relative;
+}
+
+.ibm-z_os-1 {
+ align-self: center;
+ flex: 1;
+ flex-grow: 1;
+ object-fit: cover;
+ position: relative;
+}
+
+.alma-linux_-icon_-logo-1 {
+ align-self: center;
+ flex: 1;
+ flex-grow: 1;
+ position: relative;
+}
+
+.logo-1 {
+ align-self: center;
+ flex: 1;
+ flex-grow: 1;
+ position: relative;
+}
+
+.x267px-fedora_logo-1 {
+ align-self: center;
+ flex: 1;
+ flex-grow: 1;
+ position: relative;
+}
+
+.rocky_-linux_logo-1 {
+ align-self: center;
+ flex: 1;
+ flex-grow: 1;
+ position: relative;
+}
+
+.debian_logo-1 {
+ align-self: center;
+ flex: 1;
+ flex-grow: 1;
+ position: relative;
+}
+
+.ubuntu-logo-2022-1 {
+ align-self: center;
+ flex: 1;
+ flex-grow: 1;
+ position: relative;
+}
+
+.middle-section {
+ align-items: center;
+ display: flex;
+ flex-direction: column;
+ gap: 22px;
+ height: 567.48px;
+ justify-content: center;
+ mix-blend-mode: multiply;
+ padding: 40px 0px;
+ position: relative;
+ width: 1175px;
+}
+
+.sdt-tagline {
+ align-items: center;
+ align-self: stretch;
+ display: flex;
+ flex: 1;
+ flex-grow: 1;
+ justify-content: center;
+ width: 100%;
+}
+
+.valign-text-middle {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+}
+
+.matches-developers-w {
+ letter-spacing: 0;
+ line-height: 74.8px;
+ position: relative;
+ text-align: center;
+ width: fit-content;
+}
+
+.openmainframeproject-color-1 {
+ align-self: stretch;
+ flex: 1;
+ flex-grow: 1;
+ margin-left: -0.09px;
+ margin-right: -0.09px;
+ margin-top: -0.35px;
+ position: relative;
+ width: 100%;
+}
+
+
+
+
+.search-list-container {
+ display: flex;
+ flex-direction: column;
+ width: 1179px;
+ height: 648px;
+ align-items: center;
+ gap: 20px;
+ position: relative;
+ overflow-y: auto;
+}
+
+.search-list {
+ display: flex;
+ width: 1179px;
+ align-items: center;
+ padding: 25px;
+ position: relative;
+ border-bottom-width: 3px;
+ border-bottom-style: solid;
+ border-color: #a89f9f;
+ }
+
+ .search-list .name-desc {
+ display: flex;
+ flex-direction: column;
+ height: 97px;
+ align-items: flex-start;
+ gap: 5px;
+ flex-grow: 1;
+ position: relative;
+ flex: 1;
+ }
+
+ .search-list .name {
+ align-self: stretch;
+ margin-top: -1px;
+ font-family: "Outfit-SemiBold", Helvetica;
+ font-weight: 600;
+ color: #000000e6;
+ font-size: 25px;
+ letter-spacing: 0;
+ line-height: 20px;
+ position: relative;
+ flex: 1;
+ }
+
+ .search-list .decription {
+ position: relative;
+ flex: 1;
+ align-self: stretch;
+ font-family: "Outfit-Regular", Helvetica;
+ font-weight: 400;
+ color: #00000099;
+ font-size: 14px;
+ letter-spacing: 0;
+ line-height: 18px;
+ }
+
+ .search-list .version-ostag {
+ display: flex;
+ flex-direction: column;
+ height: 97px;
+ align-items: flex-end;
+ justify-content: center;
+ position: relative;
+ flex: 1;
+ flex-grow: 1;
+ }
+
+ .search-list .version-year-wrapper {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ gap: 5px;
+ position: relative;
+ flex: 1;
+ align-self: stretch;
+ width: 100%;
+ flex-grow: 1;
+ }
+
+ .search-list .text-wrapper {
+ position: relative;
+ width: fit-content;
+ font-family: "Fira Mono-Regular", Helvetica;
+ font-weight: 400;
+ color: #666666;
+ font-size: 14px;
+ text-align: right;
+ letter-spacing: 0;
+ line-height: 21px;
+ white-space: nowrap;
+ }
+
+ .search-list .tag-wrapper {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ gap: 20px;
+ position: relative;
+ flex: 1;
+ align-self: stretch;
+ width: 100%;
+ flex-grow: 1;
+ }
+
+ .search-list .tag {
+ display: flex;
+ width: 105px;
+ align-items: center;
+ justify-content: flex-end;
+ padding: 10px;
+ position: relative;
+ background-color: #030303;
+ border-radius: 5px;
+ }
+
+ .search-list .tagname {
+ position: relative;
+ flex: 1;
+ align-self: stretch;
+ margin-top: -1px;
+ font-family: "Outfit-SemiBold", Helvetica;
+ font-weight: 600;
+ color: #ffffff;
+ font-size: 18px;
+ text-align: center;
+ letter-spacing: 0.4px;
+ line-height: 10px;
+ white-space: nowrap;
+ }
+
+
+/*
+.dropbtn {
+ background-color: #3498DB;
+ color: white;
+ padding: 16px;
+ font-size: 16px;
+ border: none;
+ cursor: pointer;
+}
+
+.dropbtn:hover, .dropbtn:focus {
+ background-color: #2980B9;
+}
+
+.dropdown {
+ position: relative;
+ display: inline-block;
+}
+
+.dropdown-content {
+ display: none;
+ position: absolute;
+ background-color: #f1f1f1;
+ min-width: 160px;
+ overflow: auto;
+ box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
+ z-index: 1;
+}
+
+.dropdown-content a {
+ color: black;
+ padding: 12px 16px;
+ text-decoration: none;
+ display: block;
+}
+
+.dropdown a:hover {background-color: #ddd;}
+
+.show {display: block;} */
\ No newline at end of file
diff --git a/react-frontend/src/images/hero-theme-pic.png b/react-frontend/src/images/hero-theme-pic.png
new file mode 100644
index 0000000..5a408c6
Binary files /dev/null and b/react-frontend/src/images/hero-theme-pic.png differ
diff --git a/react-frontend/src/images/openmainframe-logo.png b/react-frontend/src/images/openmainframe-logo.png
new file mode 100644
index 0000000..3dee2e0
Binary files /dev/null and b/react-frontend/src/images/openmainframe-logo.png differ
diff --git a/react-frontend/src/images/openmainframeproject-color-1.png b/react-frontend/src/images/openmainframeproject-color-1.png
new file mode 100644
index 0000000..84c1c83
Binary files /dev/null and b/react-frontend/src/images/openmainframeproject-color-1.png differ
diff --git a/react-frontend/src/images/sdt-logo.png b/react-frontend/src/images/sdt-logo.png
new file mode 100644
index 0000000..fbf7b6a
Binary files /dev/null and b/react-frontend/src/images/sdt-logo.png differ
diff --git a/react-frontend/src/index.js b/react-frontend/src/index.js
new file mode 100644
index 0000000..35a0782
--- /dev/null
+++ b/react-frontend/src/index.js
@@ -0,0 +1,15 @@
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import App from './App';
+
+
+const root = ReactDOM.createRoot(document.getElementById('root'));
+root.render(
+
+
+
+);
+
+// If you want to start measuring performance in your app, pass a function
+// to log results (for example: reportWebVitals(console.log))
+// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
diff --git a/react-frontend/src/screens/LandingPage.jsx b/react-frontend/src/screens/LandingPage.jsx
new file mode 100644
index 0000000..4add3b2
--- /dev/null
+++ b/react-frontend/src/screens/LandingPage.jsx
@@ -0,0 +1,18 @@
+import Navbar from "./components/Navbar";
+import HeroSection from "./components/HeroSection";
+import Footer from "./components/Footer";
+import SearchResults from "./components/SearchResults";
+import { useState } from "react";
+function LandingPage() {
+ const [results, setResults] = useState([]);
+ return (
+
+
+ {/* */}
+
+ {/* */}
+
+ );
+}
+
+export default LandingPage;
diff --git a/react-frontend/src/screens/components/Footer.jsx b/react-frontend/src/screens/components/Footer.jsx
new file mode 100644
index 0000000..f6765df
--- /dev/null
+++ b/react-frontend/src/screens/components/Footer.jsx
@@ -0,0 +1,58 @@
+function Footer() {
+ return(
+
+ );
+}
+
+export default Footer;
\ No newline at end of file
diff --git a/react-frontend/src/screens/components/HeroSection.jsx b/react-frontend/src/screens/components/HeroSection.jsx
new file mode 100644
index 0000000..6aa3f60
--- /dev/null
+++ b/react-frontend/src/screens/components/HeroSection.jsx
@@ -0,0 +1,44 @@
+import heroPic from "../../images/hero-theme-pic.png";
+import openMainFrameLogo from "../../images/openmainframeproject-color-1.png";
+
+function HeroSection() {
+ return (
+
+
+
+
+ Packages From
+
+ any Source
+
+ any Repository
+ in One Place.
+
+
+ Discover Open Source Packages For
+ Z architecture/s390x On Any Z Operating
+ system In One Place.
+
+
+
+
+
+
+
+
+ Matches Developers With
+ Best Open Source Software That
+
+ Meets Their Needs.
+
+
+
+
+ );
+}
+
+export default HeroSection;
diff --git a/react-frontend/src/screens/components/NavTopSection.jsx b/react-frontend/src/screens/components/NavTopSection.jsx
new file mode 100644
index 0000000..80b6d95
--- /dev/null
+++ b/react-frontend/src/screens/components/NavTopSection.jsx
@@ -0,0 +1,19 @@
+import sdtLogo from "../../images/sdt-logo.png";
+
+function NavTopSection() {
+ return (
+
+
+
+
+
+
about
+
blog
+
contact
+
documentation
+
+
+ );
+}
+
+export default NavTopSection;
\ No newline at end of file
diff --git a/react-frontend/src/screens/components/Navbar.jsx b/react-frontend/src/screens/components/Navbar.jsx
new file mode 100644
index 0000000..87e10a8
--- /dev/null
+++ b/react-frontend/src/screens/components/Navbar.jsx
@@ -0,0 +1,13 @@
+import NavTopSection from "./NavTopSection";
+import SearchBar from "./SearchBar";
+
+function Navbar({ setResults }) {
+ return (
+
+
+
+
+ );
+}
+
+export default Navbar;
diff --git a/react-frontend/src/screens/components/SearchBar.jsx b/react-frontend/src/screens/components/SearchBar.jsx
new file mode 100644
index 0000000..ec1a88b
--- /dev/null
+++ b/react-frontend/src/screens/components/SearchBar.jsx
@@ -0,0 +1,60 @@
+import React, { useState } from "react";
+
+import omfLogo from "../../images/openmainframe-logo.png";
+
+function SearchBar({ setResults }) {
+ const [input, setInput] = useState("");
+
+ const fetchData = (value) => {
+ fetch(
+ "https://raw.githubusercontent.com/openmainframeproject/software-discovery-tool-data/d37ec20db63776674dae7beccfd95e152b0d1e55/data_files/IBMZ_container_registry.json"
+ )
+ .then((response) => response.json())
+ .then((json) => {
+ const results = json.filter((software) => {
+ return (
+ value &&
+ software &&
+ software.packageName &&
+ software.packageName.toLowerCase().includes(value)
+ );
+ });
+ setResults(results);
+ });
+ };
+
+ const handleChange = (value) => {
+ setInput(value);
+ fetchData(value);
+ };
+
+ return (
+
+
+
+
+
+ handleChange(e.target.value)}
+ />
+
+
+
+ );
+}
+
+export default SearchBar;
diff --git a/react-frontend/src/screens/components/SearchList.jsx b/react-frontend/src/screens/components/SearchList.jsx
new file mode 100644
index 0000000..4e57d90
--- /dev/null
+++ b/react-frontend/src/screens/components/SearchList.jsx
@@ -0,0 +1,29 @@
+function SearchList({ result }) {
+ return (
+
+
+
{result.packageName}
+
{result.description}
+
+
+
+
version: {result.version}
+ {/*
5 years ago
*/}
+
+ {/*
*/}
+
+
+ );
+}
+
+export default SearchList;
diff --git a/react-frontend/src/screens/components/SearchResults.jsx b/react-frontend/src/screens/components/SearchResults.jsx
new file mode 100644
index 0000000..b21d45c
--- /dev/null
+++ b/react-frontend/src/screens/components/SearchResults.jsx
@@ -0,0 +1,13 @@
+import SearchList from "./SearchList";
+
+function SearchResults({ results }) {
+ return (
+
+ {results.map((result) => {
+ return ;
+ })}
+
+ );
+}
+
+export default SearchResults;
diff --git a/src/main.py b/src/main.py
index 8e19cca..0288c04 100644
--- a/src/main.py
+++ b/src/main.py
@@ -26,6 +26,7 @@ def getSupportedDistros():
package_search = PackageSearch.load()
json_data = json.dumps(package_search.getSupportedDistros())
resp = Response(json_data,mimetype="application/json")
+ resp.headers.set('Access-Control-Allow-Origin',"*")
resp.headers.set('Cache-Control','no-cache, no-store, must-revalidate')
resp.headers.set('Pragma','no-cache')
resp.headers.set('Expires','0')
@@ -48,6 +49,7 @@ def searchPackages():
json_data = package_search.searchSQLPackages(search_term,exact_match,search_bit_flag,page_number)
resp = Response(json_data,mimetype="application/json")
+ resp.headers.set('Access-Control-Allow-Origin',"*")
resp.headers.set('Cache-Control','no-cache, no-store, must-revalidate')
resp.headers.set('Pragma','no-cache')
resp.headers.set('Expires','0')
@@ -55,6 +57,13 @@ def searchPackages():
except Exception as ex:
LOGGER.error('Error in searchPackages with search parameters: %s', str(ex))
+@app.route("/sdt/data")
+def get_data():
+ return {
+ 'Name':"geek",
+ "Age":"22",
+ "programming":"python"
+ }
# Logic to start flask server if executed via command line.
if __name__ == '__main__':