diff --git a/client/index.html b/client/index.html index e4b78ea..50c0ae1 100644 --- a/client/index.html +++ b/client/index.html @@ -2,9 +2,9 @@ - + - Vite + React + TS + trx shortlink
diff --git a/client/package-lock.json b/client/package-lock.json index 7bb06b6..fc8ae69 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -9,7 +9,8 @@ "version": "0.0.0", "dependencies": { "react": "^19.1.0", - "react-dom": "^19.1.0" + "react-dom": "^19.1.0", + "react-router-dom": "^7.7.0" }, "devDependencies": { "@eslint/js": "^9.30.1", @@ -2122,6 +2123,15 @@ "dev": true, "license": "MIT" }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -3562,6 +3572,44 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.7.0.tgz", + "integrity": "sha512-3FUYSwlvB/5wRJVTL/aavqHmfUKe0+Xm9MllkYgGo9eDwNdkvwlJGjpPxono1kCycLt6AnDTgjmXvK3/B4QGuw==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.7.0.tgz", + "integrity": "sha512-wwGS19VkNBkneVh9/YD0pK3IsjWxQUVMDD6drlG7eJpo1rXBtctBqDyBm/k+oKHRAm1x9XWT3JFC82QI9YOXXA==", + "license": "MIT", + "dependencies": { + "react-router": "7.7.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -3707,6 +3755,12 @@ "semver": "bin/semver.js" } }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "license": "MIT" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", diff --git a/client/package.json b/client/package.json index 54dbd0b..959a86a 100644 --- a/client/package.json +++ b/client/package.json @@ -11,7 +11,8 @@ }, "dependencies": { "react": "^19.1.0", - "react-dom": "^19.1.0" + "react-dom": "^19.1.0", + "react-router-dom": "^7.7.0" }, "devDependencies": { "@eslint/js": "^9.30.1", diff --git a/client/src/App.css b/client/src/App.css index b9d355d..c51f84a 100644 --- a/client/src/App.css +++ b/client/src/App.css @@ -6,13 +6,14 @@ } .logo { - height: 6em; + height: 12em; padding: 1.5em; will-change: filter; transition: filter 300ms; } .logo:hover { - filter: drop-shadow(0 0 2em #646cffaa); + filter: drop-shadow(0 0 1em #f29732); + } .logo.react:hover { filter: drop-shadow(0 0 2em #61dafbaa); @@ -28,15 +29,124 @@ } @media (prefers-reduced-motion: no-preference) { - a:nth-of-type(2) .logo { + /*a .logo { animation: logo-spin infinite 20s linear; - } + }*/ } .card { padding: 2em; + box-shadow: 0 0 10px 5px rgb(0 0 0 / 20%); + border-radius: 35px; } -.read-the-docs { - color: #888; +.input { + height: 100px; + width: 1000px; + border-radius: 15px; + border-color: #f29732; + border-style: double; + font-size: 48pt; + text-align: center; } +.nav { + text-align: center; +} + +header { + width: 100%; + height: 65px; + position: fixed; + top: 0; + left: 0; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); + z-index: 1; + background: rgba(0,0,0,0); +} + +header nav { + margin: 12px 20px 0 0; + display: flex; + justify-content: center; + align-items: center; +} +header nav ul li a { + padding: 12px 11px 12px 11px; + color: rgb(230, 223, 223); +} +header nav ul li { + margin: -12.5px 0px 0px 15px; + height: 35px; + float: left; + transition: all 300ms; -webkit-transition: all 300ms; -moz-transition: all 300ms; -o-transition: all 300ms; + + display: flex; + justify-content: center; /* horizontal zentrieren */ + align-items: center; /* vertikal zentrieren */ + list-style: none; + position: relative; + +} + +header nav ul li:hover { + border-radius: 8px; + background: rgba(0, 0, 0, 0.5); +} +header nav ul li a img { + width: 20px; + margin-top: 10px; +} + +a { + text-decoration: none; +} +li { + list-style-type: none; +} + +#button_short { + height: 100px; + width: 300px; + font-size: x-large; + border-radius: 15px; + will-change: filter; + transition: filter 400ms; +} +#button_short:hover { + filter: drop-shadow(0 0 0.5em #f29732); + border-color: transparent; + transition: 0.3s; +} +#button_short:active { + border-color: transparent; + background-color: transparent; +} + +#logoname { + box-shadow: 0 0 10px 5px rgb(0 0 0 / 20%); + border-radius: 35px; +} + +#logoname h1 { + will-change: filter; + transition: all 400ms; + padding: 35px; + margin-bottom: 100px; + margin-left: 440px; + margin-right: 440px; + color: rgb(230, 223, 223); +} +#logoname img { + padding: 35px; +} +#logoname h1:hover { + filter: drop-shadow(0 0 0.5em #f29732); +} + +#rightlist { + right: 20px; + position: absolute; +} +#oriurl { + margin: 50px; +} \ No newline at end of file diff --git a/client/src/App.tsx b/client/src/App.tsx deleted file mode 100644 index 6a6b59d..0000000 --- a/client/src/App.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { useState } from 'react' -import reactLogo from './assets/react.svg' -import viteLogo from '/vite.svg' -import './App.css' - -function App() { - const [count, setCount] = useState(0) - - return ( - <> -
- - Vite logo - - - React logo - -
-

Vite + React

-
- -

- -

-
-

- -

- - ) -} - -export default App diff --git a/client/src/Home.tsx b/client/src/Home.tsx new file mode 100644 index 0000000..e46a94e --- /dev/null +++ b/client/src/Home.tsx @@ -0,0 +1,57 @@ +import shortlinkLogo from './assets/trx-shortlink-orange.png' +import './App.css' + +const Home = () => { + return ( + <> +
+
+ +
+
+
+ + trx shortlink logo + +

trx shortlink

+
+
+ + +
+ + ); +}; + +export default Home; + +async function shortenLink(url: string) { + if ((document.getElementById("oriurl") as HTMLInputElement).value == "") { + alert("The url cannot be empty!") + } else { + const res = await fetch("http://localhost:3000/api/shorten", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ original_url: url }), + }); + const data = await res.json(); + console.log(data.short_url); + (document.getElementById("oriurl") as HTMLInputElement).value = "" + location.href = "link/" + data.id; + return data.id; + } + } + + diff --git a/client/src/assets/trx-shortlink-orange.png b/client/src/assets/trx-shortlink-orange.png new file mode 100644 index 0000000..8cf1d99 Binary files /dev/null and b/client/src/assets/trx-shortlink-orange.png differ diff --git a/client/src/assets/trx-shortlink.png b/client/src/assets/trx-shortlink.png new file mode 100644 index 0000000..a6fd27a Binary files /dev/null and b/client/src/assets/trx-shortlink.png differ diff --git a/client/src/main.tsx b/client/src/main.tsx index bef5202..4de0d8a 100644 --- a/client/src/main.tsx +++ b/client/src/main.tsx @@ -1,10 +1,35 @@ -import { StrictMode } from 'react' -import { createRoot } from 'react-dom/client' -import './index.css' -import App from './App.tsx' +import { createRoot } from 'react-dom/client'; +import './index.css'; +import Home from './Home.tsx'; +import Login from './pages/login.tsx' +import Copylink from './pages/copylink.tsx'; + +import { + BrowserRouter as Router, + Routes, + Route, + Navigate, +} from "react-router-dom"; createRoot(document.getElementById('root')!).render( - - - , + + + } + /> + } + /> + } + /> + } + /> + + , ) diff --git a/client/src/pages/Home.tsx b/client/src/pages/Home.tsx deleted file mode 100644 index 298ba2b..0000000 --- a/client/src/pages/Home.tsx +++ /dev/null @@ -1,9 +0,0 @@ -async function shortenLink() { - const res = await fetch("http://localhost:3000/api/shorten", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ original_url: "https://example.com" }), - }); - const data = await res.json(); - console.log(data.short_url); -} diff --git a/client/src/pages/copylink.tsx b/client/src/pages/copylink.tsx new file mode 100644 index 0000000..103be30 --- /dev/null +++ b/client/src/pages/copylink.tsx @@ -0,0 +1,39 @@ +import shortlinkLogo from '../assets/trx-shortlink-orange.png' +import '../App.css' + +const Copylink = () => { + + return ( + <> +
+
+ +
+
+
+ + trx shortlink logo + +

trx shortlink

+
+
+ + +
+ + ) + +}; + +export default Copylink; \ No newline at end of file diff --git a/client/src/pages/login.tsx b/client/src/pages/login.tsx new file mode 100644 index 0000000..d99283a --- /dev/null +++ b/client/src/pages/login.tsx @@ -0,0 +1,42 @@ +import shortlinkLogo from '../assets/trx-shortlink-orange.png' +import '../App.css' + +function App() { + + + return ( + <> +
+
+ +
+
+
+ + trx shortlink logo + +

trx shortlink

+
+
+

Login

+

+

+ +
+ + ) +} + + +export default App diff --git a/client/tsconfig.app.json b/client/tsconfig.app.json index 227a6c6..751d3e6 100644 --- a/client/tsconfig.app.json +++ b/client/tsconfig.app.json @@ -16,7 +16,7 @@ "jsx": "react-jsx", /* Linting */ - "strict": true, + "strict": false, "noUnusedLocals": true, "noUnusedParameters": true, "erasableSyntaxOnly": true, diff --git a/server/index.js b/server/index.js index adcb5cb..484f013 100644 --- a/server/index.js +++ b/server/index.js @@ -18,7 +18,8 @@ app.post("/api/shorten", (req, res) => { [id, original_url], (err) => { if (err) return res.status(500).json({ error: err.message }); - res.json({ short_url: `http://localhost:5173/${id}` }); + res.json({ short_url: `http://localhost:3000/${id}` }); + res.json({ id: `${id}`}); } ); });