Skip to content

Commit

Permalink
Merge pull request #14 from frank-mendez/feature/settings
Browse files Browse the repository at this point in the history
Feature/settings
  • Loading branch information
frank-mendez authored Aug 25, 2024
2 parents 9599c19 + 0ca5976 commit 4a8bb18
Show file tree
Hide file tree
Showing 7 changed files with 313 additions and 30 deletions.
12 changes: 10 additions & 2 deletions src/App.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
@tailwind base;
@import url('https://fonts.googleapis.com/css2?family=Outfit:[email protected]&display=swap');@tailwind base;

@tailwind components;
@tailwind utilities;
@tailwind utilities;

.outfit-font {
font-family: "Outfit", sans-serif;
font-optical-sizing: auto;
font-weight: 500;
font-style: normal;
}
31 changes: 5 additions & 26 deletions src/components/MainContent.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,17 @@
import { useContentStore } from "../stores/useContentStore.ts";
import { useProfileQuery } from "../api/user";
import { useAuth } from "../context/AuthContext.tsx";
import { MainContent as MC } from "../data-objects/enum";
import ReactCountryFlag from "react-country-flag";
import Profile from "../pages/Profile.tsx";
import Settings from "../pages/Settings.tsx";

const MainContent = () => {
const { currentContent } = useContentStore();
const { accessToken } = useAuth();
const { data, isPending } = useProfileQuery(accessToken ?? "");
const srcImage = "/assets/images/man.png";
return (
<div
data-testid="main-content-element"
className="card bg-base-300 my-10 basis-1/2 shadow-xl"
className="card bg-base-300 my-10 basis-1/2 shadow-xl max-h-screen overflow-y-auto"
>
{currentContent === MC.PROFILE && (
<div className={`card-body ${isPending ? "skeleton" : ""}`}>
{!isPending && data && (
<div className="flex flex-row gap-4 items-center">
<img className="mask mask-circle w-[300px]" src={srcImage} />
<div className="flex flex-col justify-around align-middle gap-4">
<p className="text-sm">Profile</p>
<h1 className="font-bold text-6xl">
{data?.display_name ?? "John Doe"}
</h1>
<p className="text-sm">
{data?.followers?.total ?? 100} Followers
</p>
<ReactCountryFlag countryCode={data.country} />
</div>
</div>
)}
</div>
)}
{currentContent === MC.PROFILE && <Profile />}
{currentContent === MC.SETTINGS && <Settings />}
</div>
);
};
Expand Down
4 changes: 2 additions & 2 deletions src/pages/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import ExpandContent from "../components/ExpandContent.tsx";

const Dashboard = () => {
return (
<div data-testid="dashboard-element">
<div className="outfit-font max-auto" data-testid="dashboard-element">
<Header />
<div className="flex flex-row gap-2 px-2">
<div className="flex flex-row gap-2 px-2 h-[80vh] overflow-y-auto">
<Sidebar />
<MainContent />
<ExpandContent />
Expand Down
25 changes: 25 additions & 0 deletions src/pages/Profile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import ReactCountryFlag from "react-country-flag";

const Profile = () => {
const srcImage = "/assets/images/man.png";
return (
<div data-testid="profile-card-element" className="card-body">
<div className="flex flex-row gap-4 items-center">
<img
alt="Profile"
data-testid="profile-img-element"
className="mask mask-circle w-[300px]"
src={srcImage}
/>
<div className="flex flex-col justify-around align-middle gap-4">
<p className="text-sm">Profile</p>
<h1 className="font-bold text-6xl">John Doe</h1>
<p className="text-sm">1K Followers</p>
<ReactCountryFlag countryCode="PH" />
</div>
</div>
</div>
);
};

export default Profile;
181 changes: 181 additions & 0 deletions src/pages/Settings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
import SearchIcon from "@mui/icons-material/Search";

const Settings = () => {
return (
<div data-testid="settings-element" className="flex flex-col p-6 gap-4">
<div className="flex flex-row justify-between w-full items-center">
<h1
data-testid="settings-header-element"
className="font-bold text-3xl"
>
Settings
</h1>
<SearchIcon />
</div>
<div data-testid="lanaguage-select-element" className="flex flex-col">
<p className="font-bold text-sm">Language</p>
<div className="flex flex-row justify-between w-full items-center">
<p className="text-sm">
Choose language - Changes will be applied after restarting the app
</p>
<select className="select w-full max-w-xs">
<option>English</option>
<option>Japanese</option>
<option>Chinese</option>
<option>French</option>
<option>Swedish</option>
</select>
</div>
</div>
<div className="flex flex-col">
<p className="font-bold text-sm">Explicit Content</p>
<div className="flex flex-row justify-between w-full items-center">
<p className="text-sm">Allow playback of explicit-rated content</p>
<input type="checkbox" className="toggle" defaultChecked />
</div>
</div>
<div className="flex flex-col">
<p className="font-bold text-sm">Autoplay</p>
<div className="flex flex-row justify-between w-full items-center">
<p className="text-sm">
Enjoy nonstop listening. When your audio ends, we'll play you
something similar
</p>
<input type="checkbox" className="toggle" defaultChecked />
</div>
</div>
<div className="flex flex-col gap-4">
<p className="font-bold text-sm">Audio Quality</p>
<div className="flex flex-row justify-between w-full items-center">
<p className="text-sm">Streaming quality</p>
<select className="select w-full max-w-xs">
<option>Low</option>
<option>Normal</option>
<option>High</option>
<option>Very High</option>
</select>
</div>
<div className="flex flex-row justify-between w-full items-center">
<p className="text-sm">Download</p>
<select className="select w-full max-w-xs">
<option>Low</option>
<option>Normal</option>
<option>High</option>
<option>Very High</option>
</select>
</div>
<div className="flex flex-row justify-between w-full items-center">
<p className="text-sm">
Auto adjust quality - Recommended setting: On
</p>
<input type="checkbox" className="toggle" defaultChecked />
</div>
<div className="flex flex-row justify-between w-full items-center">
<p className="text-sm">
Normalize volume - Set the same volume level for all songs and
podcast s
</p>
<input type="checkbox" className="toggle" defaultChecked />
</div>
<div className="flex flex-row justify-between w-full items-center">
<p className="text-sm">
Volume level - Adjust the volume for your environment. Loud may{" "}
diminish audio quality. No effect on audio quality in Normal or
Quiet
</p>
<select className="select w-full max-w-xs">
<option>Low</option>
<option>Normal</option>
<option>High</option>
<option>Very High</option>
</select>
</div>
</div>
<div className="flex flex-col">
<p className="font-bold text-sm">Your library</p>
<div className="flex flex-row justify-between w-full items-center">
<p className="text-sm">Show local files</p>
<input type="checkbox" className="toggle" defaultChecked />
</div>
</div>
<div className="flex flex-col">
<p className="font-bold text-sm">Display</p>
<div className="flex flex-col gap-2">
<div className="flex flex-row justify-between w-full items-center">
<p className="text-sm">
Show the now-playing panel on click of play
</p>
<input type="checkbox" className="toggle" defaultChecked />
</div>
<div className="flex flex-row justify-between w-full items-center">
<p className="text-sm">Show announcements about new releases</p>
<input type="checkbox" className="toggle" defaultChecked />
</div>
<div className="flex flex-row justify-between w-full items-center">
<p className="text-sm">
Show desktop notifications when the song changes
</p>
<input type="checkbox" className="toggle" defaultChecked />
</div>
<div className="flex flex-row justify-between w-full items-center">
<p className="text-sm">See what your friends are playing</p>
<input type="checkbox" className="toggle" defaultChecked />
</div>
</div>
</div>
<div className="flex flex-col">
<p className="font-bold text-sm">Social</p>
<div className="flex flex-col gap-2">
<div className="flex flex-row justify-between w-full items-center">
<p className="text-sm">Publish my new playlists on my profile</p>
<input type="checkbox" className="toggle" defaultChecked />
</div>
<div className="flex flex-row justify-between w-full items-center">
<p className="text-sm">Start a private session</p>
<input type="checkbox" className="toggle" defaultChecked />
</div>
<div className="flex flex-row justify-between w-full items-center">
<p className="text-sm">Share my listening activity on Spotify</p>
<input type="checkbox" className="toggle" defaultChecked />
</div>
<div className="flex flex-row justify-between w-full items-center">
<p className="text-sm">
Show my recently played artists on my public profile
</p>
<input type="checkbox" className="toggle" defaultChecked />
</div>
</div>
</div>
<div className="flex flex-col">
<p className="font-bold text-sm">Playback</p>
<div className="flex flex-col gap-2">
<div className="flex flex-row justify-between w-full items-center">
<p className="text-sm">Crossfade songs</p>
<input type="checkbox" className="toggle" defaultChecked />
</div>
<div className="flex flex-row justify-between w-full items-center">
<p className="text-sm">
Automix - Allow seamless transition between songs on select
playlists
</p>
<input type="checkbox" className="toggle" defaultChecked />
</div>
<div className="flex flex-row justify-between w-full items-center">
<p className="text-sm">
Mono audio - Makes left and right speakers play the same audio
</p>
<input type="checkbox" className="toggle" defaultChecked />
</div>
<div className="flex flex-row justify-between w-full items-center">
<p className="text-sm">
Show my recently played artists on my public profile
</p>
<input type="checkbox" className="toggle" defaultChecked />
</div>
</div>
</div>
</div>
);
};

export default Settings;
45 changes: 45 additions & 0 deletions src/pages/tests/Profile.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { render, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
import { describe, it, expect } from "vitest";
import { BrowserRouter } from "react-router-dom";
import { AuthContext } from "../../context/AuthContext";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import Profile from "../Profile.tsx";

describe("Profile Component", () => {
const mockAuthContext = {
accessToken: "mockAccessToken",
login: async () => {},
logout: () => {},
refreshToken: "mockRefresh",
};
const profileComponent = () => {
const queryClient = new QueryClient();
render(
<QueryClientProvider client={queryClient}>
<AuthContext.Provider
value={{
accessToken: mockAuthContext.accessToken,
login: mockAuthContext.login,
logout: mockAuthContext.logout,
refreshToken: mockAuthContext.refreshToken,
}}
>
<BrowserRouter>
<Profile />
</BrowserRouter>
</AuthContext.Provider>
,
</QueryClientProvider>,
);
};
it("renders without crashing", () => {
profileComponent();
expect(screen.getByTestId("profile-card-element")).toBeInTheDocument();
});

it("contains a profile image", () => {
profileComponent();
expect(screen.getByTestId("profile-img-element")).toBeInTheDocument();
});
});
45 changes: 45 additions & 0 deletions src/pages/tests/Settings.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { render, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
import { describe, it, expect } from "vitest";
import { BrowserRouter } from "react-router-dom";
import { AuthContext } from "../../context/AuthContext";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import Settings from "../Settings.tsx";

describe("Settings Component", () => {
const mockAuthContext = {
accessToken: "mockAccessToken",
login: async () => {},
logout: () => {},
refreshToken: "mockRefresh",
};
const settingsComponent = () => {
const queryClient = new QueryClient();
render(
<QueryClientProvider client={queryClient}>
<AuthContext.Provider
value={{
accessToken: mockAuthContext.accessToken,
login: mockAuthContext.login,
logout: mockAuthContext.logout,
refreshToken: mockAuthContext.refreshToken,
}}
>
<BrowserRouter>
<Settings />
</BrowserRouter>
</AuthContext.Provider>
,
</QueryClientProvider>,
);
};
it("renders without crashing", () => {
settingsComponent();
expect(screen.getByTestId("settings-element")).toBeInTheDocument();
});

it("contains a profile image", () => {
settingsComponent();
expect(screen.getByTestId("lanaguage-select-element")).toBeInTheDocument();
});
});

0 comments on commit 4a8bb18

Please sign in to comment.