1
Fork 0

Use svelte instead

This commit is contained in:
Hadeed 2025-04-10 00:43:21 +05:00
parent a53f5a2ad2
commit 3f453bc3b5
10 changed files with 769 additions and 1774 deletions

View file

@ -1,3 +1,2 @@
.env
.venv/
__pycache__/

1
frontend/.gitignore vendored
View file

@ -1,2 +1 @@
node_modules/
dist/

View file

@ -4,23 +4,18 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="styles.css" />
<style>
@import "tailwindcss";
</style>
</head>
<body>
<div id="root"></div>
<div id="app"></div>
<script type="module">
import React from "react";
import { createRoot } from "react-dom/client";
import { mount } from "svelte";
import App from "./src/App.svelte";
import App from "./src/app.jsx";
createRoot(document.getElementById("root")).render(
React.createElement(
React.StrictMode,
null,
React.createElement(App, null),
),
);
mount(App, { target: document.getElementById("app") });
</script>
</body>
</html>

File diff suppressed because it is too large Load diff

View file

@ -1,29 +1,22 @@
{
"name": "svelte-hello",
"type": "module",
"dependencies": {
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-youtube": "^10.1.0"
},
"devDependencies": {
"autoprefixer": "^10.4.19",
"postcss": "^8.4.38",
"prettier": "^3.3.2",
"@sveltejs/vite-plugin-svelte": "^5.0.3",
"@tailwindcss/vite": "^4.1.3",
"prettier": "^3.5.3",
"prettier-plugin-css-order": "^2.1.2",
"prettier-plugin-tailwindcss": "^0.6.5",
"tailwindcss": "^3.4.4",
"prettier-plugin-svelte": "^3.3.3",
"prettier-plugin-tailwindcss": "^0.6.11",
"svelte": "^5.25.9",
"tailwindcss": "^4.1.3",
"vite": "^6.2.5"
},
"prettier": {
"plugins": [
"prettier-plugin-css-order",
"prettier-plugin-svelte",
"prettier-plugin-tailwindcss"
]
},
"postcss": {
"plugins": {
"tailwindcss": {},
"autoprefixer": {}
}
}
}

65
frontend/src/App.svelte Normal file
View file

@ -0,0 +1,65 @@
<script>
let channelName = "";
let videoId = "";
let loading = false;
let error = "";
async function fetchVideo() {
if (!channelName) return;
loading = true;
error = "";
videoId = "";
try {
const res = await fetch(`http://localhost:8000/video?channel_name=${channelName}`);
if (!res.ok) throw new Error("Channel not found or API error");
const data = await res.json();
videoId = data.id;
} catch (err) {
error = err.message;
} finally {
loading = false;
}
}
function handleSubmit(e) {
e.preventDefault();
fetchVideo();
}
</script>
<main class="min-h-screen bg-gray-100 flex flex-col items-center justify-center p-6">
<h1 class="text-4xl font-extrabold mb-6">YouTube Latest Video Finder</h1>
<form on:submit={handleSubmit} class="flex flex-col sm:flex-row items-center gap-4">
<input
type="text"
bind:value={channelName}
placeholder="Enter channel name"
class="px-4 py-2 border border-gray-300 rounded-md w-72"
/>
<button
type="submit"
disabled={loading}
class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 disabled:opacity-50"
>
{loading ? "Loading..." : "Get Latest Video"}
</button>
</form>
{#if error}
<p class="text-red-600 mt-4 text-sm">{error}</p>
{/if}
{#if videoId}
<div class="mt-8 w-full flex justify-center">
<iframe
title="video"
width="560"
height="315"
src={`https://www.youtube.com/embed/${videoId}?rel=0`}
class="rounded-lg shadow-lg"
></iframe>
</div>
{/if}
</main>

View file

@ -1,76 +0,0 @@
import { useState } from "react";
import YouTube from "react-youtube";
export default function App() {
const [channelName, setChannelName] = useState("");
const [videoId, setVideoId] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");
async function fetchLatestVideo() {
if (!channelName) return;
setLoading(true);
setError("");
setVideoId(null);
try {
const res = await fetch(
`http://localhost:8000/video?channel_name=${channelName}`,
);
if (!res.ok) throw new Error("Channel not found or API error");
const data = await res.json();
setVideoId(data.id);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
}
const playerOptions = {
playerVars: {
autoplay: 0,
rel: 0,
},
};
return (
<div className="flex min-h-screen flex-col items-center justify-center bg-gray-100 p-6">
<h1 className="mb-6 text-4xl font-extrabold">
YouTube Latest Video Finder
</h1>
<form
onSubmit={(e) => {
e.preventDefault();
fetchLatestVideo();
}}
className="flex flex-col items-center gap-4 sm:flex-row"
>
<input
type="text"
value={channelName}
onChange={(e) => setChannelName(e.target.value)}
placeholder="Enter channel name"
className="w-72 rounded-md border border-gray-300 px-4 py-2"
/>
<button
type="submit"
disabled={loading}
className="rounded-md bg-blue-600 px-4 py-2 text-white hover:bg-blue-700 disabled:opacity-50"
>
{loading ? "Loading..." : "Get Latest Video"}
</button>
</form>
{error && <p className="mt-4 text-sm text-red-600">{error}</p>}
{videoId && (
<div className="mt-8 flex w-full justify-center">
<YouTube videoId={videoId} opts={playerOptions} />
</div>
)}
</div>
);
}

View file

@ -1,3 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View file

@ -1,8 +0,0 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ["./index.html", "./src/**/*.jsx"],
theme: {
extend: {},
},
plugins: [],
};

View file

@ -1,7 +1,11 @@
import tailwindcss from "@tailwindcss/vite"
import { defineConfig } from "vite";
import { svelte } from "@sveltejs/vite-plugin-svelte";
export default defineConfig({
esbuild: {
jsxInject: `import React from 'react'`,
},
plugins: [
svelte(),
tailwindcss()
],
});