Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions app/page.tsx

This file was deleted.

118 changes: 118 additions & 0 deletions src/app/components/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
'use client';

import Link from "next/link";
import { useState } from "react";
import { Menu, X, Music } from "lucide-react";

export default function Navbar() {
const [open, setOpen] = useState(false);
const user = false; // Placeholder for user authentication state

const navItems = [
{ href: "/", label: "Home" },
{ href: "/library", label: "Library" },
];

if (!user) {
return (
<header className="w-full bg-card/80 backdrop-blur-sm border-b border-border">
<div className="w-full px-4 sm:px-6 lg:px-8">
<div className="flex items-center justify-between h-16">
<div className="flex items-center gap-3">
<Link href="/" className="flex items-center gap-2 no-underline">
<span className="font-semibold text-lg">FirstFM</span>
</Link>
</div>

<div className="flex items-center gap-4">
<Link
href="/login"
>
Log in
</Link>
</div>
</div>
</div>
</header>
);
}

return (
<header className="w-full bg-card/80 backdrop-blur-sm border-b border-border">
<div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex items-center justify-between h-16">
<div className="flex items-center gap-3">
<Link href="/" className="flex items-center gap-2 no-underline">
<span className="font-semibold text-lg">FirstFM</span>
</Link>
</div>

<nav className="hidden md:flex items-center space-x-4">
{navItems.map((item) => (
<Link
key={item.href}
href={item.href}
className="px-3 py-2 rounded-md text-sm hover:bg-muted/60"
>
{item.label}
</Link>
))}
</nav>

<div className="flex items-center gap-2">
<div className="hidden md:block">
<button
type="button"
aria-label="Profile"
className="w-9 h-9 rounded-full bg-muted/40 flex items-center justify-center text-sm font-medium"
// title={} placeholder for user name
onClick={() => {
// Implement profile click functionality
}}
>
{/* Placeholder for user initial */}
</button>
</div>

{/* Mobile menu button */}
<div className="md:hidden">
<button
onClick={() => setOpen((v) => !v)}
aria-label="Toggle menu"
className="p-2 rounded-md hover:bg-muted/60"
>
{open ? <X className="w-5 h-5" /> : <Menu className="w-5 h-5" />}
</button>
</div>
</div>
</div>
</div>

{/* Mobile panel */}
{open && (
<div className="md:hidden border-t border-border bg-card/95">
<div className="px-4 pt-2 pb-4 space-y-1">
{navItems.map((item) => (
<Link
key={item.href}
href={item.href}
onClick={() => setOpen(false)}
className="block px-3 py-2 rounded-md text-base hover:bg-muted/60"
>
{item.label}
</Link>
))}
<div className="flex items-center gap-2 px-3 py-2">
<button
onClick={() => {}} // Implement logout functionality
className="w-full text-left px-3 py-2 rounded-md hover:bg-muted/60"
>
Log out
</button>
</div>
</div>
</div>
)}
</header>
);
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
10 changes: 6 additions & 4 deletions app/layout.tsx → src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import Navbar from "./components/Navbar";
import "./globals.css";

const geistSans = Geist({
Expand All @@ -13,8 +14,8 @@ const geistMono = Geist_Mono({
});

export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
title: "FirstFM",
description: "Generated by FirstFM",
};

export default function RootLayout({
Expand All @@ -25,9 +26,10 @@ export default function RootLayout({
return (
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
className={`${geistSans.variable} ${geistMono.variable} antialiased flex flex-col min-h-screen`}
>
{children}
<Navbar />
<main className="flex flex-1 min-h-0">{children}</main>
</body>
</html>
);
Expand Down
20 changes: 20 additions & 0 deletions src/app/login/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use client';

export default function LoginPage() {
return (
<div className="flex flex-col justify-between h-65 max-w-md mx-auto mt-24 p-6 bg-card/80 border border-border rounded-md">
<div>
<h1 className="font-semibold text-lg mb-4 mt-4">Log in with Last.fm</h1>
<p>FirstFM uses your Last.fm account to recommend songs and personalize your experience.</p>
</div>
<div className="flex justify-end">
<button
onClick={() => {}}
className="px-4 py-2 bg-primary text-primary-foreground rounded-md"
>
Sign in with LastFM
</button>
</div>
</div>
);
}
20 changes: 20 additions & 0 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Image from "next/image";

export default function Home() {
return (
<div className="font-sans flex flex-col flex-1 justify-between min-h-full mt-8 sm:mt-10">
<div className="text-center sm:text-left sm:pl-4 sm:w-100 md:w-125 xl:w-150 md:pl-8">
<div className="pb-4">
<h1 className="font-bold pb-2 sm:text-lg md:text-xl xl:text-2xl">Visualize Your Music, Discover Your Story</h1>
<p className="">
Unlock your music map by signing in with your Last.fm account.
</p>
</div>
<button className="mt-4 px-4 py-2 bg-primary text-primary-foreground rounded-md">Start Your Personalized Experience</button>
</div>
<div className="text-center pb-4 sm:text-right sm:flex sm:justify-end sm:pr-4 md:pr-8">
<p className="text-sm text-muted-foreground sm:w-100 md:w-100">This couldn't have been possible without the FirstFM team check them out <a href="#">here!</a> v1.0.0</p>
</div>
</div>
);
}
File renamed without changes.
File renamed without changes.