Skip to content

Commit

Permalink
push local project to github
Browse files Browse the repository at this point in the history
  • Loading branch information
ArijitCloud committed Sep 25, 2024
0 parents commit b2f4ca2
Show file tree
Hide file tree
Showing 56 changed files with 2,809 additions and 0 deletions.
26 changes: 26 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended",
"plugin:react/recommended",
"plugin:react/jsx-runtime",
],
ignorePatterns: ["dist", ".eslintrc.cjs"],
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
project: ["./tsconfig.json", "./tsconfig.node.json"],
tsconfigRootDir: __dirname,
},
plugins: ["react-refresh"],
rules: {
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],
},
};
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
pnpm-lock.yaml
coverage
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Music finder app

This is a music finnding web app.

## Running the app

1. get into the app directory
`cd music-finnd-web`

2. Use npm or any other package manager (I use pnpm) to:
1. install dependencies with `npm install`
2. run the app `npm run dev`
3. run the tests `npm run test`

## Future enhancement ideas

- Theme toggle button
- Configuration driven panels? global configs based UI
- Add e2e tests
17 changes: 17 additions & 0 deletions SortFeature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
### The sorting feature for albums

The sorting feature allows users to sort albums based on different criteria such as release date or album ranking. This is implemented using `useSearchContext` context for setting the current sort option and rendering albums based on the selected option.

- **Sorting Options**: Users can select between "Top album" (default sorting), "Recent release", and "Oldest release". The sort options are handled in the `QuickNav` component and dynamically updated based on user interaction.
- **Sorting State**: The `sortOption` state from the `useSearchContext` hook is used to track and set the selected sort criteria. A visual check mark (`Check` icon) is displayed next to the currently active sorting option in the menu.

### Key Implementation Points

- **`QuickNav.tsx`**: Contains the sorting button using the `MenuButton` component and allows toggling between favorite albums.
- **`useSearchContext`**: Handles the sort state (`sortOption`) and allows the user to select sorting logic.
- **`Content.tsx`**: Processes the sort option and renders albums based on the chosen sorting criteria.

### Potential Improvement

1. **User Preferences**: Persist the user’s selected sorting preference across sessions using localStorage or backend sync.
2. **More sort options**: Persist the user’s selected sorting preference across sessions using localStorage or backend sync.
14 changes: 14 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="A website let you find your favourite music">
<title>Music finnd web</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
9 changes: 9 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default {
moduleNameMapper: {
"\\.(css|less)$": "identity-obj-proxy",
},
transform: {
"^.+\\.(ts|tsx)$": "ts-jest",
},
testEnvironment: "jsdom",
};
45 changes: 45 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"name": "music-finnd-web",
"private": true,
"version": "0.0.1",
"type": "module",
"scripts": {
"dev": "vite",
"test": "jest",
"test:watch": "jest --watchAll",
"test:coverage": "jest --coverage",
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"@heroicons/react": "^2.1.5",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^14.2.1",
"identity-obj-proxy": "^3.0.0",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"jsdom": "^24.0.0",
"lodash.debounce": "^4.0.8",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"ts-jest": "^29.1.2"
},
"devDependencies": {
"@types/jest": "^29.5.12",
"@types/lodash.debounce": "^4.0.9",
"@types/react": "^18.2.64",
"@types/react-dom": "^18.2.21",
"@typescript-eslint/eslint-plugin": "^7.1.1",
"@typescript-eslint/parser": "^7.1.1",
"@vitejs/plugin-react-swc": "^3.5.0",
"autoprefixer": "^10.4.20",
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5",
"postcss": "^8.4.47",
"tailwindcss": "^3.4.12",
"typescript": "^5.2.2",
"vite": "^5.1.6"
}
}
6 changes: 6 additions & 0 deletions postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
50 changes: 50 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { useEffect, useState } from "react";
import { HeaderBar, FilterNav, Content, QuickNav } from "./layouts";
import { useFetchReducer, SearchProvider } from "./state";

const allFilter = "All";

function App() {
const { loading, error, data } = useFetchReducer(100);
const [categories, setCategories] = useState<string[]>([allFilter]);
const [showSaved, setShowSaved] = useState(false);

useEffect(() => {
if (data) {
const uniqueCategories = Array.from(
new Set(
data
.map((album) => album.category?.label)
.filter((label): label is string => typeof label === "string")
)
);
setCategories([allFilter, ...uniqueCategories]);
}
}, [data]);

return (
<div
style={{ scrollbarGutter: "stable" }}
className="h-screen flex flex-col flex-grow overflow-auto px-2 sm:px-10 text-black dark:text-white"
>
<SearchProvider>
<header className="sticky top-0 z-40 bg-white dark:bg-gray-bg py-4 px-6">
<HeaderBar />
<FilterNav categories={categories} loading={loading} />
<QuickNav onShowSaved={(reset) => setShowSaved(!reset)} />
</header>

<main className="px-6">
<Content
data={data}
error={error}
loading={loading}
showSaved={showSaved}
/>
</main>
</SearchProvider>
</div>
);
}

export default App;
Loading

0 comments on commit b2f4ca2

Please sign in to comment.