├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── issue_template.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── PRValidator.yml │ ├── auto_label.yaml │ ├── check-merge-conflicts.yml │ ├── check_fork_status.yaml │ ├── issue_thank.yaml │ └── post_pr_thankyou.yaml ├── .gitignore ├── .htaccess ├── .vscode └── settings.json ├── 25a7f6e52f7d373e7db6d63c4bdb38d1.jpg ├── 404.html ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Carousel.js ├── Instructions.txt ├── LICENSE ├── OIP (10).jpeg ├── OIP (11).jpeg ├── OIP (12).jpeg ├── OIP (13).jpeg ├── OIP (5).jpeg ├── OIP (6).jpeg ├── OIP (7).jpeg ├── OIP (8).jpeg ├── OIP (9).jpeg ├── README.md ├── Scroll_and_progressbar.css ├── SignIn_SignUp.js ├── __pycache__ └── app.cpython-312.pyc ├── app.py ├── assets ├── 380x80 │ ├── img1.webp │ ├── img1_380x80.webp │ ├── img2.webp │ ├── img2_380x80.webp │ ├── img3.webp │ ├── img3_380x80.webp │ ├── img4.webp │ ├── img4_380x80.webp │ ├── img5.webp │ └── img5_380x80.webp ├── avatar.webp ├── face │ ├── face1.webp │ ├── face2.webp │ └── face3.webp ├── fashion.webp ├── google_icon.webp ├── health.webp ├── img1.webp ├── img10.webp ├── img11.webp ├── img12.webp ├── img13.webp ├── img14.webp ├── img2.webp ├── img21.webp ├── img3.webp ├── img4.webp ├── img5.webp ├── img6.webp ├── img7.webp ├── img8.webp ├── img9.webp ├── slider │ ├── img1.webp │ ├── img2.webp │ ├── img3.webp │ ├── img4.webp │ ├── img5.webp │ ├── img6.webp │ └── img7.webp └── start.webp ├── backend ├── .env.example ├── .gitignore ├── README.md ├── app.js ├── controllers │ ├── addBlogController.js │ ├── blogController.js │ ├── contactController.js │ ├── discussionController.js │ ├── faqController.js │ ├── feedController.js │ ├── getInTouchController.js │ ├── postsController.js │ ├── ratingController.js │ ├── subscribeController.js │ └── userController.js ├── generateFromAi.py ├── middlewares │ ├── adminMiddleware.js │ └── authMiddleware.js ├── models │ ├── addBlog.js │ ├── answers.js │ ├── blog.js │ ├── comment.js │ ├── contact.js │ ├── discussion.js │ ├── feedback.js │ ├── getInTouch.js │ ├── postModel.js │ ├── question.js │ ├── rating.js │ ├── subscribe.js │ └── user.js ├── package-lock.json ├── package.json ├── routes │ ├── addBlogRoutes.js │ ├── blogRoutes.js │ ├── contactRoute.js │ ├── discussionRoutes.js │ ├── faqRoutes.js │ ├── feedbackRoute.js │ ├── getInTouchRoutes.js │ ├── ratingRoutes.js │ ├── storiesRoutes.js │ ├── subscribeRoutes.js │ └── userRoutes.js ├── sendFeedbackToAdmin.js ├── utils │ ├── db.js │ └── sendMailToSubscribe.js └── validations │ ├── blogValidation.js │ └── userValidation.js ├── blog-comment.js ├── blog.css ├── blog.html ├── bookmarks.html ├── boy.webp ├── category.css ├── category.html ├── chatbot.gif ├── chatbot.html ├── comment.css ├── comment.js ├── comment1.html ├── comment10.html ├── comment11.html ├── comment12.html ├── comment13.html ├── comment14.html ├── comment2.html ├── comment3.html ├── comment4.html ├── comment5.html ├── comment6.html ├── comment7.html ├── comment8.html ├── comment9.html ├── contact.html ├── contact_us.css ├── contact_us.html ├── contact_us.js ├── darkMode.js ├── dist ├── contact_us.dev.js ├── contact_us.dev.js.map ├── contact_us.min.js └── contact_us.min.js.map ├── download (1).jpeg ├── download (2).jpeg ├── download (3).jpeg ├── download.jpeg ├── faq.js ├── faq.webp ├── fashion.html ├── food.html ├── forum.html ├── frontend ├── .gitignore ├── README.md ├── package.json ├── public │ └── blog │ │ ├── post-1.webp │ │ ├── post-2.webp │ │ └── post-3.webp ├── src │ ├── assets │ │ ├── about │ │ │ └── chart.png │ │ └── blog │ │ │ ├── 1.webp │ │ │ ├── 10.webp │ │ │ ├── 11.webp │ │ │ ├── 12.webp │ │ │ ├── 13.webp │ │ │ ├── 14.webp │ │ │ ├── 15.webp │ │ │ ├── 16.webp │ │ │ ├── 17.webp │ │ │ ├── 18.webp │ │ │ ├── 19.webp │ │ │ ├── 2.webp │ │ │ ├── 20.webp │ │ │ ├── 21.webp │ │ │ ├── 22.webp │ │ │ ├── 23.webp │ │ │ ├── 24.webp │ │ │ ├── 25.webp │ │ │ ├── 26.webp │ │ │ ├── 27.webp │ │ │ ├── 28.webp │ │ │ ├── 29.webp │ │ │ ├── 3.webp │ │ │ ├── 30.webp │ │ │ ├── 31.webp │ │ │ ├── 32.webp │ │ │ ├── 33.webp │ │ │ ├── 34.webp │ │ │ ├── 35.webp │ │ │ ├── 36.webp │ │ │ ├── 37.webp │ │ │ ├── 38.webp │ │ │ ├── 39.webp │ │ │ ├── 4.webp │ │ │ ├── 40.webp │ │ │ ├── 41.webp │ │ │ ├── 42.webp │ │ │ ├── 5.webp │ │ │ ├── 6.webp │ │ │ ├── 7.webp │ │ │ ├── 8.webp │ │ │ └── 9.webp │ ├── components │ │ ├── Footer.js │ │ └── Navbar.js │ ├── index.html │ ├── main.js │ ├── pages │ │ ├── About.js │ │ ├── AddBlog.js │ │ ├── BloggerProfile.js │ │ ├── Blogs.js │ │ ├── Categories.js │ │ ├── Contact.js │ │ ├── DiscussionForum.js │ │ ├── Feedback.js │ │ ├── GoogleTranslator.js │ │ ├── Home.js │ │ ├── Login.js │ │ ├── ReadMoreBlog.js │ │ ├── Stories.js │ │ └── TermsOfUse.js │ ├── styles │ │ ├── footer.css │ │ ├── input.css │ │ ├── navbar.css │ │ └── output.css │ └── utils │ │ └── router.js ├── tailwind.config.js └── vite.config.js ├── gaming_chronicles.html ├── give_feedback.html ├── give_feedback.js ├── google_signin.js ├── health.html ├── home.webp ├── icon-192x192.png ├── icon-512x512.png ├── images ├── Untitled design.webp ├── android-chrome-192x192.webp ├── android-chrome-512x512.webp ├── apple-touch-icon.webp ├── background.jpg ├── favi.webp ├── favicon-16x16.webp ├── favicon-32x32.webp ├── favicon.ico ├── favicon.webp ├── profile.webp └── website.webp ├── index.html ├── life.html ├── login.css ├── main.js ├── main2.js ├── manifest.json ├── package-lock.json ├── package.json ├── privacy.html ├── profile.html ├── profile.js ├── profiledropdown.js ├── profileedit.html ├── progress_bar.js ├── requirements.txt ├── resetpass.html ├── script.js ├── scripts.js ├── share.js ├── signup.css ├── site.webmanifest ├── start.html ├── start_writing.css ├── start_writing.html ├── start_writing.js ├── style.css ├── styles.css ├── sw.js ├── tech.html ├── testp.css ├── testp.js ├── travel.html └── words.json /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | 27 | 28 | 29 | **Additional context** 30 | Add any other context about the problem here. 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/issue_template.md: -------------------------------------------------------------------------------- 1 | ### Issue Checklist 2 | 3 | - [ ] I have searched for existing issues and made sure my issue is new. 4 | - [ ] I have made sure to add all necessary details. 5 | - [ ] I will not create multiple issues related to the same topic. 6 | 7 | ### Issue Description 8 | 9 | 10 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Pull Request Checklist 2 | 3 | - [ ] I have added screenshots and videos to show before and after the working of my code. 4 | - [ ] I have ensured that the screen size is set to 100% while making the video. 5 | - [ ] I have synced the latest fork with my local repository and resolved any conflicts. 6 | - [ ] I have mentioned the issue number which I created before making this PR .(format to mention issue number is : fixes #(issue number) ) 7 | - [ ] I understand that if any the above conditions are not met , my PR will not be MERGED . 8 | 9 | -------------------------------------------------------------------------------- /.github/workflows/PRValidator.yml: -------------------------------------------------------------------------------- 1 | name: PR Description Check 2 | 3 | on: 4 | pull_request: 5 | types: [opened] 6 | 7 | jobs: 8 | validate-pr-description: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Validate PR Description 12 | id: check_description 13 | run: | 14 | if [ -z "${{ github.event.pull_request.body }}" ]; then 15 | echo "::error::Description is missing!" 16 | exit 1 17 | fi 18 | 19 | - name: Check for issue number or 'Fixes #NEW' 20 | id: check_issue_number 21 | run: | 22 | description="${{ github.event.pull_request.body }}" 23 | if [[ ! "$description" =~ (Fixes #[0-9])]]; then 24 | echo "::error::PR description must contain an issue number or 'Fixes #NEW'" 25 | exit 1 26 | fi 27 | -------------------------------------------------------------------------------- /.github/workflows/auto_label.yaml: -------------------------------------------------------------------------------- 1 | name: Auto Label Issues and PRs 2 | 3 | on: 4 | issues: 5 | types: [opened] 6 | pull_request_target: # Correct indentation here 7 | types: [opened] 8 | 9 | jobs: 10 | add-labels: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Add labels to new issues 15 | if: github.event_name == 'issues' 16 | uses: actions-ecosystem/action-add-labels@v1 17 | with: 18 | github_token: ${{ secrets.PAT_TOKEN }} # Use PAT_TOKEN for issues 19 | labels: | 20 | gssoc-ext 21 | hacktoberfest-accepted 22 | 23 | - name: Add labels to new pull requests 24 | if: github.event_name == 'pull_request_target' 25 | uses: actions-ecosystem/action-add-labels@v1 26 | with: 27 | github_token: ${{ secrets.GITHUB_TOKEN }} # Use GITHUB_TOKEN for PRs 28 | labels: | 29 | gssoc-ext 30 | hacktoberfest-accepted 31 | -------------------------------------------------------------------------------- /.github/workflows/check-merge-conflicts.yml: -------------------------------------------------------------------------------- 1 | name: Merge Conflict Checker 2 | 3 | on: 4 | pull_request: 5 | types: [opened, synchronize, reopened] 6 | 7 | permissions: 8 | pull-requests: write 9 | contents: read 10 | 11 | jobs: 12 | check_merge_conflicts: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout repository 16 | uses: actions/checkout@v3 17 | 18 | - name: Check for merge conflicts 19 | run: | 20 | git fetch origin 21 | if git merge-base --is-ancestor HEAD origin/main; then 22 | echo "No merge conflicts." 23 | else 24 | echo "Merge conflicts detected." 25 | exit 1 26 | fi 27 | continue-on-error: true 28 | 29 | - name: Post comment if there are merge conflicts 30 | if: failure() 31 | uses: actions/github-script@v6 32 | with: 33 | script: | 34 | github.rest.issues.createComment({ 35 | issue_number: context.payload.pull_request.number, 36 | owner: context.repo.owner, 37 | repo: context.repo.repo, 38 | body: '⚠️ This branch has conflicts that must be resolved. Please resolve the merge conflicts before proceeding.' 39 | }) 40 | -------------------------------------------------------------------------------- /.github/workflows/check_fork_status.yaml: -------------------------------------------------------------------------------- 1 | name: Check Fork Status and Notify 2 | 3 | on: 4 | pull_request: 5 | types: [opened, synchronize] # Trigger when a PR is opened or updated 6 | 7 | permissions: 8 | pull-requests: write # Allow posting comments on PRs 9 | 10 | jobs: 11 | check_fork: 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - name: Checkout the repository 16 | uses: actions/checkout@v3 17 | with: 18 | fetch-depth: 2 # Fetch enough history to compare branches 19 | 20 | - name: Fetch the latest base branch 21 | run: | 22 | git fetch origin main # Replace 'main' with your base branch if different 23 | 24 | - name: Check if the branch is up to date 25 | id: check_fork 26 | run: | 27 | # Compare the contributor's branch with the base branch (main) 28 | behind_count=$(git rev-list --right-only --count HEAD...origin/main) 29 | echo "::set-output name=behind::$behind_count" 30 | 31 | - name: Comment on the PR if fork is outdated 32 | if: steps.check_fork.outputs.behind != '0' # If the fork is behind 33 | uses: actions/github-script@v7 34 | with: 35 | script: | 36 | const prNumber = context.payload.pull_request.number; 37 | const owner = context.repo.owner; 38 | const repo = context.repo.repo; 39 | 40 | await github.rest.issues.createComment({ 41 | owner: owner, 42 | repo: repo, 43 | issue_number: prNumber, 44 | body: '⚠️ It looks like your branch is out of date with the base branch. Please sync your fork and update the PR.' 45 | }); 46 | -------------------------------------------------------------------------------- /.github/workflows/issue_thank.yaml: -------------------------------------------------------------------------------- 1 | name: Auto Assign and Thank Issues 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | 8 | jobs: 9 | auto-assign: 10 | runs-on: ubuntu-latest 11 | 12 | permissions: 13 | issues: write 14 | 15 | steps: 16 | - name: 'Thank and assign the issue to the creator' 17 | uses: actions/github-script@v7 # Updated to v7 18 | with: 19 | github-token: ${{ secrets.GITHUB_TOKEN }} # Use auto-generated GitHub Token 20 | script: | 21 | const issueNumber = context.issue.number; 22 | const issueCreator = context.payload.issue.user.login; 23 | 24 | // Thank the issue creator 25 | await github.rest.issues.createComment({ 26 | issue_number: issueNumber, 27 | owner: context.repo.owner, 28 | repo: context.repo.repo, 29 | body: `Thanks @${issueCreator} for raising this issue! We'll look into it.We hope you have made sure that a similar issue doesnt exist , if it does, kindly ask to be assigned on that issue ` 30 | }); 31 | 32 | // Assign the issue to the creator 33 | //await github.rest.issues.addAssignees({ 34 | // issue_number: issueNumber, 35 | // owner: context.repo.owner, 36 | // repo: context.repo.repo, 37 | // assignees: [issueCreator] 38 | // }); 39 | -------------------------------------------------------------------------------- /.github/workflows/post_pr_thankyou.yaml: -------------------------------------------------------------------------------- 1 | name: Post-PR Merge Thank You 2 | 3 | on: 4 | pull_request_target: 5 | types: [closed] # Trigger when a PR is closed 6 | 7 | permissions: 8 | issues: write 9 | pull-requests: write 10 | 11 | jobs: 12 | post_merge_message: 13 | if: github.event.pull_request.merged == true # Only run if the PR was merged 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: Post thank you message 18 | uses: actions/github-script@v7 19 | with: 20 | github-token: ${{ secrets.GITHUB_TOKEN }} # Ensure token is used 21 | script: | 22 | const prNumber = context.payload.pull_request.number; 23 | const owner = context.repo.owner; 24 | const repo = context.repo.repo; 25 | 26 | // Post a thank you message upon PR merge 27 | await github.rest.issues.createComment({ 28 | owner: owner, 29 | repo: repo, 30 | issue_number: prNumber, 31 | body: `🎉🎉 Thank you for your contribution! Your PR #${prNumber} has been merged! 🎉🎉` 32 | }); 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | ErrorDocument 404 /404.html -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "liveServer.settings.port": 5501 3 | } -------------------------------------------------------------------------------- /25a7f6e52f7d373e7db6d63c4bdb38d1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANSHIKA-26/WordWise/35306bcecabfe172acab453a8de12bf1ffde08dc/25a7f6e52f7d373e7db6d63c4bdb38d1.jpg -------------------------------------------------------------------------------- /404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 |The page you are looking for not available!
63 | 64 | Go to Home 65 |Dear Subscriber,
65 |We are thrilled to have you with us. Stay tuned for our latest updates, offers, and insights to keep you informed and inspired!
66 | 67 | 68 |Best Regards,
WORDWISE Team
© ${new Date().getFullYear()} WORDWISE. All rights reserved.
80 |36 | Field 37 | | 38 |39 | Value 40 | | 41 |
---|---|
Submitted At | 46 |${new Date(userdata.submittedAt).toLocaleString()} | 47 |
Overall Experience | 50 |${userdata.overallExperience} | 51 |
Recommendation | 54 |${userdata.recommendation} | 55 |
Additional Comments | 58 |${userdata.additionalComments} | 59 |
Improvement | 62 |${userdata.improvement} | 63 |
Most Helpful Feature | 66 |${userdata.mostHelpfulFeature} | 67 |
New Features | 70 |${userdata.newFeatures} | 71 |
Features Used | 74 |${userdata.featuresUsed.join(', ')} | 75 |
31 | We’re thrilled to have you join the WordWise community—a place where words come alive, and every blog post is crafted to expand your vocabulary and deepen your understanding of language and topics you care about. 32 |
33 |34 | At WordWise, we believe in the power of words to enlighten and inspire. Our responsive, user-friendly platform is designed with you in mind, ensuring that each visit feels as seamless as it is engaging. Whether you’re here to explore our latest blogs, delve into specific topics, or simply enjoy a well-crafted read, WordWise has something for everyone. 35 |
36 |37 | As part of our community, you’ll be among the first to receive fresh content that’s both insightful and enriching. From curated articles that explore a variety of subjects to interactive features that enhance your reading experience, WordWise is more than just a blog—it’s a journey into the world of words. 38 |
39 |40 | We encourage you to dive into our sections, such as Home, Leading Blogs, About, and Contact Us. Each one is thoughtfully designed to guide you through your reading adventure. And if you ever wish to share feedback or connect with us, our Contact Us page is always open. 41 |
42 |43 | Thank you for subscribing to WordWise! We’re excited to share our latest blogs and updates with you. Here’s to many engaging reads and enriching experiences ahead! 44 |
45 |
46 | With warm regards,
47 | The WordWise Team
48 |
Explore our articles by topic
7 |${post.description}
106 |8 | WordWise offers a platform for passionate writers to express their ideas and connect with readers worldwide. 9 | Start your blogging journey today and join our community of creative minds. 10 |
11 |Blog post not found.
'; 68 | } 69 | } 70 | 71 | 72 | -------------------------------------------------------------------------------- /frontend/src/styles/footer.css: -------------------------------------------------------------------------------- 1 | footer { 2 | background-color: #f8f9fa; 3 | text-align: center; 4 | } 5 | 6 | body.dark-mode footer { 7 | background-color: #222; 8 | } 9 | 10 | @media (max-width: 1200px) { 11 | .footer-container { 12 | padding: 20px; 13 | } 14 | .col-3-main { 15 | flex-direction: row; 16 | flex-wrap: wrap; 17 | } 18 | .col-3 { 19 | width: 33.33%; 20 | } 21 | } 22 | 23 | @media (max-width: 992px) { 24 | .col-3 { 25 | width: 50%; /* Stack 2 columns side by side on medium screens */ 26 | } 27 | } 28 | 29 | @media (max-width: 768px) { 30 | .col-3 { 31 | width: 100%; /* Stack all columns vertically on small screens */ 32 | margin-bottom: 20px; 33 | } 34 | 35 | .feature-post div { 36 | flex-direction: column; 37 | } 38 | 39 | .tags { 40 | text-align: center; 41 | } 42 | } 43 | 44 | @media (max-width: 576px) { 45 | .feature-post div { 46 | align-items: center; 47 | } 48 | 49 | .tags.social { 50 | justify-content: center; 51 | } 52 | 53 | .wordwise-footer-content { 54 | text-align: center; 55 | } 56 | } 57 | 58 | /* Optional: You can also set max-width for images */ 59 | img.object-fit { 60 | max-width: 100%; /* Makes images responsive */ 61 | height: auto; 62 | } 63 | -------------------------------------------------------------------------------- /frontend/src/styles/input.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @import 'navbar.css'; 6 | @import 'footer.css'; 7 | 8 | body { 9 | font-family: Arial, sans-serif; 10 | margin: 0; 11 | padding: 0; 12 | transition: background-color 0.3s, color 0.3s; 13 | } 14 | 15 | body.dark-mode { 16 | background-color: #333; 17 | color: #fff; 18 | } 19 | 20 | #app { 21 | display: flex; 22 | flex-direction: column; 23 | min-height: 100vh; 24 | } 25 | 26 | #content { 27 | flex: 1; 28 | padding: 20px; 29 | } 30 | -------------------------------------------------------------------------------- /frontend/src/styles/navbar.css: -------------------------------------------------------------------------------- 1 | nav ul { 2 | list-style-type: none; 3 | padding: 0; 4 | display: flex; 5 | justify-content: space-around; 6 | } 7 | 8 | nav a { 9 | text-decoration: none; 10 | color: #333; 11 | } 12 | 13 | body.dark-mode nav { 14 | background-color: #222; 15 | } 16 | 17 | body.dark-mode nav a { 18 | color: #fff; 19 | } 20 | 21 | .form-popup { 22 | display: none; 23 | position: fixed; 24 | z-index: 9; 25 | left: 50%; 26 | top: 50%; 27 | transform: translate(-50%, -50%); 28 | width: 100%; 29 | max-width: 500px; 30 | padding: 20px; 31 | background-color: white; 32 | box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.6); 33 | border-radius: 10px; 34 | box-sizing: border-box; 35 | } 36 | 37 | .form-container h2 { 38 | margin-bottom: 20px; 39 | color: #333; 40 | } 41 | 42 | .form-group { 43 | margin-bottom: 15px; 44 | } 45 | 46 | .form-control { 47 | border-radius: 5px; 48 | padding: 12px; 49 | font-size: 16px; 50 | line-height: 1.5; 51 | box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.1); 52 | width: 100%; 53 | } 54 | 55 | .forgot { 56 | text-align: right; 57 | margin-left: 50px; 58 | font-size: 10px; 59 | margin-top: -40px; 60 | 61 | } 62 | 63 | .btn { 64 | margin-top: 10px; 65 | border-radius: 5px; 66 | } 67 | 68 | .eye-icon { 69 | position: absolute; 70 | right: 15px; 71 | top: 38px; 72 | cursor: pointer; 73 | color: #007bff; 74 | } 75 | 76 | .close-icon { 77 | font-size: 24px; 78 | cursor: pointer; 79 | float: right; 80 | } 81 | 82 | .position-relative { 83 | position: relative; 84 | } 85 | 86 | /* Login button jumping issue fix */ 87 | .btn-primary { 88 | transition: all 0.3s ease; 89 | /* Smooth transition */ 90 | } 91 | 92 | .btn-primary:hover { 93 | background-color: #0056b3; 94 | } 95 | 96 | .google-btn { 97 | display: flex; 98 | align-items: center; 99 | justify-content: center; 100 | } 101 | 102 | .google-logo { 103 | width: 20px; 104 | height: 20px; 105 | margin-right: 10px; 106 | } 107 | 108 | .btn-primary:hover { 109 | background-color: #0056b3; 110 | } 111 | 112 | .open { 113 | background: #0f1522f0; 114 | position: absolute; 115 | left: 42%; 116 | display: flex !important; 117 | align-items: start; 118 | top: 0%; 119 | height: 100vh; 120 | border-radius: 15px; 121 | padding: 30px; 122 | padding-top: 30px; 123 | padding-top: 75px; 124 | z-index: 9; 125 | } -------------------------------------------------------------------------------- /frontend/src/utils/router.js: -------------------------------------------------------------------------------- 1 | import { renderHome } from '../pages/Home.js'; 2 | import { renderBlogs } from '../pages/Blogs.js'; 3 | import { renderAddBlog } from '../pages/AddBlog.js'; 4 | import { renderCategories } from '../pages/Categories.js'; 5 | import { renderAbout } from '../pages/About.js'; 6 | import { renderContact } from '../pages/Contact.js'; 7 | import { renderFeedback } from '../pages/Feedback.js'; 8 | import { renderProfilePage } from '../pages/BloggerProfile.js'; 9 | import { renderFullBlogPost } from '../pages/ReadMoreBlog.js'; 10 | import { renderTermsOfUse } from '../pages/TermsOfUse.js'; 11 | import { renderDiscussionForum } from '../pages/DiscussionForum.js'; 12 | import { renderStories } from '../pages/Stories.js'; 13 | 14 | const routes = { 15 | '/': renderHome, 16 | '/blogs': renderBlogs, 17 | '/add-blog': renderAddBlog, 18 | '/categories': renderCategories, 19 | '/about': renderAbout, 20 | '/contact': renderContact, 21 | '/feedback': renderFeedback, 22 | '/profile': renderProfilePage, 23 | '/discussion': renderDiscussionForum, 24 | '/readmore': renderFullBlogPost, 25 | '/termsOfUse': renderTermsOfUse, 26 | '/stories': renderStories, 27 | }; 28 | 29 | export function router() { 30 | const path = window.location.pathname; 31 | const renderFunction = routes[path] || renderHome; 32 | const content = document.getElementById('content'); 33 | content.innerHTML = ''; 34 | renderFunction(content); 35 | } 36 | 37 | document.addEventListener('click', e => { 38 | if (e.target.matches('[data-link]')) { 39 | e.preventDefault(); 40 | history.pushState(null, null, e.target.href); 41 | router(); 42 | } 43 | }); 44 | -------------------------------------------------------------------------------- /frontend/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | content: ["./src/**/*.{html,js}"], 4 | theme: { 5 | extend: {}, 6 | }, 7 | plugins: [], 8 | darkMode: 'class', 9 | }; 10 | -------------------------------------------------------------------------------- /frontend/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | 3 | export default defineConfig({ 4 | root: 'src', 5 | build: { 6 | outDir: '../dist', 7 | emptyOutDir: true, 8 | }, 9 | server: { 10 | open: true, 11 | }, 12 | }) 13 | -------------------------------------------------------------------------------- /give_feedback.js: -------------------------------------------------------------------------------- 1 | document.getElementById('feedbackForm').addEventListener('submit', function(event) { 2 | event.preventDefault(); // Prevent form submission 3 | 4 | // Validation 5 | const name = document.getElementById('name').value.trim(); 6 | const email = document.getElementById('email').value.trim(); 7 | const feedback = document.getElementById('feedback').value.trim(); 8 | const rating = document.getElementById('rating').value; 9 | 10 | if (name === '' || email === '' || feedback === '' || rating === '') { 11 | alert('Please fill out all fields.'); 12 | return; 13 | } 14 | 15 | // If validation passes, submit the form (e.g., send data to server) 16 | alert('Thank you for your feedback!'); 17 | document.getElementById('feedbackForm').reset(); // Reset the form 18 | }); 19 | -------------------------------------------------------------------------------- /google_signin.js: -------------------------------------------------------------------------------- 1 | function handleGoogleLogin() { 2 | // The pop up for google login will only appear if the clientID is provided 3 | const clientId = 'YOUR_CLIENT_ID'; // Replace with your actual Client ID 4 | 5 | // Initialize the Google Identity Services library 6 | window.google.accounts.id.initialize({ 7 | client_id: clientId, 8 | callback: handleCredentialResponse 9 | }); 10 | 11 | // Prompt the user to sign in 12 | window.google.accounts.id.prompt(); 13 | } 14 | 15 | function handleCredentialResponse(response) { 16 | const token = response.credential; // This is the access token 17 | 18 | // Send the token to your backend for verification 19 | // Backend logic has to be written 20 | fetch('http://localhost:3000/oauth/google-login', { 21 | method: 'POST', 22 | headers: { 23 | 'Content-Type': 'application/json' 24 | }, 25 | body: JSON.stringify({ token }) 26 | }) 27 | .then(res => res.json()) 28 | .then(data => { 29 | if (data.token) { 30 | // Save the token in cookies or local storage 31 | document.cookie = `token=${data.token}; path=/; max-age=${60 * 60 * 24}`; // 1 day expiration 32 | 33 | // Redirect to home or other page 34 | window.location.href = '/home'; // Adjust as needed 35 | } else { 36 | alert('Login failed. Please try again.'); 37 | } 38 | }) 39 | .catch(error => { 40 | console.error('Error during Google login:', error); 41 | alert('Google login failed. Please try again.'); 42 | }); 43 | } 44 | 45 | -------------------------------------------------------------------------------- /home.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANSHIKA-26/WordWise/35306bcecabfe172acab453a8de12bf1ffde08dc/home.webp -------------------------------------------------------------------------------- /icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANSHIKA-26/WordWise/35306bcecabfe172acab453a8de12bf1ffde08dc/icon-192x192.png -------------------------------------------------------------------------------- /icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANSHIKA-26/WordWise/35306bcecabfe172acab453a8de12bf1ffde08dc/icon-512x512.png -------------------------------------------------------------------------------- /images/Untitled design.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANSHIKA-26/WordWise/35306bcecabfe172acab453a8de12bf1ffde08dc/images/Untitled design.webp -------------------------------------------------------------------------------- /images/android-chrome-192x192.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANSHIKA-26/WordWise/35306bcecabfe172acab453a8de12bf1ffde08dc/images/android-chrome-192x192.webp -------------------------------------------------------------------------------- /images/android-chrome-512x512.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANSHIKA-26/WordWise/35306bcecabfe172acab453a8de12bf1ffde08dc/images/android-chrome-512x512.webp -------------------------------------------------------------------------------- /images/apple-touch-icon.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANSHIKA-26/WordWise/35306bcecabfe172acab453a8de12bf1ffde08dc/images/apple-touch-icon.webp -------------------------------------------------------------------------------- /images/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANSHIKA-26/WordWise/35306bcecabfe172acab453a8de12bf1ffde08dc/images/background.jpg -------------------------------------------------------------------------------- /images/favi.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANSHIKA-26/WordWise/35306bcecabfe172acab453a8de12bf1ffde08dc/images/favi.webp -------------------------------------------------------------------------------- /images/favicon-16x16.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANSHIKA-26/WordWise/35306bcecabfe172acab453a8de12bf1ffde08dc/images/favicon-16x16.webp -------------------------------------------------------------------------------- /images/favicon-32x32.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANSHIKA-26/WordWise/35306bcecabfe172acab453a8de12bf1ffde08dc/images/favicon-32x32.webp -------------------------------------------------------------------------------- /images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANSHIKA-26/WordWise/35306bcecabfe172acab453a8de12bf1ffde08dc/images/favicon.ico -------------------------------------------------------------------------------- /images/favicon.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANSHIKA-26/WordWise/35306bcecabfe172acab453a8de12bf1ffde08dc/images/favicon.webp -------------------------------------------------------------------------------- /images/profile.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANSHIKA-26/WordWise/35306bcecabfe172acab453a8de12bf1ffde08dc/images/profile.webp -------------------------------------------------------------------------------- /images/website.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANSHIKA-26/WordWise/35306bcecabfe172acab453a8de12bf1ffde08dc/images/website.webp -------------------------------------------------------------------------------- /login.css: -------------------------------------------------------------------------------- 1 | main{ 2 | width: 100vw; 3 | height: 84vh; 4 | background: url(images/login_bg.jpg); 5 | background-size: cover; 6 | background-position: center; 7 | background-repeat: no-repeat; 8 | background-attachment: fixed; 9 | } 10 | .container-login{ 11 | display: flex; 12 | justify-content: center; 13 | align-items: center; 14 | min-height: 100%; 15 | } 16 | .box-login{ 17 | background-color: rgba(238, 216, 187, 0.849); 18 | color: white; 19 | display: flex; 20 | flex-direction: column; 21 | justify-content: center; 22 | position: relative; 23 | padding: 0px 20px 30px 20px; 24 | height: 550px; 25 | width: 450px; 26 | border: 3px solid rgba(245, 135, 62, 0.882); 27 | border-radius: 23px; 28 | -webkit-backdrop-filter: blur(15px); 29 | backdrop-filter: blur(-15px); 30 | overflow: hidden; 31 | } 32 | .top-header{ 33 | text-align: center; 34 | margin: 30px 0; 35 | margin-top: 0; 36 | } 37 | .top-header h2{ 38 | color: brown; 39 | font-size: 29px; 40 | font-weight: 700; 41 | margin-bottom: 8px; 42 | margin-left: 18px; 43 | } 44 | .input-group{ 45 | width: 100%; 46 | } 47 | .input-field{ 48 | margin: 12px 0; 49 | position: relative; 50 | } 51 | .input-box{ 52 | /* width: 100%; */ 53 | margin-top: 8px; 54 | margin-left: 13px; 55 | height: 40px; 56 | width: 340px; 57 | font-size: 15px; 58 | color: black; 59 | border: 1px solid rgb(178, 95, 18); 60 | border-radius:10px; 61 | padding: 2px 15px 0 20px; 62 | background: rgba(244, 208, 154, 0.926); 63 | backdrop-filter: blur(2px); 64 | outline: none; 65 | } 66 | .input-field label{ 67 | color: brown; 68 | font-size: 18px; 69 | transition: .3s ease-in-out; 70 | 71 | } 72 | .remember{ 73 | display: flex; 74 | font-size: 16px; 75 | margin: 12px 0 20px 0; 76 | color: brown; 77 | } 78 | .check{ 79 | margin-right: 8px; 80 | width: 14px; 81 | } 82 | .Input-submit{ 83 | width: 100%; 84 | height: 50px; 85 | font-size: 15px; 86 | font-weight: 500; 87 | border: none; 88 | border-radius: 10px; 89 | background: rgb(184, 98, 5); 90 | color: white; 91 | box-shadow: 0px 4px 20px rgba(169, 115, 61, 0.726); 92 | cursor: pointer; 93 | transition: .4s; 94 | } 95 | .Input-submit:hover{ 96 | background: wheat; 97 | color: brown; 98 | border: 2px solid brown; 99 | box-shadow: 0px 4px 20px rgba(117, 88, 54, 0.32); 100 | } 101 | .forgot{ 102 | text-align:end; 103 | font-size: 13px; 104 | padding: 23px; 105 | } 106 | .forgot a{ 107 | text-decoration: none; 108 | color: rgb(254, 252, 252); 109 | color: brown; 110 | } 111 | .new{ 112 | text-align:center; 113 | font-size: 16px; 114 | padding: 13px; 115 | font-weight: 500; 116 | color: brown; 117 | } 118 | .new a{ 119 | text-decoration: none; 120 | color: brown; 121 | font-weight: bolder; 122 | } -------------------------------------------------------------------------------- /main2.js: -------------------------------------------------------------------------------- 1 | let toggle = document.querySelector("#header .toggle-button"); 2 | let collapse = document.querySelectorAll("#header .collapse"); 3 | 4 | toggle.addEventListener('click' , function(){ 5 | collapse.forEach(col => col.classList.toggle("collapse-toggle")); 6 | }) 7 | //swiper library 8 | // main.js 9 | document.addEventListener('DOMContentLoaded', function () { 10 | var swiper = new Swiper('.swiper-container', { 11 | direction: 'horizontal', 12 | loop: true, 13 | slidesPerView: 1, 14 | autoplay: { 15 | delay: 3000 16 | }, 17 | pagination: { 18 | el: '.swiper-pagination', 19 | clickable: true, 20 | }, 21 | navigation: { 22 | nextEl: '.swiper-button-next', 23 | prevEl: '.swiper-button-prev', 24 | }, 25 | }); 26 | }); 27 | window.onscroll = function(){ myFunction()}; 28 | 29 | // get the current value 30 | let navbar = document.getElementById("header"); 31 | 32 | // get the navbar position 33 | let sticky = navbar.offsetTop; 34 | 35 | // sticky function 36 | function myFunction(){ 37 | if(window.pageYOffset >= sticky){ 38 | navbar.classList.add("sticky"); 39 | }else{ 40 | navbar.classList.remove("sticky"); 41 | } 42 | } 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WordWise", 3 | "short_name": "WordWise", 4 | "start_url": "/", 5 | "display": "standalone", 6 | "background_color": "#ffffff", 7 | "theme_color": "#000000", 8 | "icons": [ 9 | { 10 | "src": "/icon-192x192.png", 11 | "sizes": "192x192", 12 | "type": "image/png" 13 | }, 14 | { 15 | "src": "/icon-512x512.png", 16 | "sizes": "512x512", 17 | "type": "image/png" 18 | } 19 | ] 20 | 21 | } 22 | 23 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wordwise", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "wordwise", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "wordwise": "file:" 13 | } 14 | }, 15 | "node_modules/wordwise": { 16 | "resolved": "", 17 | "link": true 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wordwise", 3 | "version": "1.0.0", 4 | "description": "\r # 📖 WordWise Blogging Website 📝", 5 | "main": "main.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "wordwise": "file:" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /profile.js: -------------------------------------------------------------------------------- 1 | // profile.js 2 | document.addEventListener("DOMContentLoaded", async () => { 3 | try { 4 | // Fetch user profile data from backend 5 | const response = await fetch("http://localhost:5000/api/users/profile", { 6 | method: "GET", 7 | headers: { 8 | "Content-Type": "application/json", 9 | "Authorization": `Bearer ${localStorage.getItem("authToken")}`, // Use your auth token here 10 | }, 11 | }); 12 | 13 | if (!response.ok) { 14 | throw new Error("Failed to fetch profile data."); 15 | } 16 | 17 | // Parse the JSON data 18 | const profileData = await response.json(); 19 | 20 | // Populate profile data in HTML 21 | document.querySelector(".profile-name").textContent = profileData.username; 22 | document.querySelector(".profile-email").textContent = `Email: ${profileData.email}`; 23 | } catch (error) { 24 | console.error("Error fetching profile data:", error); 25 | } 26 | }); 27 | -------------------------------------------------------------------------------- /profiledropdown.js: -------------------------------------------------------------------------------- 1 | function toggleDropdown() { 2 | var dropdownMenu = document.getElementById('dropdownMenu'); 3 | dropdownMenu.classList.toggle('show'); // Toggles the 'show' class 4 | } 5 | 6 | // Close the dropdown if clicked outside 7 | window.onclick = function(event) { 8 | if (!event.target.closest('.profile-icon')) { // Updated to closest to avoid immediate closing 9 | var dropdowns = document.getElementsByClassName('dropdown-menu'); 10 | for (var i = 0; i < dropdowns.length; i++) { 11 | var openDropdown = dropdowns[i]; 12 | if (openDropdown.classList.contains('show')) { 13 | openDropdown.classList.remove('show'); 14 | } 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /progress_bar.js: -------------------------------------------------------------------------------- 1 | // Function to update the progress bar width as the user scrolls 2 | function updateProgressBar() { 3 | const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; 4 | const scrollHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight; 5 | const scrollPercentage = (scrollTop / scrollHeight) * 100; 6 | 7 | document.getElementById('progress-bar').style.width = scrollPercentage + '%'; 8 | } 9 | 10 | // Event listener for scrolling to update the progress bar 11 | window.addEventListener('scroll', updateProgressBar); 12 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | flask 2 | flask-cors 3 | transformers 4 | torch -------------------------------------------------------------------------------- /scripts.js: -------------------------------------------------------------------------------- 1 | // Register the service worker 2 | if ('serviceWorker' in navigator) { 3 | window.addEventListener('load', () => { 4 | navigator.serviceWorker.register('/sw.js') // Pointing to the sw.js file 5 | .then(registration => { 6 | console.log('ServiceWorker registration successful:', registration); 7 | }) 8 | .catch(error => { 9 | console.error('ServiceWorker registration failed:', error); 10 | }); 11 | }); 12 | 13 | 14 | } -------------------------------------------------------------------------------- /share.js: -------------------------------------------------------------------------------- 1 | // Function to open the sharing modal 2 | function openShareModal(url, title) { 3 | const modal = document.getElementById('share-modal'); 4 | modal.style.display = 'block'; // Show the modal 5 | 6 | // Set the sharing links in the modal 7 | const facebookShareLink = document.getElementById('share-facebook'); 8 | const twitterShareLink = document.getElementById('share-twitter'); 9 | const linkedinShareLink = document.getElementById('share-linkedin'); 10 | const pinterestShareLink = document.getElementById('share-pinterest'); 11 | 12 | facebookShareLink.href = `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}`; 13 | twitterShareLink.href = `https://twitter.com/intent/tweet?url=${encodeURIComponent(url)}&text=${encodeURIComponent(title)}`; 14 | linkedinShareLink.href = `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(url)}`; 15 | pinterestShareLink.href = `https://pinterest.com/pin/create/button/?url=${encodeURIComponent(url)}&description=${encodeURIComponent(title)}`; 16 | } 17 | 18 | // Function to close the modal 19 | function closeShareModal() { 20 | const modal = document.getElementById('share-modal'); 21 | modal.style.display = 'none'; // Hide the modal 22 | } 23 | 24 | // Event listener for close button 25 | document.addEventListener('DOMContentLoaded', () => { 26 | document.getElementById('close-modal').addEventListener('click', closeShareModal); 27 | }); 28 | 29 | -------------------------------------------------------------------------------- /signup.css: -------------------------------------------------------------------------------- 1 | main{ 2 | width: 100vw; 3 | height: 84vh; 4 | background: url(images/login_bg.jpg); 5 | background-size: cover; 6 | background-position: center; 7 | background-repeat: no-repeat; 8 | background-attachment: fixed; 9 | } 10 | .container-signup{ 11 | display: flex; 12 | justify-content: center; 13 | align-items: center; 14 | max-height: 900px; 15 | overflow-y: auto; 16 | } 17 | header div h2 a.home-link{ 18 | text-align: center; 19 | } 20 | 21 | .box-login{ 22 | background-color: rgba(238, 216, 187, 0.849); 23 | color: white; 24 | display: flex; 25 | flex-direction: column; 26 | justify-content: center; 27 | position: relative; 28 | padding: 0px 20px 15px 20px; 29 | height: 550px; 30 | width: 450px; 31 | border: 3px solid rgba(245, 135, 62, 0.882); 32 | border-radius: 23px; 33 | -webkit-backdrop-filter: blur(15px); 34 | backdrop-filter: blur(-15px); 35 | overflow: hidden; 36 | } 37 | .top-header{ 38 | text-align: center; 39 | margin: 15px 0; 40 | /* padding-top: 15px; */ 41 | } 42 | .top-header h2{ 43 | color: brown; 44 | font-size: 29px; 45 | font-weight: 700; 46 | margin-bottom: 8px; 47 | margin-left: 18px; 48 | } 49 | .input-group{ 50 | width: 100%; 51 | } 52 | .input-field{ 53 | margin: 12px 0; 54 | position: relative; 55 | } 56 | .input-box{ 57 | /* width: 100%; */ 58 | margin-top: 8px; 59 | margin-left: 13px; 60 | height: 40px; 61 | width: 340px; 62 | font-size: 15px; 63 | color: black; 64 | border: 1px solid rgb(178, 95, 18); 65 | border-radius:10px; 66 | padding: 2px 15px 0 20px; 67 | background: rgba(244, 208, 154, 0.926); 68 | backdrop-filter: blur(2px); 69 | outline: none; 70 | } 71 | .input-field label{ 72 | color: brown; 73 | font-size: 18px; 74 | transition: .3s ease-in-out; 75 | 76 | } 77 | .remember{ 78 | display: flex; 79 | font-size: 16px; 80 | margin: 12px 0 20px 0; 81 | color: brown; 82 | } 83 | .check{ 84 | margin-right: 8px; 85 | width: 14px; 86 | } 87 | .Input-submit{ 88 | width: 100%; 89 | height: 50px; 90 | margin: 5px 0; 91 | font-size: 15px; 92 | font-weight: 500; 93 | border: none; 94 | border-radius: 10px; 95 | background: rgb(184, 98, 5); 96 | color: white; 97 | box-shadow: 0px 4px 20px rgba(169, 115, 61, 0.726); 98 | cursor: pointer; 99 | transition: .4s; 100 | } 101 | .Input-submit:hover{ 102 | background: wheat; 103 | color: brown; 104 | border: 2px solid brown; 105 | box-shadow: 0px 4px 20px rgba(117, 88, 54, 0.32); 106 | } 107 | .forgot{ 108 | text-align:end; 109 | font-size: 13px; 110 | padding: 23px; 111 | } 112 | .forgot a{ 113 | text-decoration: none; 114 | color: rgb(254, 252, 252); 115 | color: brown; 116 | } 117 | .new{ 118 | text-align:center; 119 | font-size: 16px; 120 | padding-top: 26px; 121 | padding-bottom: 0; 122 | font-weight: 500; 123 | color: brown; 124 | } 125 | .new a{ 126 | text-decoration: none; 127 | color: brown; 128 | font-weight: bolder; 129 | } -------------------------------------------------------------------------------- /site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /start_writing.js: -------------------------------------------------------------------------------- 1 | async function PostBlog(event) { 2 | event.preventDefault(); 3 | 4 | 5 | const form = document.getElementById("blogForm"); 6 | const formData = new FormData(form); 7 | 8 | try { 9 | 10 | const response = await fetch("http://localhost:3000/post_blog", { 11 | method: "POST", 12 | body: formData, 13 | }); 14 | 15 | const result = await response.json(); 16 | 17 | if (result.success) { 18 | 19 | let existingPopup = document.getElementById("popupMessage"); 20 | if (existingPopup) { 21 | existingPopup.remove(); 22 | } 23 | 24 | 25 | const popup = document.createElement("div"); 26 | popup.id = "popupMessage"; 27 | popup.innerText = "Blog submitted successfully!"; 28 | 29 | 30 | document.body.appendChild(popup); 31 | 32 | 33 | popup.style.display = "block"; 34 | 35 | setTimeout(() => { 36 | popup.style.display = "none"; 37 | document.getElementById("blogForm").reset(); 38 | }, 3000); 39 | } else { 40 | alert("Error: " + result.message); 41 | } 42 | } catch (error) { 43 | console.error("Error submitting blog:", error); 44 | alert("An error occurred while submitting the blog."); 45 | } 46 | } 47 | 48 | const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; 49 | if (SpeechRecognition) { 50 | const recognition = new SpeechRecognition(); 51 | recognition.continuous = true; 52 | recognition.interimResults = false; 53 | recognition.lang = 'en-US'; 54 | 55 | const blogContent = document.getElementById('blogContent'); 56 | const startVoiceInputButton = document.getElementById('start-voice-input'); 57 | 58 | let isListening = false; 59 | 60 | startVoiceInputButton.addEventListener('click', () => { 61 | if (isListening) { 62 | recognition.stop(); 63 | startVoiceInputButton.innerText = '🎤'; 64 | isListening = false; 65 | } else { 66 | recognition.start(); 67 | startVoiceInputButton.innerText = '🛑'; 68 | isListening = true; 69 | } 70 | }); 71 | 72 | recognition.onresult = (event) => { 73 | const transcript = event.results[event.resultIndex][0].transcript; 74 | blogContent.value += ' ' + transcript; 75 | }; 76 | 77 | recognition.onerror = (event) => { 78 | console.error("Speech recognition error:", event.error); 79 | alert("Error with voice input: " + event.error); 80 | }; 81 | } else { 82 | alert("Speech recognition is not supported by your browser."); 83 | } 84 | 85 | 86 | 87 | async function getWritingSuggestions() { 88 | const content = document.getElementById("blogContent").value; 89 | 90 | 91 | if (!content) { 92 | alert("Please enter some content to get suggestions."); 93 | return; 94 | } 95 | 96 | try { 97 | 98 | const response = await fetch('http://127.0.0.1:5000/grammar-correct', { 99 | method: 'POST', 100 | headers: { 101 | 'Content-Type': 'application/json', 102 | }, 103 | body: JSON.stringify({ text: content }) 104 | }); 105 | 106 | 107 | if (response.ok) { 108 | const result = await response.json(); 109 | const suggestions = result.corrected_text || "No suggestions available"; 110 | 111 | 112 | document.getElementById("suggestionsText").innerText = suggestions; 113 | document.getElementById("suggestionsContainer").classList.add('visible'); 114 | } else { 115 | console.error("Error fetching suggestions:", response.status); 116 | alert("Failed to fetch suggestions. Please try again later."); 117 | } 118 | } catch (error) { 119 | console.error("Error:", error); 120 | alert("An error occurred while fetching suggestions."); 121 | } 122 | } 123 | 124 | // Get the Back to Top button element 125 | const backToTopButton = document.getElementById('backToTop'); 126 | 127 | // Add scroll event to show/hide the button 128 | window.addEventListener('scroll', () => { 129 | if (window.scrollY > 300) { 130 | backToTopButton.classList.add('show'); 131 | } else { 132 | backToTopButton.classList.remove('show'); 133 | } 134 | }); 135 | 136 | // Add click event to scroll to the top smoothly 137 | backToTopButton.addEventListener('click', () => { 138 | window.scrollTo({ 139 | top: 0, 140 | behavior: 'smooth' 141 | }); 142 | }); 143 | 144 | 145 | document.getElementById("getSuggestions").addEventListener("click", getWritingSuggestions); 146 | 147 | -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | /* .form-popup { 2 | display: none; Initially hidden */ 3 | /* position: fixed; 4 | top: 50%; 5 | left: 50%; 6 | transform: translate(-50%, -50%); 7 | border: 1px solid #ccc; 8 | padding: 20px; 9 | background-color: white; 10 | box-shadow: 0 2px 10px rgba(0,0,0,0.1); 11 | z-index: 1000; 12 | } 13 | .form-container { 14 | width: 300px; 15 | } 16 | .btn { 17 | display: block; 18 | width: 100%; 19 | padding: 10px; 20 | margin: 10px 0; 21 | background-color: #007bff; 22 | color: white; 23 | border: none; 24 | cursor: pointer; 25 | } */ 26 | /* .btn.cancel { 27 | background-color: #dc3545; Red for cancel button */ 28 | /* } */ 29 | /* .toggle-button { 30 | cursor: pointer; 31 | margin-left: 5px; 32 | } 33 | .form-group { 34 | margin-bottom: 15px; 35 | } */ 36 | -------------------------------------------------------------------------------- /sw.js: -------------------------------------------------------------------------------- 1 | const CACHE_NAME = 'my-pwa-cache-v1'; 2 | const urlsToCache = [ 3 | '/', 4 | '/index.html', 5 | '/styles.css', 6 | '/scripts.js', 7 | '/manifest.json', 8 | '/icon-192x192.png', 9 | '/icon-512x512.png' 10 | ]; 11 | 12 | 13 | self.addEventListener('install', (event) => { 14 | event.waitUntil( 15 | caches.open(CACHE_NAME) 16 | .then((cache) => { 17 | return cache.addAll(urlsToCache); 18 | }) 19 | ); 20 | }); 21 | 22 | 23 | self.addEventListener('fetch', (event) => { 24 | event.respondWith( 25 | caches.match(event.request) 26 | .then((response) => { 27 | return response || fetch(event.request); 28 | }) 29 | ); 30 | }); 31 | 32 | 33 | self.addEventListener('activate', (event) => { 34 | const cacheWhitelist = [CACHE_NAME]; 35 | event.waitUntil( 36 | caches.keys().then((cacheNames) => { 37 | return Promise.all( 38 | cacheNames.map((cacheName) => { 39 | if (!cacheWhitelist.includes(cacheName)) { 40 | return caches.delete(cacheName); 41 | } 42 | }) 43 | ); 44 | }) 45 | ); 46 | }); -------------------------------------------------------------------------------- /testp.js: -------------------------------------------------------------------------------- 1 | // Get current timestamp 2 | const getCurrentTimestamp = () => { 3 | return new Date().getTime(); 4 | }; 5 | 6 | // Store last active timestamp in LocalStorage 7 | const storeLastActive = () => { 8 | const lastActive = getCurrentTimestamp(); 9 | localStorage.setItem('lastActive', lastActive); 10 | }; 11 | 12 | // Get last active timestamp from LocalStorage 13 | const getLastActive = () => { 14 | return localStorage.getItem('lastActive'); 15 | }; 16 | 17 | // Update last active timestamp on page load and interaction 18 | document.addEventListener('DOMContentLoaded', storeLastActive); 19 | document.addEventListener('click', storeLastActive); 20 | document.addEventListener('scroll', storeLastActive); 21 | document.addEventListener('keydown', storeLastActive); 22 | 23 | // Example usage: 24 | const displayLastActive = () => { 25 | const lastActive = getLastActive(); 26 | if (lastActive) { 27 | const formattedTime = new Date(parseInt(lastActive)).toLocaleString(); 28 | document.getElementById('last-active').innerHTML = `Last active: ${formattedTime}`; 29 | } 30 | }; 31 | 32 | // Display the last active time on page load 33 | document.addEventListener('DOMContentLoaded', displayLastActive); 34 | --------------------------------------------------------------------------------