Spaces:
Running
Running
Update src/App.js
Browse files- src/App.js +282 -60
src/App.js
CHANGED
|
@@ -1,77 +1,299 @@
|
|
| 1 |
-
import React, { useState } from
|
| 2 |
-
import
|
| 3 |
-
import './App.css';
|
| 4 |
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
body: JSON.stringify({
|
| 23 |
-
data: [ticker],
|
| 24 |
-
}),
|
| 25 |
-
});
|
| 26 |
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
|
|
|
| 36 |
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
} finally {
|
| 41 |
-
|
| 42 |
}
|
| 43 |
};
|
| 44 |
|
| 45 |
return (
|
| 46 |
<div className="App">
|
| 47 |
-
<
|
| 48 |
-
|
| 49 |
-
<h1>Stock Forecaster</h1>
|
| 50 |
-
<p>Enter a stock ticker (e.g., AAPL, GOOGL, TSLA) to predict the next day's closing price.</p>
|
| 51 |
-
|
| 52 |
-
<div className="input-container">
|
| 53 |
-
<input
|
| 54 |
-
type="text"
|
| 55 |
-
value={ticker}
|
| 56 |
-
onChange={(e) => setTicker(e.target.value.toUpperCase())}
|
| 57 |
-
placeholder="Enter Ticker"
|
| 58 |
-
className="ticker-input"
|
| 59 |
-
/>
|
| 60 |
-
<button onClick={handleForecast} disabled={isLoading} className="forecast-button">
|
| 61 |
-
{isLoading ? 'Forecasting...' : 'Get Forecast'}
|
| 62 |
-
</button>
|
| 63 |
-
</div>
|
| 64 |
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
</div>
|
| 74 |
);
|
| 75 |
}
|
| 76 |
|
| 77 |
-
export default App;
|
|
|
|
| 1 |
+
import React, { useState } from "react";
|
| 2 |
+
import "./App.css";
|
|
|
|
| 3 |
|
| 4 |
+
// ๐งฉ Company-to-Ticker mapping
|
| 5 |
+
const companyToTicker = {
|
| 6 |
+
"Agilent Technologies, Inc.": "A",
|
| 7 |
+
"AAALY": "AAALY",
|
| 8 |
+
"AAC": "AAC",
|
| 9 |
+
"AAC Technologies Holdings Inc.": "AACAY",
|
| 10 |
+
"American Airlines Group Inc.": "AAL",
|
| 11 |
+
"Atlantic American Corporation": "AAME",
|
| 12 |
+
"Applied Optoelectronics, Inc.": "AAOI",
|
| 13 |
+
"AAON, Inc.": "AAON",
|
| 14 |
+
"Advance Auto Parts, Inc.": "AAP",
|
| 15 |
+
"Apple Inc.": "AAPL",
|
| 16 |
+
"American Assets Trust, Inc.": "AAT",
|
| 17 |
+
"AAVL": "AAVL",
|
| 18 |
+
"AAWW": "AAWW",
|
| 19 |
+
"AllianceBernstein Holding L.P.": "AB",
|
| 20 |
+
"AbbVie Inc.": "ABBV",
|
| 21 |
+
"ABC": "ABC",
|
| 22 |
+
"Ameris Bancorp": "ABCB",
|
| 23 |
+
"Cambium Learning Group, Inc.": "ABCD",
|
| 24 |
+
"ABCO": "ABCO",
|
| 25 |
+
"Asbury Automotive Group, Inc.": "ABG",
|
| 26 |
+
"ABIO": "ABIO",
|
| 27 |
+
"American Biltrite Inc.": "ABLT",
|
| 28 |
+
"ABM Industries Incorporated": "ABM",
|
| 29 |
+
"ABMD": "ABMD",
|
| 30 |
+
"Arbor Realty Trust, Inc.": "ABR",
|
| 31 |
+
"Abbott Laboratories": "ABT",
|
| 32 |
+
"Aboitiz Equity Ventures, Inc.": "ABTZY",
|
| 33 |
+
"ACADIA Pharmaceuticals Inc.": "ACAD",
|
| 34 |
+
"Accor SA": "ACCYY",
|
| 35 |
+
"Air Canada": "ACDVF",
|
| 36 |
+
"Adicet Bio, Inc.": "ACET",
|
| 37 |
+
"ACFC": "ACFC",
|
| 38 |
+
"AMC Financial Holdings Inc.": "ACFL",
|
| 39 |
+
"Acorn Energy, Inc.": "ACFN",
|
| 40 |
+
"ACG": "ACG",
|
| 41 |
+
"Agricultural Bank of China Limited": "ACGBY",
|
| 42 |
+
"Arch Capital Group Ltd.": "ACGL",
|
| 43 |
+
"Acadia Healthcare Company, Inc.": "ACHC",
|
| 44 |
+
"ACHN": "ACHN",
|
| 45 |
+
"ACI Worldwide, Inc.": "ACIW",
|
| 46 |
+
"Axcelis Technologies, Inc.": "ACLS",
|
| 47 |
+
"Accenture plc": "ACN",
|
| 48 |
+
"ACNB Corporation": "ACNB",
|
| 49 |
+
"ACOR": "ACOR",
|
| 50 |
+
"Abrdn Income Credit Strategies Fund": "ACP",
|
| 51 |
+
"Ares Commercial Real Estate Corporation": "ACRE",
|
| 52 |
+
"ACRX": "ACRX",
|
| 53 |
+
"ACST": "ACST",
|
| 54 |
+
"Actua Corporation": "ACTA",
|
| 55 |
+
"Acacia Research Corporation": "ACTG",
|
| 56 |
+
"Acura Pharmaceuticals, Inc.": "ACUR",
|
| 57 |
+
"Acciona, S.A.": "ACXIF",
|
| 58 |
+
"Adobe Inc.": "ADBE",
|
| 59 |
+
"Agree Realty Corporation": "ADC",
|
| 60 |
+
"adidas AG": "ADDYY",
|
| 61 |
+
"Aida Engineering, Ltd.": "ADERY",
|
| 62 |
+
"ADES": "ADES",
|
| 63 |
+
"Analog Devices, Inc.": "ADI",
|
| 64 |
+
"Archer-Daniels-Midland Company": "ADM",
|
| 65 |
+
"ADMA Biologics, Inc.": "ADMA",
|
| 66 |
+
"ADMP": "ADMP",
|
| 67 |
+
"Automatic Data Processing, Inc.": "ADP",
|
| 68 |
+
"Adaptive Biotechnologies Corporation": "ADPT",
|
| 69 |
+
"Autodesk, Inc.": "ADSK",
|
| 70 |
+
"ADTRAN Holdings, Inc.": "ADTN",
|
| 71 |
+
"Addus HomeCare Corporation": "ADUS",
|
| 72 |
+
"Ayala Pharmaceuticals, Inc.": "ADXS",
|
| 73 |
+
"Ameren Corporation": "AEE",
|
| 74 |
+
"Aehr Test Systems, Inc.": "AEHR",
|
| 75 |
+
"Advanced Energy Industries, Inc.": "AEIS",
|
| 76 |
+
"AEL": "AEL",
|
| 77 |
+
"Adacel Technologies Limited": "AELTF",
|
| 78 |
+
"Agnico Eagle Mines Limited": "AEM",
|
| 79 |
+
"American Eagle Outfitters, Inc.": "AEO",
|
| 80 |
+
"American Electric Power Company, Inc.": "AEP",
|
| 81 |
+
"AerCap Holdings N.V.": "AER",
|
| 82 |
+
"AERI": "AERI",
|
| 83 |
+
"Aetna Inc.": "AET",
|
| 84 |
+
"AEY": "AEY",
|
| 85 |
+
"AEZS": "AEZS",
|
| 86 |
+
"AFAM": "AFAM",
|
| 87 |
+
"AllianceBernstein National Municipal Income Fund, Inc.": "AFB",
|
| 88 |
+
"Athens Bancshares Corporation": "AFCB",
|
| 89 |
+
"American Financial Group, Inc.": "AFG",
|
| 90 |
+
"Air France-KLM SA": "AFLYY",
|
| 91 |
+
"AFMD": "AFMD",
|
| 92 |
+
"AmTrust Financial Services, Inc.": "AFSI",
|
| 93 |
+
"AFT": "AFT",
|
| 94 |
+
"First Majestic Silver Corp.": "AG",
|
| 95 |
+
"Abrdn Global Dynamic Dividend Fund": "AGD",
|
| 96 |
+
"Agenus Inc.": "AGEN",
|
| 97 |
+
"Alamos Gold Inc.": "AGI",
|
| 98 |
+
"Agios Pharmaceuticals, Inc.": "AGIO",
|
| 99 |
+
"Federal Agricultural Mortgage Corporation": "AGM",
|
| 100 |
+
"AGNC Investment Corp.": "AGNC",
|
| 101 |
+
"Assured Guaranty Ltd.": "AGO",
|
| 102 |
+
"Agile Group Holdings Limited": "AGPYY",
|
| 103 |
+
"Adecoagro S.A.": "AGRO",
|
| 104 |
+
"AF Gruppen ASA": "AGRUF",
|
| 105 |
+
"AGRX": "AGRX",
|
| 106 |
+
"AGTC": "AGTC",
|
| 107 |
+
"Agilysys, Inc.": "AGYS",
|
| 108 |
+
"Aegean Airlines S.A.": "AGZNF",
|
| 109 |
+
"Anhui Conch Cement Company Limited": "AHCHY",
|
| 110 |
+
"AHGP": "AHGP",
|
| 111 |
+
"Armada Hoffler Properties, Inc.": "AHH",
|
| 112 |
+
"Asahi Kasei Corporation": "AHKSY",
|
| 113 |
+
"AHL": "AHL",
|
| 114 |
+
"Koninklijke Ahold Delhaize N.V.": "AHODF",
|
| 115 |
+
"AHPI": "AHPI",
|
| 116 |
+
"Ashford Hospitality Trust, Inc.": "AHT",
|
| 117 |
+
"C3.ai, Inc.": "AI",
|
| 118 |
+
"Aurubis AG": "AIAGF",
|
| 119 |
+
"AIF": "AIF",
|
| 120 |
+
"American International Group, Inc.": "AIG",
|
| 121 |
+
"AIMC": "AIMC",
|
| 122 |
+
"Albany International Corp.": "AIN",
|
| 123 |
+
"Airports of Thailand Public Company Limited": "AIPUY",
|
| 124 |
+
"Global X Artificial Intelligence & Technology ETF": "AIQ",
|
| 125 |
+
"Air Industries Group": "AIRI",
|
| 126 |
+
"Air T, Inc.": "AIRT",
|
| 127 |
+
"Applied Industrial Technologies, Inc.": "AIT",
|
| 128 |
+
"Apartment Investment and Management Company": "AIV",
|
| 129 |
+
"Assurant, Inc.": "AIZ",
|
| 130 |
+
"Arthur J. Gallagher & Co.": "AJG",
|
| 131 |
+
"Ajinomoto Co., Inc.": "AJINY",
|
| 132 |
+
"AJIS Co., Ltd.": "AJISF",
|
| 133 |
+
"Akamai Technologies, Inc.": "AKAM",
|
| 134 |
+
"Akebia Therapeutics, Inc.": "AKBA",
|
| 135 |
+
"Akbank T.A.S.": "AKBTY",
|
| 136 |
+
"Embotelladora Andina S.A.": "AKO-A",
|
| 137 |
+
"Acadia Realty Trust": "AKR",
|
| 138 |
+
"Akzo Nobel N.V.": "AKZOY",
|
| 139 |
+
"Albemarle Corporation": "ALB",
|
| 140 |
+
"Alpha Bank S.A.": "ALBKY",
|
| 141 |
+
"Alico, Inc.": "ALCO",
|
| 142 |
+
"Aldeyra Therapeutics, Inc.": "ALDX",
|
| 143 |
+
"Alexander & Baldwin, Inc.": "ALEX",
|
| 144 |
+
"Align Technology, Inc.": "ALGN",
|
| 145 |
+
"Allegiant Travel Company": "ALGT",
|
| 146 |
+
"ALIM": "ALIM",
|
| 147 |
+
"ALIOF": "ALIOF",
|
| 148 |
+
"Alaska Air Group, Inc.": "ALK",
|
| 149 |
+
"Alkermes plc": "ALKS",
|
| 150 |
+
"The Allstate Corporation": "ALL",
|
| 151 |
+
"Allegion plc": "ALLE",
|
| 152 |
+
"Allot Ltd.": "ALLT",
|
| 153 |
+
"Ally Financial Inc.": "ALLY",
|
| 154 |
+
"Alnylam Pharmaceuticals, Inc.": "ALNY",
|
| 155 |
+
"Analogic Corporation": "ALOG",
|
| 156 |
+
"Astellas Pharma Inc.": "ALPMY",
|
| 157 |
+
"ALR": "ALR",
|
| 158 |
+
"ALSD": "ALSD",
|
| 159 |
+
"Alstom SA": "ALSMY",
|
| 160 |
+
"Allison Transmission Holdings, Inc.": "ALSN",
|
| 161 |
+
"ALTR": "ALTR",
|
| 162 |
+
"Autoliv, Inc.": "ALV",
|
| 163 |
+
"Amadeus IT Group, S.A.": "AMADY",
|
| 164 |
+
"Applied Materials, Inc.": "AMAT",
|
| 165 |
+
"Ambarella, Inc.": "AMBA",
|
| 166 |
+
"Ambac Financial Group, Inc.": "AMBC",
|
| 167 |
+
"American Business Bank": "AMBZ",
|
| 168 |
+
"AMC Entertainment Holdings, Inc.": "AMC",
|
| 169 |
+
"Andatee China Marine Fuel Services Corporation": "AMCF",
|
| 170 |
+
"AMC Networks Inc.": "AMCX",
|
| 171 |
+
"Advanced Micro Devices, Inc.": "AMD",
|
| 172 |
+
"AMETEK, Inc.": "AME",
|
| 173 |
+
"Amedisys, Inc.": "AMED",
|
| 174 |
+
"Affiliated Managers Group, Inc.": "AMG",
|
| 175 |
+
"Amgen Inc.": "AMGN",
|
| 176 |
+
"American Homes 4 Rent": "AMH",
|
| 177 |
+
"Atrium Mortgage Investment Corporation": "AMIVF",
|
| 178 |
+
"A.P. Moller - Maersk A/S": "AMKBY",
|
| 179 |
+
"Amkor Technology, Inc.": "AMKR",
|
| 180 |
+
"AMNB": "AMNB",
|
| 181 |
+
"AMOT": "AMOT",
|
| 182 |
+
"Ameriprise Financial, Inc.": "AMP",
|
| 183 |
+
"Amphastar Pharmaceuticals, Inc.": "AMPH",
|
| 184 |
+
"Amarin Corporation plc": "AMRN",
|
| 185 |
+
"AMRS": "AMRS",
|
| 186 |
+
"American Superconductor Corporation": "AMSC",
|
| 187 |
+
"AMSWA": "AMSWA",
|
| 188 |
+
"American Tower Corporation": "AMT",
|
| 189 |
+
"AMTD IDEA Group": "AMTD",
|
| 190 |
+
"Aemetis, Inc.": "AMTX",
|
| 191 |
+
"American Woodmark Corporation": "AMWD",
|
| 192 |
+
"America Movil, S.A.B. de C.V.": "AMX",
|
| 193 |
+
"Amazon.com, Inc.": "AMZN",
|
| 194 |
+
"AutoNation, Inc.": "AN",
|
| 195 |
+
"ANAC": "ANAC",
|
| 196 |
+
"Anchor Bancorp": "ANCB",
|
| 197 |
+
"Access National Corporation": "ANCX",
|
| 198 |
+
"The Andersons, Inc.": "ANDE",
|
| 199 |
+
"Arista Networks Inc": "ANET",
|
| 200 |
+
"Abercrombie & Fitch Co.": "ANF",
|
| 201 |
+
"Angi Inc.": "ANGI",
|
| 202 |
+
"AngioDynamics, Inc.": "ANGO",
|
| 203 |
+
"Anika Therapeutics, Inc.": "ANIK",
|
| 204 |
+
"ANI Pharmaceuticals, Inc.": "ANIP",
|
| 205 |
+
"ANR": "ANR",
|
| 206 |
+
"Anthera Pharmaceuticals, Inc.": "ANTH",
|
| 207 |
+
"Sphere 3D Corp.": "ANY",
|
| 208 |
+
"Abrdn Total Dynamic Dividend Fund": "AOD",
|
| 209 |
+
"Aon plc": "AON"
|
| 210 |
+
};
|
| 211 |
|
| 212 |
+
// ๐งญ Reverse mapping (Ticker โ Company)
|
| 213 |
+
const tickerToCompany = Object.fromEntries(
|
| 214 |
+
Object.entries(companyToTicker).map(([k, v]) => [v, k])
|
| 215 |
+
);
|
| 216 |
|
| 217 |
+
function App() {
|
| 218 |
+
const [inputValue, setInputValue] = useState("");
|
| 219 |
+
const [ticker, setTicker] = useState("");
|
| 220 |
+
const [companyName, setCompanyName] = useState("");
|
| 221 |
+
const [forecast, setForecast] = useState("");
|
| 222 |
+
const [loading, setLoading] = useState(false);
|
|
|
|
|
|
|
|
|
|
|
|
|
| 223 |
|
| 224 |
+
// ๐ Handle input (detect if company or ticker)
|
| 225 |
+
const handleInputChange = (e) => {
|
| 226 |
+
const value = e.target.value.trim();
|
| 227 |
+
setInputValue(value);
|
| 228 |
+
|
| 229 |
+
// Check if user entered a known company name
|
| 230 |
+
if (companyToTicker[value]) {
|
| 231 |
+
setTicker(companyToTicker[value]);
|
| 232 |
+
setCompanyName(value);
|
| 233 |
+
}
|
| 234 |
+
// Or if entered a known ticker
|
| 235 |
+
else if (tickerToCompany[value.toUpperCase()]) {
|
| 236 |
+
setTicker(value.toUpperCase());
|
| 237 |
+
setCompanyName(tickerToCompany[value.toUpperCase()]);
|
| 238 |
+
} else {
|
| 239 |
+
setTicker("");
|
| 240 |
+
setCompanyName("");
|
| 241 |
+
}
|
| 242 |
+
};
|
| 243 |
|
| 244 |
+
// ๐ Call Gradio backend API
|
| 245 |
+
const handleForecast = async () => {
|
| 246 |
+
if (!ticker) {
|
| 247 |
+
setForecast("โ ๏ธ Please enter a valid company name or ticker.");
|
| 248 |
+
return;
|
| 249 |
+
}
|
| 250 |
|
| 251 |
+
setLoading(true);
|
| 252 |
+
try {
|
| 253 |
+
const response = await fetch(
|
| 254 |
+
`${window.location.origin}/api/predict?ticker_symbol=${ticker}`
|
| 255 |
+
);
|
| 256 |
+
const data = await response.json();
|
| 257 |
+
setForecast(data || "No prediction result found.");
|
| 258 |
+
} catch (error) {
|
| 259 |
+
console.error(error);
|
| 260 |
+
setForecast("โ Error fetching forecast from backend.");
|
| 261 |
} finally {
|
| 262 |
+
setLoading(false);
|
| 263 |
}
|
| 264 |
};
|
| 265 |
|
| 266 |
return (
|
| 267 |
<div className="App">
|
| 268 |
+
<h1>๐ Stock Price Forecaster (LSTM)</h1>
|
| 269 |
+
<p>Enter a company name or ticker to predict the next dayโs close price.</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 270 |
|
| 271 |
+
<input
|
| 272 |
+
type="text"
|
| 273 |
+
placeholder="e.g., Apple Inc. or AAPL"
|
| 274 |
+
value={inputValue}
|
| 275 |
+
onChange={handleInputChange}
|
| 276 |
+
className="input-box"
|
| 277 |
+
/>
|
| 278 |
+
|
| 279 |
+
{companyName && ticker && (
|
| 280 |
+
<p className="info-text">
|
| 281 |
+
๐ข <b>{companyName}</b> โ ๐น <b>{ticker}</b>
|
| 282 |
+
</p>
|
| 283 |
+
)}
|
| 284 |
+
|
| 285 |
+
<button onClick={handleForecast} disabled={loading}>
|
| 286 |
+
{loading ? "Predicting..." : "Get Forecast"}
|
| 287 |
+
</button>
|
| 288 |
+
|
| 289 |
+
{forecast && (
|
| 290 |
+
<div className="result-box">
|
| 291 |
+
<h3>Prediction Result</h3>
|
| 292 |
+
<p>{forecast}</p>
|
| 293 |
+
</div>
|
| 294 |
+
)}
|
| 295 |
</div>
|
| 296 |
);
|
| 297 |
}
|
| 298 |
|
| 299 |
+
export default App;
|