diff --git a/mobile-magic/apps/frontend/components/Appbar.tsx b/mobile-magic/apps/frontend/components/Appbar.tsx index 5053343..692fa04 100644 --- a/mobile-magic/apps/frontend/components/Appbar.tsx +++ b/mobile-magic/apps/frontend/components/Appbar.tsx @@ -11,6 +11,7 @@ import { Header } from '@/components/Header' import { motion } from 'motion/react' import { containerVariants, itemVariants } from '@/lib/animation-variants' import { ThemeButton } from '@/components/theme-button' +import GitHubRepoCard from './Githubcard' export function Appbar() { return ( @@ -46,6 +47,9 @@ export function Appbar() { + + + ); diff --git a/mobile-magic/apps/frontend/components/Githubcard.tsx b/mobile-magic/apps/frontend/components/Githubcard.tsx new file mode 100644 index 0000000..5fe578f --- /dev/null +++ b/mobile-magic/apps/frontend/components/Githubcard.tsx @@ -0,0 +1,87 @@ +'use client' +import { useState } from "react"; +import { ChevronDown, ChevronUp, ExternalLink } from "lucide-react"; +import { BACKEND_URL } from "@/config"; +import axios from "axios"; + + +export default function GitHubRepoCard() { + const [isOpen, setIsOpen] = useState(false); + + + const handleGithubClick = async () => { + try { + + const githubToken = localStorage.getItem("githubToken"); + const githubUsername = localStorage.getItem("githubUsername"); + + if (!githubToken) { + return (window.location.href = `${BACKEND_URL}/auth/github`); + } + const response = await axios.post(`${BACKEND_URL}/createrepo`, + { + githubToken, + githubUsername, + files: [ + { + name: "myFile.txt", + content: "This is the content of my file." + }, + { + name: "anotherFile.js", + content: "console.log('Hello from another file!');" + } + ] + }, + ); + + if (response.data.repoUrl) { + window.open(response.data.repoUrl, "_blank"); + } + } catch { + alert("Failed to clone repository"); + } +}; + + return ( +
+ + + + {isOpen && ( +
+

GitHub

+

+ This project is connected to
+ {`mobile-magic`}. +
Changes will be committed to the main branch. +

+ + +
+ + +
+
+ )} +
+ ); +} \ No newline at end of file diff --git a/mobile-magic/apps/frontend/components/hero.tsx b/mobile-magic/apps/frontend/components/hero.tsx index cacf4db..af2d4ed 100644 --- a/mobile-magic/apps/frontend/components/hero.tsx +++ b/mobile-magic/apps/frontend/components/hero.tsx @@ -2,8 +2,26 @@ import { motion } from 'motion/react' import { containerVariants, itemVariants } from '@/lib/animation-variants' +import { useRouter } from 'next/navigation'; +import { useEffect } from 'react'; export const Hero = () => { + const router = useRouter(); + + useEffect(() => { + const urlParams = new URLSearchParams(window.location.search); + const githubToken = urlParams.get("githubToken"); + const githubId = urlParams.get("githubId"); + const githubUsername = urlParams.get("githubUsername"); + + if (githubToken && githubId && githubUsername) { + localStorage.setItem("githubToken", githubToken); + localStorage.setItem("githubId", githubId); + localStorage.setItem("githubUsername", githubUsername); + } + router.push("/"); + }, [router]); + return ( { res.json({ prompts }); }); +app.post("/createrepo", async (req, res) => { + const { githubToken, githubUsername, files } = req.body; + + if (!githubToken || !githubUsername) { + res.status(400).json({ error: "Missing parameters: githubToken and githubUsername are required." }); + return; + } + + if (!files || !Array.isArray(files) || files.length === 0) { + res.status(400).json({ error: "Missing or empty 'files' array." }); + return; + } + + try { + const newRepoName = `from-magic-mobile-${Date.now()}`; + + const createRepoRes = await axios.post( + "https://api.github.com/user/repos", + { name: newRepoName, private: false }, + { headers: { Authorization: `Bearer ${githubToken}` } } + ); + + const newRepoUrl = createRepoRes.data.html_url; + + for (const file of files) { + if (file && file.name && file.content) { + const encodedContent = Buffer.from(file.content).toString("base64"); + console.log(`Uploading ${file.name} from system to ${newRepoName}`); + + await axios.put( + `https://api.github.com/repos/${githubUsername}/${newRepoName}/contents/${file.name}`, + { + message: `Added ${file.name} from system`, + content: encodedContent, + branch: "main", + }, + { headers: { Authorization: `Bearer ${githubToken}` } } + ); + } else { + console.warn("Invalid file object in 'files' array."); + } + } + + res.status(200).json({ message: "Repository created successfully!", repoUrl: newRepoUrl }); + } catch (error) { + console.error("Error creating repository:", error.response?.data || error.message); + res.status(500).json({ error: "Failed to create repository" }); + } +}); + +app.get("/auth/github", (req, res) => { + const githubAuthUrl = `https://github.com/login/oauth/authorize?client_id=${CLIENT_ID}&redirect_uri=${BACKEND_URL}/auth/github/callback&scope=repo,user`; + res.redirect(githubAuthUrl); +}); + +app.get("/auth/github/callback", async (req, res) => { + const code = req.query.code; + if (!code) res.status(400).send("GitHub OAuth failed!"); + + try { + + const tokenRes = await axios.post( + "https://github.com/login/oauth/access_token", + { + client_id: CLIENT_ID, + client_secret: CLIENT_SECRET, + code, + }, + { headers: { Accept: "application/json" } } + ); + + const accessToken = tokenRes.data.access_token; + + const userRes = await axios.get("https://api.github.com/user", { + headers: { Authorization: `Bearer ${accessToken}` }, + }); + + const { login, id } = userRes.data; + + res.redirect(`http://localhost:3000?githubToken=${accessToken}&githubId=${id}&githubUsername=${login}`); // Redirect to frontend after linking GitHub + } catch (error) { + console.error("GitHub OAuth Error:", error); + res.status(500).send("GitHub authentication failed"); + } +}); + app.listen(9090, () => { console.log("Server is running on port 9090"); -}); \ No newline at end of file +});