├── .eslintrc.json ├── .github ├── ISSUE_TEMPLATE │ ├── bug.yml │ ├── documentation.yml │ ├── feature_request.yml │ └── styles.yml ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yml └── workflows │ ├── author-assign-pr.yml │ ├── close_old_issues.yaml │ ├── codeql.yml │ ├── comment-on-PR.yml │ ├── greetings.yml │ ├── lock.yml │ ├── npm-publish-github-packages.yml │ └── static.yml ├── .gitignore ├── Added more features ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── STYLE_GUIDE.md ├── app ├── about │ └── page.jsx ├── accessibility │ └── page.jsx ├── adchoices │ └── page.jsx ├── addBooks │ ├── AddBooks.jsx │ └── page.jsx ├── api │ ├── auth │ │ └── [...nextauth] │ │ │ └── route.js │ ├── book │ │ ├── [id] │ │ │ └── route.js │ │ ├── category │ │ │ └── route.js │ │ ├── new │ │ │ └── route.js │ │ └── route.js │ ├── mail │ │ └── route.js │ ├── newsletter │ │ ├── route.js │ │ └── user │ │ │ └── route.js │ └── register │ │ └── route.js ├── awards │ ├── BookAward.jsx │ ├── bookAwardsData.js │ └── page.js ├── benefits │ └── page.js ├── bookmark │ ├── Bookmark.jsx │ └── page.jsx ├── books │ ├── BookList.jsx │ ├── Spinner.css │ ├── [id] │ │ └── page.jsx │ └── page.jsx ├── contact │ ├── Contact.jsx │ └── page.jsx ├── cookie │ └── page.js ├── copyright │ └── page.js ├── develop │ └── page.jsx ├── faq │ ├── Accordion.jsx │ ├── faqData.js │ └── page.js ├── favicon.ico ├── formats │ ├── SBook.jsx │ ├── [slug] │ │ └── page.js │ ├── bookFormatsData.js │ └── page.js ├── genre │ ├── SGenre.jsx │ ├── [slug] │ │ └── page.js │ ├── genreDetailsData.js │ └── page.js ├── googlebooks │ ├── [bookId] │ │ ├── [isbn] │ │ │ └── page.jsx │ │ └── page.jsx │ └── page.jsx ├── join │ └── page.js ├── layout.jsx ├── login │ ├── Login.jsx │ └── page.jsx ├── metadata.js ├── page.jsx ├── pcategories │ ├── biography │ │ ├── Biography.jsx │ │ └── page.js │ ├── career │ │ └── page.js │ ├── contemporary │ │ └── page.js │ ├── cooking │ │ └── page.js │ ├── garden │ │ └── page.js │ ├── mystery │ │ └── page.js │ ├── politics │ │ └── page.js │ ├── science │ │ └── page.js │ ├── selfhelp │ │ └── page.js │ └── travel │ │ └── page.js ├── privacy │ └── page.js ├── publishers │ └── page.jsx ├── signup │ ├── Signup.jsx │ └── page.jsx ├── team │ ├── Contributors.js │ ├── Team.jsx │ └── page.jsx └── terms │ └── page.js ├── components ├── About │ ├── Download.css │ ├── Download.js │ ├── Feature.css │ ├── Feature.js │ ├── Hero.jsx │ └── Testimonial.js ├── BkCards │ ├── BkCards.js │ └── CardContent │ │ └── CardContent.js ├── DataProvider.js ├── Footer │ ├── Footer.js │ └── NewsLetter │ │ ├── NewsLetter.css │ │ └── NewsLetter.js ├── Home │ ├── CgCards │ │ ├── CardContent │ │ │ ├── CardContent.css │ │ │ └── CardContent.js │ │ ├── CgCards.js │ │ └── cardComponentData.js │ └── ImgSection │ │ ├── AutoType.jsx │ │ ├── ImgSection.css │ │ └── ImgSection.js ├── Icons.js ├── Logo.js ├── Navbar │ ├── NavItems │ │ └── NavItems.js │ ├── Navbar.css │ └── Navbar.js ├── Preloader │ ├── Preloader.css │ └── Preloader.jsx ├── Quotes │ └── Card.jsx ├── RStar.jsx ├── ScrollButton │ ├── ScrollButton.css │ └── ScrollButton.js ├── TNYCards │ ├── BkCards.js │ ├── CardContent │ │ └── CardContent.js │ └── Spinner.css ├── Upload │ └── Upload.js ├── join │ ├── Benefits.jsx │ ├── Community.jsx │ ├── Employee.jsx │ ├── Header.jsx │ ├── ImgSection.jsx │ └── JobSection.jsx └── theme │ ├── theme-provider.jsx │ └── theme-toggle.jsx ├── context └── AuthContext.jsx ├── docker-compose.yml ├── jsconfig.json ├── libs └── prismadb.jsx ├── model ├── Book.js ├── Newsletter.js └── User.js ├── next.config.js ├── package.json ├── pages └── 404.js ├── postcss.config.js ├── prisma └── schema.prisma ├── public ├── add-book.png ├── afsd.ico ├── assets │ ├── Formats │ │ ├── audiobook.webp │ │ ├── comics.webp │ │ ├── ebook.webp │ │ ├── magazines.webp │ │ └── paperback.webp │ ├── Genre │ │ ├── adventure.jpeg │ │ ├── biography.webp │ │ ├── fantasy.jpeg │ │ ├── historical.jpeg │ │ ├── horror.webp │ │ ├── mystery.webp │ │ ├── romance.webp │ │ ├── science.webp │ │ └── thriller.webp │ ├── audiobks │ │ ├── abk1.webp │ │ ├── abk2.webp │ │ ├── abk3.webp │ │ └── abk4.webp │ ├── auth │ │ ├── captcha.webp │ │ ├── googleLogo.png │ │ ├── login.jpg │ │ └── signup.jpg │ ├── awards │ │ ├── manbooker.webp │ │ ├── national.webp │ │ ├── pen-faulkner.webp │ │ ├── pulitzer.webp │ │ └── womenprize.webp │ ├── benefits │ │ ├── benefit-1.webp │ │ ├── benefit-2.webp │ │ ├── benefit-3.webp │ │ ├── benefit-4.webp │ │ └── benefit-5.webp │ ├── biography │ │ ├── Arthur.webp │ │ ├── Einstein.webp │ │ ├── Mandela.webp │ │ ├── Steve.webp │ │ ├── ashuwiz.webp │ │ ├── benjamin.webp │ │ ├── bill.webp │ │ ├── charles.webp │ │ ├── mark.webp │ │ ├── obama.webp │ │ └── parmanand.webp │ ├── book1.webp │ ├── book2.webp │ ├── career │ │ ├── achieve.webp │ │ ├── c.webp │ │ ├── luck.webp │ │ ├── mind.webp │ │ ├── mindset.webp │ │ ├── money.jpeg │ │ ├── monk.webp │ │ ├── new.webp │ │ ├── secret.webp │ │ ├── steven.webp │ │ └── thousand.webp │ ├── cooking │ │ ├── OIP (1).webp │ │ ├── OIP (2).webp │ │ ├── OIP (3).webp │ │ ├── OIP.webp │ │ ├── cook.webp │ │ ├── download (1).webp │ │ ├── download (2).webp │ │ └── download.webp │ ├── ebooks │ │ ├── ReadingChallenge.webp │ │ ├── atomic-habits.webp │ │ ├── ebk1.webp │ │ ├── ebk2.webp │ │ ├── ebk3.webp │ │ ├── ebk4.webp │ │ ├── ebk5.webp │ │ ├── ebk6.webp │ │ ├── ebk7.webp │ │ ├── ebk8.webp │ │ └── starts-with-us.webp │ ├── error │ │ ├── construct.webp │ │ └── pagenotfound.webp │ ├── fiction │ │ ├── 1.webp │ │ ├── 10.webp │ │ ├── 2.webp │ │ ├── 3.webp │ │ ├── 4.webp │ │ ├── 5.webp │ │ ├── 6.webp │ │ ├── 7.webp │ │ ├── 8.webp │ │ └── 9.webp │ ├── home.webp │ ├── join │ │ ├── quotationmark.webp │ │ ├── workinginoffice.webp │ │ └── workplace.jpeg │ ├── logos │ │ ├── AppStore_Icon.webp │ │ ├── add.webp │ │ ├── dark_logo.png │ │ ├── darklogo_png.png │ │ ├── icon.webp │ │ ├── light_logo.png │ │ ├── logo.webp │ │ ├── logo_play_store.webp │ │ └── logo_png.png │ ├── mainPages │ │ ├── aboutUs.webp │ │ ├── contact-us.webp │ │ ├── help.webp │ │ ├── newsletter.webp │ │ ├── opensrc.webp │ │ ├── start.webp │ │ ├── start2.webp │ │ └── start3.webp │ ├── maths science │ │ ├── 10.webp │ │ ├── OIP.webp │ │ ├── esses.webp │ │ ├── girl.webp │ │ ├── math.webp │ │ ├── maths.webp │ │ ├── physics.webp │ │ └── science.webp │ ├── mobile.webp │ ├── mystery │ │ ├── buried.webp │ │ ├── comehome.webp │ │ ├── falls.webp │ │ ├── first.webp │ │ ├── foresaken.webp │ │ ├── grave.webp │ │ ├── haunting.webp │ │ ├── i.webp │ │ ├── love.webp │ │ ├── mansion.webp │ │ ├── meliss.webp │ │ ├── murders.webp │ │ ├── mystery.webp │ │ ├── night.webp │ │ ├── secret.webp │ │ ├── she.webp │ │ └── treasure.webp │ ├── politics │ │ ├── america.webp │ │ ├── british.webp │ │ ├── international.webp │ │ ├── little.webp │ │ ├── obama.webp │ │ ├── office.webp │ │ ├── politics.webp │ │ ├── power.webp │ │ ├── purpose.webp │ │ └── rival.webp │ ├── selfHelp │ │ ├── 6.webp │ │ ├── alchemist.jpg │ │ ├── boy.webp │ │ ├── homeless.webp │ │ ├── husband.webp │ │ ├── journey.webp │ │ ├── pocket.webp │ │ ├── rest.webp │ │ ├── rich.webp │ │ ├── rise.webp │ │ └── robert.webp │ └── travel │ │ ├── OIP (1).webp │ │ ├── OIP (2).webp │ │ ├── OIP (3).webp │ │ ├── OIP (4).webp │ │ ├── OIP (5).webp │ │ ├── OIP (6).webp │ │ ├── OIP (7).webp │ │ ├── OIP.webp │ │ └── download.webp ├── copyIcon.svg ├── error.png ├── favicon1.ico ├── favicon3.ico ├── logo192.png ├── logo512.png ├── manifest.json ├── robots.txt ├── search-svgrepo-com.svg ├── search.png └── sitemap.xml ├── readme.md ├── styles ├── CardContent.module.css ├── SingleBK.css └── globals.css ├── tailwind.config.js └── utils ├── Constants.js ├── database.js ├── searchBooks.js └── validation.js /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next", 3 | "rules": { 4 | "react/no-unescaped-entities": "off", 5 | "@next/next/no-page-custom-font": "off" 6 | } 7 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.yml: -------------------------------------------------------------------------------- 1 | name: ​🐞 Bug 2 | description: Report an issue to help us improve the project. 3 | title: "[BUG] " 4 | labels: ["bug", "goal: fix"] 5 | body: 6 | - type: textarea 7 | attributes: 8 | label: Description 9 | description: A brief description of the issue or bug you are facing, also include what you tried and what didn't work. 10 | validations: 11 | required: false 12 | - type: textarea 13 | attributes: 14 | label: Screenshots 15 | description: Please add screenshots if applicable 16 | validations: 17 | required: false 18 | - type: textarea 19 | attributes: 20 | label: Any additional information? 21 | description: Any additional information or Is there anything we should know about this bug? 22 | validations: 23 | required: false 24 | - type: dropdown 25 | id: browsers 26 | attributes: 27 | label: What browser are you seeing the problem on? 28 | multiple: true 29 | options: 30 | - Firefox 31 | - Chrome 32 | - Safari 33 | - Microsoft Edge 34 | - type: checkboxes 35 | id: no-duplicate-issues 36 | attributes: 37 | label: "Checklist" 38 | options: 39 | - label: "I have checked the existing issues" 40 | required: true 41 | 42 | - label: "I have read the [Contributing Guidelines](https://github.com/rohansx/informatician/blob/main/CONTRIBUTING.md)" 43 | required: true 44 | 45 | - label: "I have read the discussion tab thoroughly and got the project idea" 46 | required: true 47 | 48 | - label: "I am willing to work on this issue (optional)" 49 | required: false 50 | 51 | - label: "I am a GSSoC'23 contributor" 52 | required: false 53 | 54 | 55 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Documentation Issue 3 | about: Report an issue with the project documentation 4 | title: "[Documentation] " 5 | 6 | --- 7 | 8 | body: 9 | - type: markdown 10 | attributes: 11 | value: | 12 | 15 | 16 | ### Issue Summary 17 | 18 | **Description:** 19 | A clear and concise description of the problem with the documentation or the improvement you'd like to suggest. 20 | 21 | **Severity:** 22 | [ ] Low 23 | [ ] Medium 24 | [ ] High 25 | [ ] Critical 26 | 27 | **Affected Documentation Section:** 28 | Specify the relevant section(s) or page(s) of the documentation where you encountered the issue. 29 | 30 | ### Expected Documentation 31 | 32 | **Describe the expected content:** 33 | If applicable, describe how you expected the documentation to be or provide examples of how it could be improved. 34 | 35 | **Proposed Solution:** 36 | Share your ideas for improving the documentation or propose a solution if you have one. 37 | 38 | ### Reproduction Steps 39 | 40 | **Steps to Reproduce:** 41 | If the issue is related to inaccuracies or unclear instructions, provide the steps to reproduce the problem. 42 | 43 | **Screenshots or Code Snippets:** 44 | Attach any relevant screenshots or code snippets that illustrate the problem. 45 | 46 | ### Environment Information 47 | 48 | **Your Environment:** 49 | - OS: [e.g., Windows, macOS, Linux] 50 | - Browser: [e.g., Chrome, Firefox, Safari] 51 | - Version: [e.g., 1.0.0] 52 | 53 | **Additional Context:** 54 | Add any other context or details that might be helpful for understanding the issue. 55 | 56 | ### Related Documentation URLs 57 | 58 | **Links:** 59 | If relevant, provide any specific URLs or links to the documentation in question. 60 | 61 | ### Contributor Checklist 62 | 63 | Please make sure that you have considered the following before submitting this documentation issue: 64 | 65 | - [ ] I have checked the project's existing documentation issues to ensure there are no duplicates. 66 | - [ ] I have reviewed the project's CONTRIBUTING guidelines. 67 | - [ ] I understand that submitting a documentation issue does not guarantee immediate updates. 68 | 69 | ### Additional Notes 70 | 71 | **Notes:** 72 | Add any other notes or comments related to this documentation issue. 73 | 74 | 78 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 💡 2 | description: Have any new idea or new feature ? Please suggest! 3 | title: "[Feature] " 4 | labels: ["enhancement", "goal: addition"] 5 | body: 6 | - type: textarea 7 | id: description 8 | attributes: 9 | label: Description 10 | description: A clear and concise description of any alternative solution or features you've considered. 11 | validations: 12 | required: true 13 | - type: textarea 14 | id: screenshots 15 | attributes: 16 | label: Screenshots 17 | description: Please add screenshots if applicable 18 | validations: 19 | required: false 20 | - type: checkboxes 21 | id: no-duplicate-issues 22 | attributes: 23 | label: "Checklist" 24 | options: 25 | - label: "I have checked the existing issues" 26 | required: true 27 | 28 | - label: "I have read the [Contributing Guidelines]" 29 | required: true 30 | 31 | - label: "I have read the discussion tab thoroughly and got the project idea " 32 | required: true 33 | 34 | - label: "I am willing to work on this issue (optional)" 35 | required: false 36 | 37 | - label: "I am a GSSoC'23 contributor" 38 | required: false 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/styles.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Style Changing Request 3 | description: Suggest a style designs 4 | title: '[style]: ' 5 | labels: ['enhancement'] 6 | 7 | --- 8 | 9 | body: 10 | - type: markdown 11 | attributes: 12 | value: | 13 | Thanks for taking the time to fill out this template! 14 | - type: textarea 15 | id: style-idea 16 | attributes: 17 | label: What's the style idea? 18 | placeholder: Add descriptions 19 | value: 'We need to improve ' 20 | validations: 21 | required: true 22 | - type: textarea 23 | id: screenshots 24 | attributes: 25 | label: Add screenshots 26 | description: Add screenshots to see the demo 27 | placeholder: Add screenshots 28 | value: 'Add screenshots' 29 | - type: checkboxes 30 | id: terms 31 | attributes: 32 | label: Code of Conduct 33 | description: By submitting this issue, you agree to follow our Code of Conduct 34 | options: 35 | - label: I agree to follow this project's Code of Conduct 36 | required: true 37 | - label: I have read the [Contributing Guidelines](https://github.com/NarendraKoya999/informatician/blob/main/CONTRIBUTING.md) 38 | required: true 39 | 40 | - label: I agree to follow this project's [Code of Conduct](https://github.com/rohansx/informatician/blob/main/CODE_OF_CONDUCT.md) 41 | required: true 42 | 43 | - label: I'm a GSSoC'23 contributor 44 | 45 | - label: I want to work on this issue 46 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Related Issue 4 | 5 | Closes #issue_number 6 | 7 | 8 | 9 | ## Description 10 | 11 | 13 | 14 | ## Screenshots (if applicable) 15 | 16 | | Original | Updated | 17 | | :-----------------: | :----------------: | 18 | | original screenshot | updated screenshot | 19 | 20 | ## Checklist 21 | 22 | 23 | 24 | 25 | - [ ] My code adheres to the established style guidelines of the project. 26 | - [ ] I have included comments in areas that may be difficult to understand. 27 | - [ ] My changes have not introduced any new warnings. 28 | - [ ] I have conducted a self-review of my code. -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # Update GitHub Actions and dependencies 4 | - package-ecosystem: "github-actions" 5 | - package-ecosystem: "npm" 6 | directory: "/" 7 | schedule: 8 | interval: "daily" 9 | -------------------------------------------------------------------------------- /.github/workflows/author-assign-pr.yml: -------------------------------------------------------------------------------- 1 | name: 'Author Assign' 2 | 3 | on: 4 | pull_request_target: 5 | types: [opened, reopened] 6 | 7 | permissions: 8 | pull-requests: write 9 | 10 | jobs: 11 | assign-author: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: toshimaru/auto-author-assign@v1.6.2 15 | with: 16 | repo-token: '${{ secrets.GITHUB_TOKEN }}' 17 | -------------------------------------------------------------------------------- /.github/workflows/close_old_issues.yaml: -------------------------------------------------------------------------------- 1 | name: Close Old Issues 2 | on: 3 | schedule: 4 | - cron: "0 0 * * *" 5 | 6 | jobs: 7 | close-issues: 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - name: Checkout Repository 12 | uses: actions/checkout@v3 13 | 14 | - name: Close Old Issues 15 | run: | 16 | open_issues=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ 17 | "https://api.github.com/repos/${{ github.repository }}/issues?state=open" \ 18 | | jq -r '.[] | .number') 19 | 20 | for issue in $open_issues; do 21 | # Get the last updated timestamp of the issue 22 | last_updated=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ 23 | "https://api.github.com/repos/${{ github.repository }}/issues/$issue" \ 24 | | jq -r '.updated_at') 25 | 26 | days_since_update=$(( ( $(date +%s) - $(date -d "$last_updated" +%s) ) / 86400 )) 27 | 28 | if [ $days_since_update -gt 7 ]; then # Modify the condition to check if days_since_update is greater than 7 29 | curl -s -X PATCH -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ 30 | -H "Accept: application/vnd.github.v3+json" \ 31 | -d '{"state":"closed"}' \ 32 | "https://api.github.com/repos/${{ github.repository }}/issues/$issue" 33 | fi 34 | done 35 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ "main" ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ "main" ] 20 | schedule: 21 | - cron: '43 3 * * 6' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} 27 | timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} 28 | permissions: 29 | actions: read 30 | contents: read 31 | security-events: write 32 | 33 | strategy: 34 | fail-fast: false 35 | matrix: 36 | language: [ 'javascript' ] 37 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift' ] 38 | # Use only 'java' to analyze code written in Java, Kotlin or both 39 | # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both 40 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support 41 | 42 | steps: 43 | - name: Checkout repository 44 | uses: actions/checkout@v3 45 | 46 | # Initializes the CodeQL tools for scanning. 47 | - name: Initialize CodeQL 48 | uses: github/codeql-action/init@v2 49 | with: 50 | languages: ${{ matrix.language }} 51 | # If you wish to specify custom queries, you can do so here or in a config file. 52 | # By default, queries listed here will override any specified in a config file. 53 | # Prefix the list here with "+" to use these queries and those in the config file. 54 | 55 | # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs 56 | # queries: security-extended,security-and-quality 57 | 58 | 59 | # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). 60 | # If this step fails, then you should remove it and run the build manually (see below) 61 | - name: Autobuild 62 | uses: github/codeql-action/autobuild@v2 63 | 64 | # ℹ️ Command-line programs to run using the OS shell. 65 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun 66 | 67 | # If the Autobuild fails above, remove it and uncomment the following three lines. 68 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. 69 | 70 | # - run: | 71 | # echo "Run, Build Application using script" 72 | # ./location_of_script_within_repo/buildscript.sh 73 | 74 | - name: Perform CodeQL Analysis 75 | uses: github/codeql-action/analyze@v2 76 | with: 77 | category: "/language:${{matrix.language}}" 78 | -------------------------------------------------------------------------------- /.github/workflows/comment-on-PR.yml: -------------------------------------------------------------------------------- 1 | name: Add Comment to Newly Open PRs 2 | 3 | on: 4 | pull_request_target: 5 | types: [opened] 6 | branches: 7 | - main 8 | - develop 9 | 10 | jobs: 11 | add-comment: 12 | runs-on: ubuntu-latest 13 | permissions: 14 | pull-requests: write 15 | 16 | steps: 17 | - name: Checkout repository 18 | uses: actions/checkout@v3 19 | 20 | - name: Add Comment 21 | uses: actions/github-script@v6 22 | with: 23 | github-token: ${{ secrets.GITHUB_TOKEN }} 24 | script: | 25 | const { pull_request } = context.payload; 26 | const author = pull_request.user.login; 27 | const prNumber = pull_request.number; 28 | const comment = `Thank you, @${author}, for creating this pull request and contributing to GitHub-ReadMe! \nOur review team will thoroughly review the pull request and will reach out to you soon! \nPlease make sure you have marked all the completed tasks as done.\nWe appreciate your patience and contribution!`; 29 | const { owner, repo } = context.repo; 30 | 31 | await github.issues.createComment({ 32 | owner: owner, 33 | repo: repo, 34 | issue_number: prNumber, 35 | body: comment 36 | }); 37 | 38 | console.log(`Comment added to the PR #${prNumber}.`); 39 | -------------------------------------------------------------------------------- /.github/workflows/greetings.yml: -------------------------------------------------------------------------------- 1 | name: Greetings 2 | 3 | on: 4 | fork: 5 | push: 6 | branches: [main] 7 | issues: 8 | types: [opened] 9 | pull_request_target: 10 | types: [opened] 11 | 12 | jobs: 13 | welcome: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v3 17 | - uses: EddieHubCommunity/gh-action-community/src/welcome@main 18 | with: 19 | github-token: ${{ secrets.GITHUB_TOKEN }} 20 | issue-message: "Hello ${{ github.actor }}, thanks for opening a issue, your contribution is valuable to us. The maintainers will review this issue and provide feedback as soon as possible." 21 | pr-message: "Hello ${{ github.actor }}, thanks for rising a Pull request, your contribution is valuable to us. The maintainers will review this Pull Request and provide feedback as soon as possible. Keep the great work up!" 22 | -------------------------------------------------------------------------------- /.github/workflows/lock.yml: -------------------------------------------------------------------------------- 1 | name: 'Lock new issues' 2 | 3 | on: 4 | issues: 5 | types: opened 6 | 7 | permissions: 8 | issues: write 9 | 10 | jobs: 11 | action: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Lock issues 15 | uses: dessant/repo-lockdown@v3 16 | with: 17 | close-issue: false 18 | exclude-issue-labels: 'gssoc23.' 19 | process-only: 'issues' 20 | skip-closed-issue-comment: true 21 | issue-comment: > 22 | To reduce notifications, issues are locked. Your issue will be unlocked when we add the label `gssoc23`. If you're participating in GSSoC'23, please add the `gssoc23` label to your issue. -------------------------------------------------------------------------------- /.github/workflows/npm-publish-github-packages.yml: -------------------------------------------------------------------------------- 1 | # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created 2 | # For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages 3 | 4 | name: Node.js Package 5 | 6 | on: 7 | release: 8 | types: [created] 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v3 15 | - uses: actions/setup-node@v3 16 | with: 17 | node-version: 16 18 | - run: npm ci 19 | - run: npm test 20 | 21 | publish-gpr: 22 | needs: build 23 | runs-on: ubuntu-latest 24 | permissions: 25 | contents: read 26 | packages: write 27 | steps: 28 | - uses: actions/checkout@v3 29 | - uses: actions/setup-node@v3 30 | with: 31 | node-version: 16 32 | registry-url: https://npm.pkg.github.com/ 33 | - run: npm ci 34 | - run: npm publish 35 | env: 36 | NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} 37 | -------------------------------------------------------------------------------- /.github/workflows/static.yml: -------------------------------------------------------------------------------- 1 | # Simple workflow for deploying static content to GitHub Pages 2 | name: Deploy static content to Pages 3 | 4 | on: 5 | # Runs on pushes targeting the default branch 6 | push: 7 | branches: ["main"] 8 | 9 | # Allows you to run this workflow manually from the Actions tab 10 | workflow_dispatch: 11 | 12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 13 | permissions: 14 | contents: read 15 | pages: write 16 | id-token: write 17 | 18 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 19 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 20 | concurrency: 21 | group: "pages" 22 | cancel-in-progress: false 23 | 24 | jobs: 25 | # Single deploy job since we're just deploying 26 | deploy: 27 | environment: 28 | name: github-pages 29 | url: ${{ steps.deployment.outputs.page_url }} 30 | runs-on: ubuntu-latest 31 | steps: 32 | - name: Checkout 33 | uses: actions/checkout@v3 34 | - name: Setup Pages 35 | uses: actions/configure-pages@v3 36 | - name: Upload artifact 37 | uses: actions/upload-pages-artifact@v2 38 | with: 39 | # Upload entire repository 40 | path: '.' 41 | - name: Deploy to GitHub Pages 42 | id: deployment 43 | uses: actions/deploy-pages@v2 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env*.local 29 | .env 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | 38 | # npm 39 | package-lock.json 40 | -------------------------------------------------------------------------------- /Added more features: -------------------------------------------------------------------------------- 1 | Cross-platform compatibility: The platform should be accessible across multiple devices and operating systems, such as desktop computers, laptops, tablets, and smartphones. Users should be able to access their books and reading progress seamlessly across different devices. 2 | 3 | User-friendly interface: The platform should have an intuitive and user-friendly interface that allows users to navigate through their library, search for books, and customize their reading settings easily. 4 | 5 | Book management: Users should be able to organize their digital library effectively, with features like categorization, tagging, and personalized bookshelves. The platform could also support importing and exporting books in various formats. 6 | 7 | Reading customization: Users should have control over their reading experience, such as adjusting font size, background color, line spacing, and font type. Additional features like night mode, bookmarks, annotations, and highlighting can further enhance the reading experience. 8 | 9 | Multiple book formats: The platform should support various book formats, including EPUB, PDF, MOBI, and HTML, allowing users to read a wide range of books without compatibility issues. 10 | 11 | Online bookstores and libraries integration: Integration with online bookstores or libraries can provide users with a vast collection of books to choose from. This can include features like book recommendations, user reviews, and purchasing options. 12 | 13 | Social features: Users should have the ability to share book recommendations, reviews, and highlights with their friends or other users on the platform. Social integration could also include the option to join reading communities or book clubs. 14 | 15 | Offline reading: The platform should provide the option to download books for offline reading, allowing users to access their books even when they don't have an internet connection. 16 | 17 | Sync and backup: Users' reading progress, bookmarks, and annotations should be automatically synced across devices, ensuring a seamless experience. Additionally, regular backups of user data can be offered to prevent data loss. 18 | 19 | Accessibility features: The platform should prioritize accessibility by offering features like text-to-speech functionality for visually impaired users, support for screen readers, and customizable reading settings for users with specific needs. 20 | 21 | Developer-friendly: Being an open source platform, it should have an active community of developers who can contribute to the platform's development, fix bugs, and add new features. The platform should also have a well-documented API and support for third-party plugins or extensions. 22 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines to informatician 2 | 3 | Thank you for your interest in contributing to informatician! This project aims to provide useful resources i.e., Books for information and research purposes to its users. You can learn more about the purpose and features of this project by reading the [README.md](README.md) file. We welcome all types of contributions, such as bug reports, feature requests, documentation improvements, code enhancements, and more. Please read this guide carefully before making your contribution. 4 | 5 | # Reporting Bugs and Issues 6 | 7 | If you encounter a bug or issue while using this project, we encourage you to report it. When reporting bugs, please provide as much information as possible, including: 8 | 9 | • Steps to reproduce the issue 10 | Expected behavior 11 | • Actual behavior 12 | • Any relevant error messages or screenshots 13 | 14 | To report a bug or issue, please follow these steps: 15 | 16 | 1. Go to the Issues section of the repository. 17 | 2. Click on the "New Issue" button. 18 | 3. Fill in the necessary details, following the provided template. 19 | 20 | # Suggesting New Features or Improvements 21 | 22 | If you have an idea for a new feature or an improvement to an existing one, please open an [issue](https://github.com/openeon/informatician/issues/new). 23 | To suggest a new feature, please follow these steps: 24 | 25 | 1. Go to the Issues section of the repository. 26 | 2. Click on the "New Issue" button. 27 | 3. Fill in the necessary details, following the provided template. 28 | 29 | ## Code Formatting and Style Guidelines 30 | 31 | Consistent code formatting and style are important for maintaining a clean and readable codebase. Please adhere to the following guidelines when submitting code changes: 32 | 33 | - Use spaces for indentation (4 spaces per level). 34 | - Follow the established naming conventions for variables, functions, and classes. 35 | - Write clear and concise comments to explain complex code sections. 36 | 37 | # Submitting Pull Requests 38 | 39 | We welcome contributions through pull requests (PRs). To submit a PR, please follow these steps: 40 | 41 | 1. Fork the repository to your GitHub account. 42 | 2. Create a new branch for your changes. 43 | 3. Make the necessary code changes in your branch. 44 | 4. Test your changes thoroughly. 45 | 5. Submit a pull request, explaining the purpose and details of your changes. 46 | 6. Be open to feedback and actively participate in the review process. 47 | 48 | # Communication 49 | 50 | Effective communication is essential for maintaining a collaborative and inclusive environment. When participating in discussions, please: 51 | 52 | - Be respectful and considerate towards others. 53 | - Provide constructive feedback and suggestions. 54 | - Clearly express your thoughts and ideas. 55 | - Be open to different perspectives and opinions. 56 | 57 | # How to Get Help 58 | 59 | If you have any questions or need any help with informatician, please feel free to reach out to us at rohanshx@gmail.com or join our `discussion forum`. You can also find more information on how to use informatician in our `documentation`. We are happy to assist you with any issues or inquiries. 60 | 61 | By following these guidelines, we aim to create a welcoming community where everyone feels comfortable and empowered to contribute. 62 | 63 | Thank you for your interest and support! 64 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Using Node.js base image 2 | FROM node:16-alpine 3 | 4 | # Set the working directory in the container 5 | WORKDIR /app 6 | 7 | # Copy package.json and package-lock.json 8 | COPY package*.json ./ 9 | 10 | # Install app dependencies 11 | RUN npm ci --only=production 12 | 13 | # Copy the rest of the app files 14 | COPY . . 15 | 16 | # Build the app 17 | RUN npm run build 18 | 19 | # Expose port 20 | EXPOSE 3000 21 | 22 | # Start the app 23 | CMD [ "npm", "start" ] 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 INFORMATICIAN 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /STYLE_GUIDE.md: -------------------------------------------------------------------------------- 1 | # Style Guide for informatician 2 | 3 | This style guide provides some general rules and recommendations for writing code and documentation for informatician. Please follow this guide as much as possible to ensure consistency and quality of your contributions. 4 | 5 | ## Code Style 6 | 7 | You can use [Prettier](https://prettier.io/) to format our code automatically. Please install Prettier in your editor or run it before committing your changes. You can also use `npm run format` to format all the files in the project. 8 | 9 | You can use [ESLint](https://eslint.org/) to enforce some code style rules and catch common errors. Please install ESLint in your editor or run it before committing your changes. You can also use `npm run lint` to check all the files in the project. 10 | 11 | Some general code style rules are: 12 | 13 | - Use 2 spaces for indentation 14 | - Use single quotes for strings 15 | - Use semicolons at the end of statements 16 | - Use camelCase for variables and functions 17 | - Use PascalCase for classes and components 18 | - Use const and let instead of var 19 | - Use arrow functions instead of function expressions 20 | - Use template literals instead of string concatenation 21 | - Use destructuring assignment instead of accessing properties 22 | - Use spread operator instead of Object.assign or array methods 23 | - Use async/await instead of callbacks or promises 24 | - Use === and !== instead of == and != 25 | - Use descriptive and meaningful names for variables, functions, classes, and components 26 | - Avoid using global variables or modifying built-in objects 27 | - Avoid using magic numbers or hard-coded values 28 | - Avoid using console.log or debugger statements 29 | - Add comments to explain complex or unclear logic 30 | - Document your code using [JSDoc](https://jsdoc.app/) syntax 31 | 32 | For more details and examples, see the [Prettier](https://prettier.io/docs/en/options.html) and [ESLint](https://eslint.org/docs/rules/) documentation. 33 | 34 | ## Documentation Style 35 | 36 | We use [Markdown](https://daringfireball.net/projects/markdown/) to write our documentation. Please follow the [Markdown style guide](https://google.github.io/styleguide/docguide/style.html) for general rules and recommendations on how to write Markdown files. 37 | 38 | We also use some custom markup syntax for specific features on docs.github.com, such as alerts, tables, images, links, and more. Please see our [markup reference guide](https://github.com/github/docs/blob/main/contributing/content-markup-reference.md) for more details and examples on how to use these features. 39 | 40 | Some general documentation style rules are: 41 | 42 | - Use sentence case for headings and titles 43 | - Use active voice instead of passive voice 44 | - Use present tense instead of past or future tense 45 | - Use simple and clear language 46 | - Use short and concise sentences and paragraphs 47 | - Use lists, tables, code blocks, images, and other visual aids to break up text and improve readability 48 | - Use consistent terminology and avoid jargon or slang 49 | - Use positive and polite tone and avoid negative or harsh words 50 | - Use gender-neutral pronouns and avoid assumptions about the audience 51 | - Provide examples and screenshots to illustrate concepts and procedures 52 | - Provide links to relevant resources and references 53 | - Provide feedback and contact information at the end of each document 54 | 55 | For more details and examples, see the [Microsoft Style Guide](https://docs.microsoft.com/en-us/style-guide/welcome/). 56 | 57 | If you have any feedback or questions, please feel free to reach out to us at rohanshx@gmail.com or join our `discussion forum` . We would love to hear from you! -------------------------------------------------------------------------------- /app/about/page.jsx: -------------------------------------------------------------------------------- 1 | import Feature from "@/components/About/Feature"; 2 | import Hero from "@/components/About/Hero"; 3 | import Testimonial from "@/components/About/Testimonial"; 4 | 5 | export const metadata = { 6 | title: "About", 7 | } 8 | 9 | export default function About () { 10 | return ( 11 |
12 | 13 | 14 | 15 |
16 | ); 17 | }; -------------------------------------------------------------------------------- /app/addBooks/page.jsx: -------------------------------------------------------------------------------- 1 | import AddBooks from './AddBooks' 2 | 3 | export const metadata = { 4 | title: "Add Books", 5 | }; 6 | 7 | export default function page() { 8 | return ( 9 | 10 | ) 11 | } 12 | -------------------------------------------------------------------------------- /app/api/auth/[...nextauth]/route.js: -------------------------------------------------------------------------------- 1 | import NextAuth from "next-auth"; 2 | import CredentialsProvider from "next-auth/providers/credentials"; 3 | import GoogleProvider from "next-auth/providers/google"; 4 | import prisma from "@/libs/prismadb" 5 | import { PrismaAdapter } from "@auth/prisma-adapter"; 6 | import bcrypt from "bcrypt" 7 | 8 | export const authOptions = { 9 | adapter: PrismaAdapter(prisma), 10 | providers: [ 11 | GoogleProvider({ 12 | clientId: process.env.GOOGLE_ID, 13 | clientSecret: process.env.GOOGLE_SECRET 14 | }), 15 | CredentialsProvider({ 16 | name: "credentials", 17 | credentials:{ 18 | email: {label: "Email", type:"text", placeholder:"Enter your Email"}, 19 | 20 | password: { label: "Password", type: "Enter your Password" }, 21 | 22 | confirmPassword: { label: "Confirm Password", type: "Confirm your Password" }, 23 | }, 24 | 25 | async authorize(credentials){ 26 | // Check if email and password is there 27 | if(!credentials.email || !credentials.password){ 28 | throw new Error("Please Enter your Email & Password"); 29 | } 30 | 31 | // check if user exist 32 | const user = await prisma.user.findUnique({ 33 | where:{ 34 | email: credentials.email 35 | } 36 | }); 37 | 38 | // if no user exist or user not found 39 | if(!user || !user?.hashedPassword){ 40 | throw new Error("User Not Found!"); 41 | } 42 | 43 | // Check Password Matches 44 | const passwordMatches = await bcrypt.compare(credentials.password, user.hashedPassword); 45 | 46 | // if password does not match 47 | if(!passwordMatches){ 48 | throw new Error("Incorrect Password!") 49 | } 50 | 51 | return user; 52 | } 53 | }) 54 | ], 55 | 56 | secret: process.env.SECRET, 57 | session:{ 58 | strategy:'jwt' 59 | }, 60 | debug: process.env.NODE_ENV === "development" 61 | } 62 | 63 | const handler = NextAuth(authOptions) 64 | export { handler as GET, handler as POST} -------------------------------------------------------------------------------- /app/api/book/[id]/route.js: -------------------------------------------------------------------------------- 1 | import Book from "@/model/Book" 2 | import { connectedToDB } from "@/utils/database"; 3 | 4 | 5 | export const GET = async (req, {params}) =>{ 6 | try { 7 | await connectedToDB(); 8 | 9 | const book = await Book.findById(params.id); 10 | 11 | if(!book) return new Response('Book not found',{status:404}) 12 | 13 | return new Response(JSON.stringify(book),{status:200}) 14 | 15 | } catch (error) { 16 | new Response("Failed to fetch book data",{status:500}) 17 | } 18 | } 19 | 20 | export const PATCH = async (req, {params})=>{ 21 | const {bookName, 22 | authorName, 23 | publisher, 24 | pages, 25 | img, 26 | bookpdf, 27 | category} = await req.json() 28 | try { 29 | await connectedToDB(); 30 | 31 | const existingBook = await Book.findById(params.id); 32 | 33 | if(!existingBook) return new Response("Book is not found", {status:404}); 34 | 35 | existingBook.bookName = bookName; 36 | existingBook.authorName = authorName; 37 | existingBook.publisher = publisher; 38 | existingBook.pages = pages; 39 | existingBook.img = img; 40 | existingBook.bookpdf = bookpdf; 41 | existingBook.category = category; 42 | 43 | await existingBook.save(); 44 | 45 | return new Response(JSON.stringify(existingBook),{status:200}) 46 | } catch (error) { 47 | return new Response("Failed to updated the book",{status:500}) 48 | } 49 | } 50 | 51 | export const DELETE = async (req, {params})=>{ 52 | 53 | try { 54 | await connectedToDB(); 55 | await Book.findByIdAndRemove(params.id); 56 | return new Response('Book Deleted successfully',{status:200}) 57 | } catch (error) { 58 | return new Response("Failed to delete the book",{status:500}) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /app/api/book/category/route.js: -------------------------------------------------------------------------------- 1 | import Book from "@/model/Book" 2 | import { connectedToDB } from "@/utils/database"; 3 | 4 | export const GET = async (req, {params}) =>{ 5 | 6 | await connectedToDB(); 7 | 8 | if (!params) return new Response("Missing parameters", { status: 400 }); 9 | 10 | const category = params.category; 11 | try { 12 | const books = await Book.find({ category: category }); 13 | console.log(books) 14 | return new Response(JSON.stringify(books),{status:200}) 15 | 16 | } catch (error) { 17 | new Response("Failed to fetch category data",{status:500}) 18 | } 19 | } -------------------------------------------------------------------------------- /app/api/book/new/route.js: -------------------------------------------------------------------------------- 1 | import { connectedToDB } from "@/utils/database"; 2 | import Book from "@/model/Book" 3 | 4 | export const POST = async(req)=>{ 5 | const {bookName, 6 | authorName, 7 | publisher, 8 | pages, 9 | img, 10 | bookpdf, 11 | category} = await req.json(); 12 | 13 | try { 14 | await connectedToDB(); 15 | const newBook = new Book({ 16 | bookName, 17 | authorName, 18 | publisher, 19 | pages, 20 | img, 21 | bookpdf, 22 | category 23 | }) 24 | 25 | await newBook.save(); 26 | 27 | return new Response(JSON.stringify(newBook),{status:201}) 28 | 29 | } catch (error) { 30 | return new Response('Failed to create a new book',{status:500}) 31 | } 32 | } -------------------------------------------------------------------------------- /app/api/book/route.js: -------------------------------------------------------------------------------- 1 | import Book from "@/model/Book" 2 | import { connectedToDB } from "@/utils/database"; 3 | 4 | export const GET = async(req)=>{ 5 | 6 | try { 7 | await connectedToDB(); 8 | 9 | const books = await Book.find(); 10 | 11 | return new Response(JSON.stringify(books),{status:200}) 12 | 13 | } catch (error) { 14 | new Response('Failed to load the all books',{status:500}) 15 | console.log(error) 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /app/api/mail/route.js: -------------------------------------------------------------------------------- 1 | import mailer from "nodemailer"; 2 | import dotenv from "dotenv"; 3 | 4 | dotenv.config(); 5 | 6 | export const POST = (req, res) => { 7 | console.log(req.body); 8 | 9 | let transporter = mailer.createTransport({ 10 | service: 'gmail', 11 | auth: { 12 | user: process.env.GMAIL, 13 | pass: process.env.GOOGLEAPPPASSWORD 14 | } 15 | }); 16 | 17 | let options = { 18 | from: process.env.GMAIL, 19 | to: process.env.GMAIL, 20 | subject: "Contact Request", 21 | html: ` 22 |
23 |

You have a new contact request.

24 |

Contact Details

25 |
    26 |
  • Name: ${req.body.name}
  • 27 |
  • Email: ${req.body.email}
  • 28 |
  • Subject: Contact Request
  • 29 |
  • Message: ${req.body.message}
  • 30 |
31 |
32 | ` 33 | }; 34 | 35 | try { 36 | transporter.sendMail(options, function (error, info) { 37 | if (error) { 38 | console.error(error); 39 | res.status(500).json('Could not send Email'); 40 | } else { 41 | console.log("Email Sent Successfully"); 42 | res.status(200).json('Email Sent Successfully'); 43 | } 44 | }); 45 | } catch (error) { 46 | console.error(error); 47 | res.status(500).json('Internal Server Error'); 48 | } 49 | }; 50 | -------------------------------------------------------------------------------- /app/api/newsletter/route.js: -------------------------------------------------------------------------------- 1 | import Newsletter from "@/model/Newsletter"; 2 | import nodemailer from "nodemailer"; 3 | import { connectedToDB } from "@/utils/database"; 4 | import fetch from "node-fetch"; 5 | 6 | export const POST = async (req, res) => { 7 | await connectedToDB(); 8 | 9 | async function getBooks() { 10 | const url = "https://hapi-books.p.rapidapi.com/week/horror/5"; 11 | const options = { 12 | method: "GET", 13 | headers: { 14 | "X-RapidAPI-Key": process.env.RAPID_API_KEY, 15 | "X-RapidAPI-Host": "hapi-books.p.rapidapi.com", 16 | }, 17 | }; 18 | 19 | try { 20 | const response = await fetch(url, options); 21 | const result = await response.json(); 22 | return result; 23 | } catch (error) { 24 | console.error(error); 25 | throw new Error(error.message); 26 | } 27 | } 28 | 29 | const transporter = nodemailer.createTransport({ 30 | service: "gmail", 31 | auth: { 32 | user: process.env.SENDEREMAIL, 33 | pass: process.env.PASSWORD, 34 | }, 35 | }); 36 | 37 | try { 38 | const result = await getBooks(); 39 | const users = await Newsletter.find(); 40 | const recipientEmails = users.map((user) => user.email); 41 | const info = await transporter.sendMail({ 42 | from: `"" ${process.env.SENDEREMAIL}`, 43 | to: recipientEmails, 44 | subject: "New Enquiry", 45 | html: result 46 | .map((book) => { 47 | return `

${book.name}

${book.url}

`; 48 | }) 49 | .join(""), 50 | }); 51 | 52 | res.json({ message: "Email sent successfully" }); 53 | } catch (err) { 54 | console.error(err); 55 | res.status(500).json({ error: "An error occurred" }); 56 | } 57 | }; 58 | -------------------------------------------------------------------------------- /app/api/newsletter/user/route.js: -------------------------------------------------------------------------------- 1 | import Newsletter from "@/model/Newsletter"; 2 | import { connectedToDB } from "@/utils/database"; 3 | 4 | export const POST = async (req, res) => { 5 | await connectedToDB(); 6 | try { 7 | const newUser = new Newsletter(req.body); 8 | await newUser.save(); 9 | res.status(200).json(newUser); 10 | } catch (err) { 11 | console.error(err); 12 | res.status(500).json({ error: "Internal Server Error" }); 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /app/api/register/route.js: -------------------------------------------------------------------------------- 1 | import bcrypt from "bcrypt" 2 | import prisma from "@/libs/prismadb" 3 | import { NextResponse } from "next/server" 4 | 5 | export const POST = async (req)=>{ 6 | const body = await req.json(); 7 | const {name,email, password, confirmPassword} = body; 8 | 9 | if(!name || !email || !password || !confirmPassword){ 10 | return new NextResponse("Missing required fields", {status:400}); 11 | } 12 | 13 | 14 | const exist = await prisma.user.findUnique({ 15 | where:{ 16 | email 17 | } 18 | }); 19 | 20 | if(exist) { 21 | throw new Error("Email already exists") 22 | } 23 | 24 | const hashedPassword = await bcrypt.hash(password, 10) 25 | 26 | const user = await prisma.user.create({ 27 | data:{ 28 | name, 29 | email, 30 | password: hashedPassword, 31 | confirmPassword: hashedPassword 32 | } 33 | }); 34 | 35 | return NextResponse.json(user) 36 | 37 | } -------------------------------------------------------------------------------- /app/awards/BookAward.jsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { useEffect } from "react"; 4 | import "aos/dist/aos.css"; 5 | import Aos from 'aos'; 6 | import Image from 'next/image' 7 | import Link from 'next/link' 8 | import React from 'react' 9 | 10 | export default function BookAward({award}) { 11 | useEffect(() => { 12 | Aos.init({ 13 | once: false, 14 | }); 15 | Aos.refresh(); 16 | }, []); 17 | return ( 18 |
24 |
25 |
26 |
27 | {award.name} 35 |
36 |
37 |
38 |

{award.name}

39 |
{award.description}
40 |
41 | Some Winners: 42 | {award.winners.map((winner, index) => ( 43 |

44 | {index + 1}. {winner.category}: "{winner.book}" by{" "} 45 | {winner.author} 46 |

47 | ))} 48 |
49 |
50 | 55 |
56 |
57 |
58 |
59 | ) 60 | } 61 | -------------------------------------------------------------------------------- /app/awards/page.js: -------------------------------------------------------------------------------- 1 | import bookAwardsData from "./bookAwardsData"; 2 | import BookAward from "./BookAward"; 3 | 4 | export const metadata = { 5 | title: "Awards", 6 | }; 7 | 8 | const BookAwards = () => { 9 | return ( 10 |
11 |

Book Awards

12 | {bookAwardsData.map((award) => ( 13 | 14 | ))} 15 |
16 | ); 17 | }; 18 | 19 | export default BookAwards; 20 | -------------------------------------------------------------------------------- /app/benefits/page.js: -------------------------------------------------------------------------------- 1 | import Image from "next/image"; 2 | 3 | import img1 from "@/public/assets/benefits/benefit-1.webp"; 4 | import img2 from "@/public/assets/benefits/benefit-2.webp"; 5 | import img3 from "@/public/assets/benefits/benefit-3.webp"; 6 | import img4 from "@/public/assets/benefits/benefit-4.webp"; 7 | import img5 from "@/public/assets/benefits/benefit-5.webp"; 8 | 9 | export const metadata = { 10 | title: "Benefits", 11 | }; 12 | 13 | export default function BenefitsOfReading(props) { 14 | return ( 15 |
16 |
17 |

18 | Benefits of Reading 19 |

20 |

21 | Reading is a wonderful activity that offers numerous benefits to 22 | individuals of all ages. Whether you prefer fiction, non-fiction, or 23 | any other genre, here are some key advantages of reading: 24 |

25 | 26 | 32 | 38 | 44 | 50 | 56 |
57 |
58 | ); 59 | } 60 | 61 | function Card({ title, para, src, alt }) { 62 | return ( 63 |
64 |
65 |
66 | {alt} 74 |
75 |
76 |

77 | {title} 78 |

79 |

{para}

80 |
81 |
82 |
83 | ); 84 | } 85 | -------------------------------------------------------------------------------- /app/bookmark/Bookmark.jsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import Image from "next/image"; 3 | import React, { useState } from "react"; 4 | 5 | const Bookmark = () => { 6 | const initialBookmarks = [ 7 | { 8 | id: 1, 9 | title: "Book 1 Title", 10 | description: "Book 1 Description", 11 | imageUrl: "https://img.freepik.com/free-vector/hand-drawn-bookmark-template_23-2149336542.jpg?w=2000", 12 | }, 13 | { 14 | id: 2, 15 | title: "Book 2 Title", 16 | description: "Book 2 Description", 17 | imageUrl: "https://img.freepik.com/free-vector/hand-drawn-bookmark-template_23-2149336542.jpg?w=2000", 18 | }, 19 | { 20 | id: 3, 21 | title: "Book 3 Title", 22 | description: "Book 3 Description", 23 | imageUrl: "https://img.freepik.com/free-vector/hand-drawn-bookmark-template_23-2149336542.jpg?w=2000", 24 | }, 25 | // Add more book items here 26 | ]; 27 | 28 | const [bookmarks, setBookmarks] = useState(initialBookmarks); 29 | 30 | const handleRemoveBookmark = (id) => { 31 | const updatedBookmarks = bookmarks.filter((bookmark) => bookmark.id !== id); 32 | setBookmarks(updatedBookmarks); 33 | }; 34 | 35 | return ( 36 |
37 |
38 | {bookmarks.map((bookmark) => ( 39 |
43 | {bookmark.title} 53 |

60 | {bookmark.title} 61 |

62 |

63 | {bookmark.description} 64 |

65 | 72 |
73 | ))} 74 |
75 |
76 |
77 | ); 78 | }; 79 | 80 | export default Bookmark; 81 | -------------------------------------------------------------------------------- /app/bookmark/page.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Bookmark from "./Bookmark"; 3 | 4 | export const metadata = { 5 | title: "Bookmark", 6 | }; 7 | 8 | export default function page() { 9 | return ( 10 |
11 |

12 | Bookmarks 13 |

14 | 15 |
16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /app/books/Spinner.css: -------------------------------------------------------------------------------- 1 | .loader { 2 | width: 48px; 3 | height: 48px; 4 | border-radius: 50%; 5 | position: relative; 6 | animation: rotate 1s linear infinite; 7 | } 8 | .loader::before, 9 | .loader::after { 10 | content: ""; 11 | box-sizing: border-box; 12 | position: absolute; 13 | inset: 0px; 14 | border-radius: 50%; 15 | border: 5px solid #fff; 16 | animation: prixClipFix 2s linear infinite; 17 | } 18 | .loader::after { 19 | inset: 8px; 20 | transform: rotate3d(90, 90, 0, 180deg); 21 | border-color: #ff3d00; 22 | } 23 | 24 | @keyframes rotate { 25 | 0% { 26 | transform: rotate(0deg); 27 | } 28 | 100% { 29 | transform: rotate(360deg); 30 | } 31 | } 32 | 33 | @keyframes prixClipFix { 34 | 0% { 35 | clip-path: polygon(50% 50%, 0 0, 0 0, 0 0, 0 0, 0 0); 36 | } 37 | 50% { 38 | clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 0, 100% 0, 100% 0); 39 | } 40 | 75%, 41 | 100% { 42 | clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 100%, 100% 100%, 100% 100%); 43 | } 44 | } 45 | 46 | #default-search{ 47 | height: 3.5rem; 48 | } 49 | 50 | #search-button-2{ 51 | height: 3.5rem; 52 | } 53 | -------------------------------------------------------------------------------- /app/books/[id]/page.jsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link"; 2 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; 3 | import { faBookmark } from "@fortawesome/free-regular-svg-icons"; 4 | import { Books } from "@/utils/Constants"; 5 | import Image from "next/image"; 6 | import RStar from "@/components/RStar"; 7 | 8 | export const metadata = { 9 | title: "Book", 10 | }; 11 | 12 | export default function BookComponent({ params }) { 13 | const { id } = params; 14 | const bookDetails = Books[id - 1]; 15 | 16 | return ( 17 |
18 |
19 |

{bookDetails?.title}

20 |
21 | 25 | Author: {bookDetails?.author} 26 | 27 |
28 |
29 | 30 | {bookDetails?.ratings} Ratings 31 |
32 |
33 |

About this Book

34 |
35 |

36 | {bookDetails?.aboutBook} 37 |

38 |

{bookDetails?.bookSynapsis}

39 |
40 |
41 |
42 |

43 | Language: 44 | {bookDetails?.language} 45 |

46 |

47 | Publisher: 48 | {bookDetails?.author} 49 |

50 |

51 | Release Date: 52 | {bookDetails?.releaseDate} 53 |

54 |

55 | ISBN: 56 | {bookDetails?.isbn} 57 |

58 |
59 |
60 |
61 |
62 | {bookDetails?.title} 70 |
71 |
72 | 78 | 84 |
85 | 91 |
92 |
93 | ); 94 | } 95 | -------------------------------------------------------------------------------- /app/contact/page.jsx: -------------------------------------------------------------------------------- 1 | import Contact from "./Contact"; 2 | 3 | export const metadata = { 4 | title: "Contact", 5 | }; 6 | 7 | export default function page() { 8 | return ( 9 |
10 |
11 |

Contact Us

12 |

13 | We'd love to hear from you! Reach out to us for any inquiries, 14 | feedback, or collaboration opportunities. 15 |

16 |
17 | 18 |
19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /app/develop/page.jsx: -------------------------------------------------------------------------------- 1 | import construct from '@/public/assets/error/construct.webp'; 2 | import Image from 'next/image'; 3 | 4 | export const metadata = { 5 | title: "Develop", 6 | }; 7 | 8 | const Develop = (props) => { 9 | return ( 10 |
11 |

Under Development

12 |
13 | a computer under construction with crane 14 |
15 |

This page is currently under development. Please check back later.

16 |
17 | ); 18 | }; 19 | 20 | export default Develop; 21 | -------------------------------------------------------------------------------- /app/faq/Accordion.jsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | // use client 4 | import { useState } from "react"; 5 | 6 | export default function AccordionItem({ title, content }) { 7 | const [expanded, setExpanded] = useState(false); 8 | 9 | const toggleAccordion = () => { 10 | setExpanded(!expanded); 11 | }; 12 | 13 | return ( 14 |
19 | 33 |
38 |

{content}

39 |
40 |
41 | ); 42 | } 43 | -------------------------------------------------------------------------------- /app/faq/faqData.js: -------------------------------------------------------------------------------- 1 | const faqData = [ 2 | { 3 | title: "Q: How can one develop a habit of reading regularly?", 4 | content: "A: One can start by setting aside dedicated time for reading each day. Creating a comfortable reading environment and choosing books that genuinely interest you can also help." 5 | }, 6 | { 7 | title: "Q: What are some common reasons why people abandon books midway?", 8 | content: "A: Some reasons include a lack of interest in the content or finding it difficult to connect with the writing style. However, there are many other books to choose from." 9 | }, 10 | { 11 | title: "Q: What are the benefits of reading regularly?", 12 | content: "A: Reading regularly has numerous benefits: improved cognitive function, increased knowledge, and enhanced focus & concentration. It reduces stress and promotes relaxation by immersing you in a different world or story. Reading improves one's vocabulary, language skills, and writing abilities, making one an effective communicator." 13 | }, 14 | { 15 | title: "Q: What are some strategies for staying motivated to read?", 16 | content: "A: To stay motivated to read, it can be helpful to set reading goals and establish a regular reading routine. Additionally, having a consistent reading routine helps to make reading a habit and ensures one to set aside dedicated time for it." 17 | } 18 | ] 19 | 20 | export default faqData; 21 | -------------------------------------------------------------------------------- /app/faq/page.js: -------------------------------------------------------------------------------- 1 | import helpImage from "@/public/assets/mainPages/help.webp"; 2 | import Image from "next/image"; 3 | import Link from "next/link"; 4 | import faqData from "./faqData"; 5 | import AccordionItem from "./Accordion"; 6 | 7 | export const metadata = { 8 | title: "FAQ", 9 | }; 10 | 11 | export default function page() { 12 | return ( 13 |
14 |
15 |

16 | Informatician Help Center 17 |

18 | a person wearing a headset 24 |
25 |
26 |

27 | Frequently Asked Questions 28 |

29 |
30 | {faqData.map((faq, index)=>{ 31 | return 35 | })} 36 | 37 |
38 |
39 |
40 |

41 | Need More Help? 42 |

43 |

44 | If you have any other questions or need further assistance, please 45 | don't hesitate to{" "} 46 | 47 | contact 48 | {" "} 49 | our customer support team. We are here to help you! 50 |

51 |
52 |
53 | ); 54 | }; 55 | -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-xyz/informatician/cbc36c2662352cbe2f2f597f9b2d368971062ad2/app/favicon.ico -------------------------------------------------------------------------------- /app/formats/SBook.jsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import { useEffect } from "react"; 3 | import "aos/dist/aos.css"; 4 | import AOS from "aos"; 5 | import Image from "next/image"; 6 | import Link from "next/link"; 7 | import React from "react"; 8 | 9 | export default function SBook({ bookFormat }) { 10 | useEffect(() => { 11 | AOS.init({ 12 | once: false, 13 | }); 14 | AOS.refresh(); 15 | }, []); 16 | return ( 17 |
23 |
24 |
25 |
26 | {bookFormat.name} 34 |
35 |
36 |
37 |

{bookFormat.name}

38 |
{bookFormat.description}
39 |
40 | Some Winners: 41 | {bookFormat.topBooks.map((winner, index) => ( 42 |

43 | {index + 1}. {winner.title} {winner.author && "by"}{" "} 44 | {winner.author} 45 |

46 | ))} 47 |
48 |
49 | 56 |
57 |
58 |
59 |
60 | ); 61 | } 62 | -------------------------------------------------------------------------------- /app/formats/[slug]/page.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import bookFormatsData from '../bookFormatsData'; 3 | import Image from "next/image"; 4 | 5 | export default function Posts({ params }) { 6 | const query = params.slug; 7 | const queryData = bookFormatsData.find((format) => format.slug === query); 8 | 9 | if (!queryData) { 10 | return ( 11 |

12 | Format not found 13 |

14 | ); 15 | } 16 | 17 | return ( 18 |
19 |

20 | {queryData.title} 21 |

22 |

{queryData.description}

23 |
24 |
25 | 31 |
32 |
33 |
    34 | {queryData.topBooks.map((book, index) => ( 35 |
  1. {index+1}. {book.title} | {book.author}
  2. 36 | ))} 37 |
38 |
39 | ); 40 | } 41 | -------------------------------------------------------------------------------- /app/formats/bookFormatsData.js: -------------------------------------------------------------------------------- 1 | import ebook from "@/public/assets/Formats/ebook.webp"; 2 | import audiobook from "@/public/assets/Formats/audiobook.webp"; 3 | import paperback from "@/public/assets/Formats/paperback.webp"; 4 | import comics from "@/public/assets/Formats/comics.webp"; 5 | import magazines from "@/public/assets/Formats/magazines.webp"; 6 | 7 | const bookFormatsData = [ 8 | { 9 | title: "Ebooks", 10 | slug:"ebook", 11 | image: ebook, 12 | description: 13 | "E-books are digital versions of printed books that can be read on electronic devices such as e-readers, tablets, or smartphones. They offer a convenient way for readers to access a wide range of literature without the need for physical books.", 14 | topBooks: [ 15 | { 16 | title: "Never Lie: An addictive psychological thriller", 17 | author: "Freida McFadden", 18 | }, 19 | { 20 | title: "Maybe Someday", 21 | author: "Colleen Hoover", 22 | }, 23 | { 24 | title: "The Housemaid", 25 | author: "Freida McFadden", 26 | }, 27 | ], 28 | }, 29 | { 30 | title: "Audiobooks", 31 | slug:"audiobook", 32 | image: audiobook, 33 | description: 34 | "Audiobooks provide an immersive storytelling experience by allowing readers to listen to narrators who bring the characters and narratives to life through spoken word. They are particularly beneficial for readers who prefer to listen to stories rather than read them.", 35 | topBooks: [ 36 | {title: "Audible"}, 37 | {title: "Scribd"}, 38 | {title: "Blinkist"}, 39 | ], 40 | }, 41 | { 42 | title: "Paperback Books", 43 | slug:"paperback", 44 | image: paperback, 45 | description: 46 | "Paperback books are the most common and affordable format. They are lightweight and portable, making them easy to carry and hold. Paperback books offer a tactile experience, allowing readers to flip through pages and physically interact with the text.", 47 | topBooks: [ 48 | { 49 | title: "Atomic Habits", 50 | author: "James Clear", 51 | }, 52 | { 53 | title: "The Psychology of Money", 54 | author: "Morgan Housel", 55 | }, 56 | { 57 | title: "Ikigai", 58 | author: "Francesc Miralles", 59 | }, 60 | ], 61 | }, 62 | { 63 | title: "Digital Magazines", 64 | slug:"magazines", 65 | image: magazines, 66 | description: 67 | "Digital magazines provide a visual and interactive reading experience. They cover a wide range of topics and interests, from lifestyle and fashion to technology and science. Digital magazines often include multimedia elements, enhancing the reading experience.", 68 | topBooks: [ 69 | {title: "National Geographic"}, 70 | {title: "People"}, 71 | {title: "Forbes"}, 72 | ], 73 | }, 74 | { 75 | title: "Comics and Graphic Novels", 76 | slug:"comics", 77 | image: comics, 78 | description: 79 | "Comics and graphic novels combine illustrations and text to tell stories in a visually engaging format. They cover various genres, including superheroes, fantasy, science fiction, memoirs, and more. Comics and graphic novels offer a unique reading experience.", 80 | topBooks: [ 81 | {title: "Detective Conan"}, 82 | {title: "Naruto"}, 83 | {title: "Dragon Ball"}, 84 | ], 85 | }, 86 | ]; 87 | 88 | export default bookFormatsData; 89 | -------------------------------------------------------------------------------- /app/formats/page.js: -------------------------------------------------------------------------------- 1 | import bookFormatsData from "./bookFormatsData"; 2 | import SBook from "./SBook"; 3 | 4 | export const metadata = { 5 | title: "Book Formats", 6 | }; 7 | 8 | const BookbookFormats = () => { 9 | return ( 10 |
11 |

Book Formats

12 | {bookFormatsData.map((bookFormat) => ( 13 | 14 | ))} 15 |
16 | ); 17 | }; 18 | 19 | export default BookbookFormats; 20 | -------------------------------------------------------------------------------- /app/genre/SGenre.jsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import { useEffect } from "react"; 3 | import "aos/dist/aos.css"; 4 | import AOS from "aos"; 5 | import Image from "next/image"; 6 | import Link from "next/link"; 7 | 8 | export default function SGenre({ genre }) { 9 | useEffect(() => { 10 | AOS.init({ 11 | once: false, 12 | }); 13 | AOS.refresh(); 14 | }, []); 15 | return ( 16 |
22 |
23 |
24 |
25 | {genre.title} 32 |
33 |
34 |
35 |

{genre.title}

36 |
{genre.description}
37 |
38 | Top 3 Books: 39 | {genre.topBooks.map((book, index) => ( 40 |

41 | {index + 1}. {book.title} by {book.author} 42 |

43 | ))} 44 |
45 |
46 | 53 |
54 |
55 |
56 |
57 | ); 58 | } 59 | -------------------------------------------------------------------------------- /app/genre/[slug]/page.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import genreFormatsData from '../genreDetailsData'; 3 | import Image from "next/image"; 4 | 5 | export default function Posts({ params }) { 6 | const query = params.slug; 7 | const queryData = genreFormatsData.find((format) => format.slug === query); 8 | 9 | if (!queryData) { 10 | return ( 11 |

12 | Format not found{query} 13 |

14 | ); 15 | } 16 | 17 | return ( 18 |
19 |

20 | {queryData.title} 21 |

22 |

{queryData.description}

23 |
24 |
25 | 31 |
32 |
33 |
    34 | {queryData.topBooks.map((book, index) => ( 35 |
  1. {index+1}. {book.title} | {book.author}
  2. 36 | ))} 37 |
38 |
39 | ); 40 | } 41 | -------------------------------------------------------------------------------- /app/genre/page.js: -------------------------------------------------------------------------------- 1 | import genreDetailsData from "./genreDetailsData"; 2 | import SGenre from "./SGenre"; 3 | 4 | export const metadata = { 5 | title: "Genre", 6 | }; 7 | 8 | const GenrePage = () => { 9 | return ( 10 |
11 |

Book Genres

12 | {genreDetailsData.map((genre) => ( 13 | 14 | ))} 15 |
16 | ); 17 | }; 18 | 19 | export default GenrePage; 20 | -------------------------------------------------------------------------------- /app/googlebooks/[bookId]/[isbn]/page.jsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import React, { useEffect, useState } from "react"; 4 | import { useLocation } from "react-router-dom"; 5 | 6 | 7 | 8 | 9 | 10 | //0415105145 11 | //0738531367 12 | const BookPreview = ({ params }) => { 13 | // const [isbn, setIsbn] = useState("0738531367"); // Default ISBN 14 | const { isbn } = params; 15 | 16 | // Create a template string for the newsletter HTML with a placeholder for the ISBN 17 | const newsletterHtmlTemplate = ` 18 | 19 | 20 | 38 | 39 | 40 | 54 | 55 | 56 |
57 | 58 | 59 | `; 60 | 61 | // Replace the placeholder in the newsletterHtmlTemplate with the actual ISBN 62 | const newsletterHtml = newsletterHtmlTemplate.replace("${isbn}", isbn); 63 | 64 | return ( 65 |
66 | 67 | 79 |
80 | ); 81 | }; 82 | 83 | export default BookPreview; -------------------------------------------------------------------------------- /app/join/page.js: -------------------------------------------------------------------------------- 1 | import Header from "@/components/join/Header"; 2 | import Benefits from "@/components/join/Benefits"; 3 | import ImgSection from "@/components/join/ImgSection"; 4 | import Employee from "@/components/join/Employee"; 5 | import Community from "@/components/join/Community"; 6 | import JobSection from "@/components/join/JobSection"; 7 | 8 | export const metadata = { 9 | title: "Join", 10 | }; 11 | 12 | export default function JoinPage() { 13 | return ( 14 |
15 |
16 | 17 | 18 | 19 | 20 | 21 |
22 | ); 23 | }; 24 | ; 25 | -------------------------------------------------------------------------------- /app/layout.jsx: -------------------------------------------------------------------------------- 1 | /** @format */ 2 | "use client"; 3 | 4 | import "@/styles/globals.css"; 5 | import { Inter } from "next/font/google"; 6 | import Preloader from "@/components/Preloader/Preloader"; // Import the Preloader component 7 | const Navbar = dynamic(() => import("@/components/Navbar/Navbar")); 8 | import dynamic from "next/dynamic"; 9 | import Footer from "@/components/Footer/Footer"; 10 | import { ThemeProvider } from "@/components/theme/theme-provider"; 11 | import ScrollToTopButton from "@/components/ScrollButton/ScrollButton"; 12 | import { Suspense } from "react"; 13 | import Provider from "@/context/AuthContext"; 14 | import { Toaster } from "react-hot-toast"; 15 | import { useState, useEffect } from "react"; 16 | 17 | // Import & exporting the metadata 18 | import { metadata } from "./metadata"; 19 | export { metadata }; 20 | 21 | const inter = Inter({ subsets: ["latin"] }); 22 | 23 | export default function RootLayout({ children }) { 24 | const [loading, setLoading] = useState(true); 25 | useEffect(() => { 26 | setTimeout(() => { 27 | setLoading(false); 28 | }, 3200); 29 | }, []); 30 | return ( 31 | 32 | 33 | 34 | 35 | {/* Add the Preloader component here */} 36 | {loading ? ( 37 | 38 | ) : ( 39 | <> 40 | Loading...}> 41 | 42 | 43 | 44 | {children} 45 |