From 860e1f55497c9ac86a70fadbc6725a5d07f3f26c Mon Sep 17 00:00:00 2001 From: zeel0m Date: Wed, 8 Apr 2026 14:41:40 +0530 Subject: [PATCH 1/2] feat: add class-validator dependency and update page styles - Added `class-validator` package to `package.json`. - Adjusted styles in `page.tsx` for sidebar positioning and button margin. - Refined text styles in `[slug]/page.tsx` for better readability. - Updated descriptions in `constants.tsx` for JSON tools to enhance clarity. --- app/[slug]/page.tsx | 316 +++++++++++++++---------- app/libs/constants.tsx | 7 +- app/libs/developmentToolsConstant.tsx | 327 ++++++++++++++++++++------ app/page.tsx | 4 +- package.json | 1 + 5 files changed, 458 insertions(+), 197 deletions(-) diff --git a/app/[slug]/page.tsx b/app/[slug]/page.tsx index 81a451f..18c07d4 100644 --- a/app/[slug]/page.tsx +++ b/app/[slug]/page.tsx @@ -350,7 +350,7 @@ const Page = ({ params: { slug } }: { params: { slug: string } }) => { return (

{splitDescriptions.map( @@ -383,7 +383,7 @@ const Page = ({ params: { slug } }: { params: { slug: string } }) => { return ( {text} @@ -457,122 +457,6 @@ const Page = ({ params: { slug } }: { params: { slug: string } }) => { )} - {/* example section */} - {development_tool_example && ( -

- {development_tool_example?.example_title && ( -

- {development_tool_example?.example_title} -

- )} - {development_tool_example?.example_description && ( -

- {development_tool_example?.example_description} -

- )} - - {development_tool_example?.example_input && ( -
- {development_tool_example?.example_input?.title && ( -

- {development_tool_example?.example_input?.title} -

- )} - {development_tool_example?.example_input?.json_data && ( -
-                              
-                                {development_tool_example?.example_input?.json_data}
-                              
-                            
- )} -
- )} - - {development_tool_example?.example_outputs && ( -
- {development_tool_example?.example_outputs?.intro && ( -

- {development_tool_example?.example_outputs?.intro} -

- )} - {development_tool_example?.example_outputs?.outputs?.map( - (output: any, index: number) => ( -
- {output?.mode && ( -

- {output?.mode} -

- )} - {output?.title && ( -

- {output?.title} -

- )} - {output?.content && ( -
-                                    
-                                      {output?.content}
-                                    
-                                  
- )} - {output?.note && ( -

- {output?.note} -

- )} -
- ) - )} -
- )} -
- )} - - {/* what section */} - {development_tools_what && ( -
- {development_tools_what?.about_title && ( -

- {development_tools_what?.about_title} -

- )} - {development_tools_what?.what_description?.map( - (desc: any, index: number) => { - const descriptions = desc?.descriptions; - const splitDescriptions = - descriptions.split(/(".*?")/); // Split quoted and unquoted text - - return ( -

- {splitDescriptions.map( - (text: any, subIndex: any) => { - const isQuoted = - text.startsWith("") && text.endsWith(""); - - return ( - - {text} - - ); - } - )} -

- ); - } - )} -
- )} - {/* step-by-step guide */}
{development_tools_steps_guide?.guide_title && ( @@ -641,7 +525,7 @@ const Page = ({ params: { slug } }: { params: { slug: string } }) => { part.endsWith("") ? ( {part} @@ -664,7 +548,7 @@ const Page = ({ params: { slug } }: { params: { slug: string } }) => { ) ? ( {sub.slice( 2, @@ -806,6 +690,198 @@ const Page = ({ params: { slug } }: { params: { slug: string } }) => { )}
+ {/* example section */} + {development_tool_example && ( +
+ {development_tool_example?.example_title && ( +

+ {development_tool_example?.example_title} +

+ )} + {development_tool_example?.example_description && ( +

+ {development_tool_example?.example_description} +

+ )} + + {development_tool_example?.example_input && ( +
+ {development_tool_example?.example_input?.title && ( +

+ {development_tool_example?.example_input?.title} +

+ )} + {development_tool_example?.example_input?.json_data && ( +
+                              
+                                {development_tool_example?.example_input?.json_data}
+                              
+                            
+ )} +
+ )} + + {development_tool_example?.example_outputs && ( +
+ {development_tool_example?.example_outputs?.intro && ( +

+ {development_tool_example?.example_outputs?.intro} +

+ )} + {development_tool_example?.example_outputs?.outputs?.map( + (output: any, index: number) => ( +
+ {output?.mode && ( +

+ {output?.mode} +

+ )} + {output?.title && ( +

+ {output?.title} +

+ )} + {output?.content && ( +
+                                    
+                                      {output?.content}
+                                    
+                                  
+ )} + {output?.note && ( +

+ {output?.note} +

+ )} +
+ ) + )} +
+ )} + + {/* JavaScript example section (optional) */} + {development_tool_example?.javascript_example && ( +
+ {development_tool_example?.javascript_example?.title && ( +
+ {development_tool_example?.javascript_example?.title} +
+ )} + {development_tool_example?.javascript_example?.description && ( +

+ {development_tool_example?.javascript_example?.description} +

+ )} + + {development_tool_example?.javascript_example?.methods?.length > + 0 && ( +
+
    + {development_tool_example?.javascript_example?.methods?.map( + (method: any, index: number) => ( +
  • + {method?.name && ( + + {method?.name}{" "} + + )} + {method?.description && ( + + {method?.description} + + )} +
  • + ) + )} +
+
+ )} + + {development_tool_example?.javascript_example?.examples?.length > + 0 && ( +
+ {development_tool_example?.javascript_example?.examples?.map( + (example: any, index: number) => ( +
+ {example?.title && ( +

+ {example?.title} +

+ )} + {example?.code && ( +
+                                          
+                                            {example?.code}
+                                          
+                                        
+ )} +
+ ) + )} +
+ )} + + {development_tool_example?.javascript_example?.note && ( +

+ {development_tool_example?.javascript_example?.note} +

+ )} +
+ )} +
+ )} + + {/* what section */} + {development_tools_what && ( +
+ {development_tools_what?.about_title && ( +

+ {development_tools_what?.about_title} +

+ )} + {development_tools_what?.what_description?.map( + (desc: any, index: number) => { + const descriptions = desc?.descriptions; + const splitDescriptions = + descriptions.split(/(".*?")/); // Split quoted and unquoted text + + return ( +

+ {splitDescriptions.map( + (text: any, subIndex: any) => { + const isQuoted = + text.startsWith("") && text.endsWith(""); + + return ( + + {text} + + ); + } + )} +

+ ); + } + )} +
+ )} + {/* how to use */}
{development_tools_how_use?.how_use_title && ( diff --git a/app/libs/constants.tsx b/app/libs/constants.tsx index 579e5b5..5e558a0 100644 --- a/app/libs/constants.tsx +++ b/app/libs/constants.tsx @@ -190,7 +190,6 @@ import XorCalculator from '../components/developmentToolsComponent/xorCalculator import CurlToCodeConverter from '../components/developmentToolsComponent/curlToCodeConverter'; import YAMLFormatterAndBeautifier from '../components/developmentToolsComponent/yamlFormatterAndBeautifier'; import EpochConverter from '../components/developmentToolsComponent/epochConverter'; -import { Cat } from '@phosphor-icons/react'; export const WEB_URL = 'https://www.betterbugs.io'; @@ -320,8 +319,8 @@ export const developmentToolsCategoryContent: any = { { // icon: , url: '/json-prettifier', - title: 'JSON Prettifier', - description: 'Format JSON to make it human-readable.', + title: 'JSON Formatter/Prettifier Tool', + description: 'The JSON formatter/prettifier is a free-to-use online tool on BetterBugs.io that instantly formats JSON strings into human-readable code structures with tree views and proper indentation.', }, ], Category10: [ @@ -717,7 +716,7 @@ export const developmentToolsCategoryContent: any = { { url: '/base64-decoder', title: 'Base64 Decoder', - description: 'Decode Base64 text or files to UTF-8.', + description: 'The Base64 decoder is a free-to-use online tool on BetterBugs.io that lets you instantly decode Base64-encoded strings into readable formats like plain text, JSON, HEX, or binary.', }, ], Category60: [ diff --git a/app/libs/developmentToolsConstant.tsx b/app/libs/developmentToolsConstant.tsx index 4891f7b..ac6c335 100644 --- a/app/libs/developmentToolsConstant.tsx +++ b/app/libs/developmentToolsConstant.tsx @@ -1,4 +1,3 @@ -import { steps } from 'framer-motion'; import { PATHS } from './constants'; export const DEVELOPMENTTOOLS: any = { @@ -802,17 +801,12 @@ export const DEVELOPMENTTOOLS: any = { }, development_tools_how_use: { how_use_title: 'Why It’s Used', - how_use_description: ( - <> -

- During development, it's best to work with JSON code that isn’t - minified as it's much easier that way to read and work with. So, + how_use_description: `During development, it's best to work with JSON code that isn't + minified as it's much easier that way to read and work with. So, the JSON minifier is particularly useful for downsizing JSON files and using just before deploying the app to production. -

-

You can use it for various purposes, such as:

- - ), + You can use it for various purposes, such as: + `, point: [ { description: @@ -856,9 +850,9 @@ export const DEVELOPMENTTOOLS: any = { }, [`json-prettifier`]: { hero_section: { - title: 'JSON Prettifier Tool', + title: 'Online JSON Formatter/Prettifier', description: - 'The JSON prettifier is a free online utility tool on BetterBugs.io that formats your JSON data, making it human-readable and easier to work with.', + 'The JSON formatter/prettifier is a free-to-use online tool on BetterBugs.io that instantly formats JSON strings into human-readable code structures with tree views and proper indentation.', }, development_tools_list: [ { tool: 'Text Upper Case', url: PATHS.TEXT_UPPERCASE_CONVERTER }, @@ -869,25 +863,90 @@ export const DEVELOPMENTTOOLS: any = { { tool: 'Sentence Count Tool', url: PATHS.SENTENCE_COUNTER_TOOL }, ], development_tools_about_details: { - about_title: 'What is the JSON Prettifier Tool?', + about_title: 'What is the JSON Formatter/Prettifier Tool?', about_description: [ { description: - 'The JSON prettifier tool allows you to nicely format your JSON code by adding proper indentation, line breaks, and spaces. This makes the JSON data more readable, usable, and easier to work with while writing and testing apps.', + 'The JSON formatter tool enables you to nicely format your JSON code in one click by adding proper indentation, line breaks, and spaces to your code. This makes the JSON data more readable, usable, and easier to work with while writing and testing apps.', }, { description: - "Developers and QA testers working with JSON data files can clearly benefit from this tool, as it changes unformatted data into a human-readable format, making it easier to spot errors and make modifications. It doesn't affect your JSON data or syntax at all; you simply get a more organized and aesthetically pleasing format.", + "You can use it to convert the minified JSON or messy JSON data (from APIs, logs, configs, or files) into properly indented, syntax-highlighted output. It supports validation for errors and tree expansion/collapse. You can also tweak the number of indentations you’d like in the formatted JSON output.", }, { description: - 'You can use the JSON prettifier here on BetterBugs.io completely free. Just copy-paste code or upload your JSON file and instantly get the prettier version of it.', + 'Plus, this tool makes it extremely easy to spot errors and make modifications in JSON data. It doesn’t affect your JSON data or syntax at all; you simply get a more organized and aesthetically pleasing format.', + }, + { + description: + 'You can use the JSON formatter here on BetterBugs.io completely free. Just copy-paste code or upload your JSON file and instantly get the formatted version of it.', + }, + ], + }, + development_tool_example: { + example_title: 'Example', + example_input: { + title: 'Unformatted JSON String', + json_data: '{"book":{"title":"1Q84","author":"Haruki Murakami","year":2009,"character":{"name":"Tengo","role":"writer","age":30,"skills":["mathematics","novel_editing"]},"world":{"little_people":true,"two_moons":true}}}', + }, + example_outputs: { + outputs: [ + { + mode: 'Formatted String with JSON Formatter Tool on BetterBugs.io', + content: `{ + "book": { + "title": "1Q84", + "author": "Haruki Murakami", + "year": 2009, + "character": { + "name": "Tengo", + "role": "writer", + "age": 30, + "skills": [ + "mathematics", + "novel_editing" + ] + }, + "world": { + "little_people": true, + "two_moons": true + } + } +}`, + }, + ], + }, + }, + example_outputs: { + outputs: [ + { + mode: 'Formatted String with JSON Formatter Tool on BetterBugs.io', + content: `{ + "book": { + "title": "1Q84", + "author": "Haruki Murakami", + "year": 2009, + "character": { + "name": "Tengo", + "role": "writer", + "age": 30, + "skills": [ + "mathematics", + "novel_editing" + ] + }, + "world": { + "little_people": true, + "two_moons": true + } + } +}`, }, ], }, development_tools_steps_guide: { - guide_title: 'Step-By-Step Guide', - guide_description: 'To use the prettifier tool,', + guide_title: 'How to Use the JSON Formatter Tool on BetterBugs.io?', + guide_description: 'Using the tool is super simple:', steps: [ { step_key: 'Step 1:', @@ -902,70 +961,104 @@ export const DEVELOPMENTTOOLS: any = { }, { steps_points_description: - 'You can also upload a minified or unformatted JSON file and get the formatted version of it. For this, you have the “Choose File” button.', + 'You can also upload a minified or unformatted JSON file from your local system. For this, use the “Choose File” button.', }, ], }, { step_key: 'Step 2:', - step_title: 'Prettify the Code:', + step_title: 'Format the Code:', step_description: - 'Hit the “Prettify” button to instantly format your JSON code. You can also specify the number of indentations for your JSON data with the Indentation dropdown. You have four options for it: 1, 2, 3, and 4 spaces.', + 'Hit the “Prettify” button to instantly format your JSON code. You can also specify the number of indentations for your JSON data. You have four options for it: 1, 2, 3, and 4 spaces.', }, { step_title: 'NOTE: ', step_description: - 'If there’s any syntax error with the JSON, make sure to fix it before adding it to the prettifier or you will end up getting the “Invalid JSON input” error.', + 'If there’s any syntax error with the JSON, make sure to fix it before adding it to the formatter or you will end up getting the “Invalid JSON input” error as a toast notification.', }, { step_key: 'Step 3:', - step_title: 'Use Prettified Code:', + step_title: 'Use Formatted Code:', step_description: 'To use the formatted code:', }, { steps_points: [ { steps_points_description: - 'Hit the “Copy to Clipboard” button and paste wherever you want to.', + 'Hit the “Copy” button and paste wherever you want to.', }, { steps_points_description: - 'You can also download it as a JSON file using the “Download Prettified JSON” button.', + 'You can also download it as a JSON file using the “Download” button.', }, ], }, { - step_description: 'To clear all code, you have the “Clean” button.', + step_description: 'To clear all code, you’ve the “Clear” button.', }, ], }, development_tools_how_use: { - how_use_title: "Why It's Used", + how_use_title: "What are the Use Cases of the JSON Formatter Tool?", how_use_description: 'You can use the JSON prettier tool to:', point: [ { - description: 'Keep JSON code well-organized and properly formatted.', + title: 'Debugging API responses', + description: 'Format RAW, minified JSON from Postman collections, curl commands, or browser Network tab to quickly spot nesting errors, missing commas, or malformed arrays during REST/GraphQL troubleshooting.', + }, + { + title: 'Log analysis', + description: 'Format complex JSON logs from Sentry dashboards, server traces, ELK stacks, or Chrome DevTools console outputs to triage issues like failed auth flows or payload mismatches in production environments.', }, { - description: 'Make JSON data easier to understand and work with.', + title: 'Config validation', + description: + 'Check and format package.json, .env configs, or YAML-to-JSON conversions during CI/CD pipelines in GitHub Actions, Jira workflows, or Azure DevOps deploys to catch syntax issues pre-merge.', }, { + title: 'API integration testing', description: - 'Easily spot errors or issues in the code while debugging.', + 'Validate incoming/outgoing payloads in automated tests using tools like Postman or Supertest; format responses to confirm data shapes match schemas before scripting assertions.', }, { + title: 'Work Collaboratively on PM Tools', description: - 'Make it easier for team members to review and edit JSON data.', + ' Convert unreadable minified JSON snippets into readable trees, then copy-paste into GitHub PR comments or your preferred version control tool; perfect for faster code reviews and triage by distributed teams.', + }, + { + title: 'Data migration', + description: + 'Clean and validate legacy JSON files or database exports before importing into other project tools.', + }, + { + title: 'Unit/Integration Testing', + description: + 'Format test fixtures, mock responses, or expected payloads in Jest/Cypress suites to visually verify structure matches real API data', + }, + { + title: 'End-to-End Testing', + description: + 'Decode and format JSON from Playwright/Puppeteer traces or Selenium logs to analyze automation failures, like assertion mismatches in e2e workflows for web apps.', + }, + { + title: 'Performance Profiling', + description: + 'Format large JSON payloads from browser performance APIs (e.g., Navigation Timing) or stack traces to identify bloat in frontend bundles during dev sprints.', + }, + { + title: 'Learning JSON', + description: + 'Beginners can paste real-world examples from public APIs (like JSONPlaceholder) to visualize object nesting, arrays, and null handling, building intuition for schema design.', }, ], }, meta_data: { - meta_title: 'JSON Prettifier - Developer Utility Tools', + meta_title: 'JSON Formatter/Prettifier Online - Developer Utility Tools', meta_description: - 'Format your JSON data for better readability with the BetterBugs online JSON Prettifier. It’s perfect for keeping your JSON data well organized and makes it easier to work with while debugging.', - og_title: 'JSON Prettifier - Developer Utility Tools', + 'Use the JSON formatter free online tool on BetterBugs.io to instantly format, validate, and beautify JSON data. Perfect for debugging APIs, logs, configs, and testing workflows.', + og_title: 'JSON Formatter/Prettifier Online - Developer Utility Tools', og_description: - 'This article covers the JSON prettifier dev utility tool on BetterBugs.io with steps for using it.', + 'This post describes usage steps and use cases of the JSON formatter free online tool on BetterBugs.io for developers, testers, and software folks.', og_image: '/images/og-images/Cover.png', }, }, @@ -7259,7 +7352,6 @@ family[1]: "Beth"`, og_image: '/images/og-images/Cover.png', }, }, - [`unicode-to-ascii-converter`]: { hero_section: { title: 'Unicode to ASCII Converter', @@ -7339,7 +7431,6 @@ family[1]: "Beth"`, og_image: '/images/og-images/Cover.png', }, }, - [`ascii-to-unicode-converter`]: { hero_section: { title: 'ASCII to Unicode Converter', @@ -7598,9 +7689,9 @@ family[1]: "Beth"`, }, [`base64-decoder`]: { hero_section: { - title: 'Base64 Decoder', + title: 'Base64 Decoder Online', description: - 'Paste Base64 text or choose a file and decode to readable text (UTF‑8).', + 'The Base64 decoder is a free-to-use online tool on BetterBugs.io that lets you instantly decode Base64-encoded strings into readable formats like plain text, JSON, HEX, or binary.', }, development_tools_list: [ { tool: 'Markdown To HTML', url: PATHS.MARKDOWN_TO_HTML }, @@ -7611,69 +7702,163 @@ family[1]: "Beth"`, { tool: 'JS Obfuscator', url: PATHS.JS_OBFUSCATOR }, ], development_tools_about_details: { - about_title: 'What is the Base64 Decoder?', + about_title: 'What is the Base64 Decoder Online Tool?', about_description: [ { description: - 'The Base64 Decoder converts Base64‑encoded strings or files back into their original text content using UTF‑8 decoding.', + 'The base64 decoder online tool instantly decodes Base64 strings (from APIs, logs, emails, or configs) into UTF-8/readable formats: plain text, JSON, HEX, or binary. ', }, { description: - 'Useful for reversing data encoded for transport or embedding (e.g., in JSON, URLs, or HTML).', + 'You can load data to it by adding a Base64 string in the input box, uploading a file from your system, or simply entering a URL. It\'s a 100% free-to-use tool on BetterBugs.io; perfect for debugging encoded data in dev, testing, or data tasks. No installations or downloads or code is required for using it. You can paste the string and get results right away. ', }, ], }, development_tools_steps_guide: { - guide_title: 'Using the Base64 Decoder', - guide_description: 'To decode Base64:', + guide_title: 'How to Use the Base64 Tool?', + guide_description: 'For using the tool, simply:', steps: [ { - step_key: 'Step 1:', - step_title: 'Paste or Upload:', - step_description: - 'Paste your Base64 text or choose a file containing Base64.', - }, - { - step_key: 'Step 2:', - step_title: 'Decode:', - step_description: - 'Click the Decode button to convert Base64 to UTF‑8 text.', - }, - { - step_key: 'Step 3:', - step_title: 'Copy or Clear:', - step_description: 'Copy the decoded result or clear to start over.', + steps_points: [ + { + steps_points_title: 'Add the encoded Base64 string', + steps_points_description: + 'to the input box OR', + }, + { + steps_points_title: 'Upload the RAW text file', + steps_points_description: + 'using the upload button (located at the top right of the input box)', + }, + ], }, ], }, + development_tool_example: { + example_title: 'Example', + example_description: 'For instance, try adding the following Base64 string in the input box and see if it matches the output:', + example_input: { + title: 'Base64 String:', + json_data: 'eyJ1c2VyX2lkIjogMTIzLCAicm9sZSI6ICJhZG1pbiIsICJzdGF0dXMiOiAiYWN0aXZlIiwgInBsYW4iOiAicHJvIn0=', + }, + example_outputs: { + outputs: [ + { mode: 'JSON/UTF-8 Output', content: '{"user_id": 123, "role": "admin", "status": "active", "plan": "pro"} ' }, + ], + }, + javascript_example: { + title: 'JavaScript Example: How to Decode Base64 using JavaScript Built-in Methods', + description: + 'In JavaScript, you can decode Base64 strings using the in-built “atob” method and encode them back using the “btoa” method. Here’s how they work:', + methods: [ + { + name: 'atob(base64String)', + description: + 'This JS method decodes a Base64‑encoded string into a plain ASCII string (e.g., text, JSON, or simple data). It assumes the input is valid Base64; malformed strings will throw an error.', + }, + { + name: 'btoa(string)', + description: + 'The btoa method encodes a plain ASCII string into a Base64‑encoded string. It only works reliably with ASCII‑safe text; for UTF‑8 text, you should first encode to bytes (e.g., using TextEncoder) and then encode to Base64.', + }, + ], + examples: [ + { + title: 'Example: decode Base64 → string → JSON', + code: `const base64Json = "eyJuYW1lIjogIkpvaG4iLCAiYWdlIjogMjUsICJjb3VudHJ5IjogIkluZGlhIn0="; +const jsonString = atob(base64Json); +const obj = JSON.parse(jsonString); +console.log(obj.name); // "John"`, + }, + { + title: 'Example: encode plain text → Base64', + code: `const plainText = "Hello World!"; +const encoded = btoa(plainText); +console.log(encoded); // "SGVsbG8gV29ybGQh"`, + }, + ], + note: + 'For UTF‑8 text or binary data, you can combine TextEncoder / Uint8Array with btoa‑like logic, but for quick debugging and API‑style payloads, “atob” and “btoa” methods works pretty well.', + }, + }, development_tools_how_use: { - how_use_title: 'How It’s Used', - how_use_description: 'Common use cases:', + how_use_title: 'What are the use cases for the tool', + how_use_description: 'You can use the Base64 decoder tools for various purposes while debugging, writing code, running API testing activities, or learning purposes, such as:', point: [ { - title: 'Reverse encoded payloads', + title: 'Debugging encoded API payloads', description: - 'Decode Base64 strings sent via APIs, environment variables, or emails.', + 'Decode Base64 in request/response bodies from tools like Postman or browser dev tools to inspect hidden data without writing scripts.', }, { - title: 'Recover embedded text', + title: 'Unpacking log files and traces', description: - 'Extract readable content embedded in HTML, JSON, or data URIs.', + 'Extract readable text from Base64-encoded errors, stack traces, or payloads in server logs, Sentry events, or Chrome console outputs.', }, { - title: 'Debugging', + title: 'Handling auth tokens and Basic Auth', + description: + 'Decode strings such as "dXNlcjpwYXNz" to verify credentials in Jira tickets, GitHub PRs, or Slack threads during auth debugging.', + }, + { + title: 'Reverse-engineering emails and configs', + description: + 'Turn Base64 blobs from email attachments, .env files, or YAML configs into plain text for quick reviews in docs or runbooks.', + }, + { + title: 'API integration testing', + description: + 'Decode JWT payloads (base64url variant supported) or GraphQL responses to validate data shapes before writing tests.', + }, + { + title: 'Security audits', + description: + 'Inspect encoded strings in bug reports or vulnerability scans without local decoders.', + }, + { + title: 'Sharing snippets in tickets', + description: + 'Decode once, paste readable output into GitHub issues, Linear tickets, or Azure DevOps for faster team triage.', + }, + { + title: 'Prototyping parsers', + description: + 'Quickly validate Base64 inputs for custom Node.js scripts or browser extensions during dev spikes.', + }, + { + title: 'Learning Base64 encoding/decoding', + description: + 'Students and CS learners can paste example Base64 strings, decode them, and visually see how text, numbers, or JSON map to encoded bytes, helping them understand how Base64 works in URLs, APIs, and configs.', + }, + { + title: 'Educational Demos', + description: + 'Instructors can encode a small snippet (e.g., a JSON object or config) into Base64, share the encoded string with students, and then decode it live in the tool to show the round‑trip between raw data and encoded form.', + }, + { + title: 'Understanding email encodings and headers', + description: + 'Anyone curious about how emails encode attachments or subject lines can paste Base64‑encoded header snippets or MIME sections into the decoder to see the underlying text.', + }, + { + title: 'Exploring API and JWT examples', + description: + 'Beginners can decode example Access Tokens or JWT payloads (base64url) into JSON to inspect claims, roles, and expiry values without installing extra libraries.', + }, + { + title: 'Personal data format experiments', description: - 'Quickly inspect encoded logs or tokens during troubleshooting.', + 'Writers, students, or hobbyists can encode notes, passwords (for demo only), or small configs into Base64, then decode them back to see how encoding affects length and readability.', }, ], }, meta_data: { - meta_title: 'Base64 Decoder – Decode Base64 to Text | Developer Tools', + meta_title: 'Base64 Decoder Online - Developer Utility Tools', meta_description: - 'Decode Base64 online. Paste text or upload a file and convert Base64 to UTF‑8 instantly.', - og_title: 'Base64 Decoder – Free Online Tool', + 'Use the base64 decoder free online tool on BetterBugs.io to instantly decode Base64 strings into plain text, JSON, HEX, or binary data. Perfect for debugging APIs, logs, and encoded payloads.', + og_title: 'Base64 Decoder Online - Developer Utility Tools', og_description: - 'Decode Base64 strings or files to readable text. Fast, simple, and secure.', + 'This post describes usage steps and the use cases of the Base64 decoder free online tool on BetterBugs.io.', og_image: '/images/og-images/Cover.png', }, }, diff --git a/app/page.tsx b/app/page.tsx index 66c5ca2..e9fe913 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -281,7 +281,7 @@ const Page = () => {
{/* Sidebar */} -
+
+ +
+
+
Resize
+
Set output dimensions in pixels
+
+ +
+
+ + setWidthAndMaybeHeight(Number(e.target.value))} + min={1} + max={20000} + disabled={!image} + className="w-full bg-black border border-[#222222] rounded-xl px-4 py-3 text-white focus:outline-none focus:border-primary disabled:opacity-60" + placeholder={image ? String(image.width) : "—"} + /> +
+ +
+ + setHeightAndMaybeWidth(Number(e.target.value))} + min={1} + max={20000} + disabled={!image} + className="w-full bg-black border border-[#222222] rounded-xl px-4 py-3 text-white focus:outline-none focus:border-primary disabled:opacity-60" + placeholder={image ? String(image.height) : "—"} + /> +
+
+ +
+
+ +
Locks width/height together.
+
+ setKeepAspectRatio(e.target.checked)} + disabled={!image} + /> +
+
+ +
+
+
Export
+
Choose format and compression
+
+ +
+ + + +
+ + {format !== "png" && ( +
+
+ Quality + {quality} +
+ setQuality(Number(e.target.value))} + style={{ accentColor: "#00DA92" }} + className="w-full mt-2" + /> +
+ )} + +
+
+
+
Target file size
+
+ Works for JPG/WebP (PNG is lossless). +
+
+
+
+ setTargetSize(Number(e.target.value))} + className="col-span-2 w-full bg-black border border-[#222222] rounded-lg px-3 py-2 text-white focus:outline-none focus:border-primary" + disabled={!image || format === "png"} + /> + +
+ +
+ + {format === "jpg" && ( +
+
+
+
Background
+
JPG has no transparency.
+
+
+ setTransparent(!e.target.checked)} + /> + +
+
+ +
+ setBg(e.target.value)} + className="w-9 h-9 rounded-md border border-[#222222]" + disabled={transparent} + /> +
+ {["#ffffff", "#000000", "#f43f5e", "#f59e0b", "#10b981", "#3b82f6"].map((c) => ( +
+
+
+ )} + +
+ + +
+
+
+ +
+
+
+
+
Preview
+
Canvas render of your export
+
+ {image && ( +
+ Output: {targetWidth}×{targetHeight}px +
+ )} +
+ +
+ {/* Keep canvas mounted so `draw()` can always produce output */} + + {output ? ( + Resized + ) : ( +
Upload an image to preview the result
+ )} +
+ {output ? ( +
+
+ Size: {(outputBytes / 1024).toFixed(1)} KB +
+ {format !== "png" && ( +
+ Quality: {quality} +
+ )} +
+ ) : null} +
+
+ + + {error && ( +
+
{error}
+
+ )} + + + + + + + ); +}; + +export default ImageResizer; + diff --git a/app/components/developmentToolsComponent/timeCalculator.tsx b/app/components/developmentToolsComponent/timeCalculator.tsx new file mode 100644 index 0000000..3c23cf9 --- /dev/null +++ b/app/components/developmentToolsComponent/timeCalculator.tsx @@ -0,0 +1,425 @@ +"use client"; + +import React, { useMemo, useState } from "react"; +import DevelopmentToolsStyles from "../../developmentToolsStyles.module.scss"; + +type Mode = "add" | "subtract" | "multiply" | "divide" | "between"; +type Unit = "ms" | "s" | "min" | "h" | "d" | "w" | "mo" | "y"; + +const UNIT_OPTIONS: { value: Unit; label: string }[] = [ + { value: "ms", label: "ms" }, + { value: "s", label: "seconds" }, + { value: "min", label: "minutes" }, + { value: "h", label: "hours" }, + { value: "d", label: "days" }, + { value: "w", label: "weeks" }, + { value: "mo", label: "months*" }, + { value: "y", label: "years*" }, +]; + +const UNIT_TO_MS: Record = { + ms: 1, + s: 1000, + min: 60_000, + h: 3_600_000, + d: 86_400_000, + w: 604_800_000, + // Omni-style approximations + mo: 30.5 * 86_400_000, + y: 365 * 86_400_000, +}; + +const pad2 = (n: number) => String(n).padStart(2, "0"); + +const formatPretty = (totalMs: number) => { + const sign = totalMs < 0 ? "-" : ""; + const ms = Math.abs(Math.trunc(totalMs)); + const totalSeconds = Math.floor(ms / 1000); + const seconds = totalSeconds % 60; + const totalMinutes = Math.floor(totalSeconds / 60); + const minutes = totalMinutes % 60; + const hours = Math.floor(totalMinutes / 60); + return `${sign}${hours} h ${minutes} min ${seconds} sec`; +}; + +const breakdown = (totalMs: number) => { + const sign = totalMs < 0 ? -1 : 1; + let ms = Math.abs(Math.trunc(totalMs)); + const days = Math.floor(ms / UNIT_TO_MS.d); + ms -= days * UNIT_TO_MS.d; + const hours = Math.floor(ms / UNIT_TO_MS.h); + ms -= hours * UNIT_TO_MS.h; + const minutes = Math.floor(ms / UNIT_TO_MS.min); + ms -= minutes * UNIT_TO_MS.min; + const seconds = Math.floor(ms / UNIT_TO_MS.s); + ms -= seconds * UNIT_TO_MS.s; + return { sign, days, hours, minutes, seconds, milliseconds: ms }; +}; + +type HMSRow = { h: number; m: number; s: number }; + +const DEFAULT_HMS_ROWS: HMSRow[] = [ + { h: 0, m: 0, s: 0 }, + { h: 0, m: 0, s: 0 }, +]; + +const toMs = (r: HMSRow) => (Number(r.h) * 3600 + Number(r.m) * 60 + Number(r.s)) * 1000; + +const calc = ( + mode: Mode, + rows: HMSRow[], + multiplier: number, + divisor: number, + betweenStart: string, + betweenEnd: string +) => { + const total = rows.reduce((acc, r) => acc + toMs(r), 0); + + if (mode === "add") return { ms: total, error: "" }; + + if (mode === "subtract") { + if (rows.length < 2) return { ms: total, error: "" }; + const first = toMs(rows[0] ?? { h: 0, m: 0, s: 0 }); + const rest = rows.slice(1).reduce((acc, r) => acc + toMs(r), 0); + return { ms: first - rest, error: "" }; + } + + if (mode === "multiply") return { ms: total * Number(multiplier || 0), error: "" }; + + if (mode === "divide") { + const d = Number(divisor || 0); + if (d === 0) return { ms: 0, error: "Divisor cannot be 0." }; + return { ms: total / d, error: "" }; + } + + // between + if (!betweenStart || !betweenEnd) return { ms: 0, error: "" }; + const a = new Date(betweenStart).getTime(); + const b = new Date(betweenEnd).getTime(); + if (!Number.isFinite(a) || !Number.isFinite(b)) { + return { ms: 0, error: "Please select valid start and end dates." }; + } + return { ms: b - a, error: "" }; +}; + +const TimeCalculator = () => { + const [mode, setMode] = useState("add"); + const [rows, setRows] = useState(DEFAULT_HMS_ROWS); + const [resultUnit, setResultUnit] = useState("h"); + const [multiplier, setMultiplier] = useState(2); + const [divisor, setDivisor] = useState(2); + const [betweenStart, setBetweenStart] = useState(""); + const [betweenEnd, setBetweenEnd] = useState(""); + + const computed = useMemo( + () => calc(mode, rows, multiplier, divisor, betweenStart, betweenEnd), + [mode, rows, multiplier, divisor, betweenStart, betweenEnd] + ); + + const resultMs = computed.ms; + const error = computed.error; + + const resultInUnit = useMemo(() => { + const denom = UNIT_TO_MS[resultUnit]; + if (!denom) return 0; + return resultMs / denom; + }, [resultMs, resultUnit]); + + const pretty = useMemo(() => formatPretty(resultMs), [resultMs]); + const parts = useMemo(() => breakdown(resultMs), [resultMs]); + + const addRow = () => setRows((prev) => [...prev, { h: 0, m: 0, s: 0 }]); + const removeRow = (idx: number) => setRows((prev) => prev.filter((_, i) => i !== idx)); + const updateRow = (idx: number, patch: Partial) => + setRows((prev) => prev.map((r, i) => (i === idx ? { ...r, ...patch } : r))); + + const clearAll = () => { + setRows(DEFAULT_HMS_ROWS); + setResultUnit("h"); + setMultiplier(2); + setDivisor(2); + setBetweenStart(""); + setBetweenEnd(""); + setMode("add"); + }; + + const copy = async (text: string) => { + try { + await navigator.clipboard.writeText(text); + } catch { + // ignore + } + }; + + const modeTitle = + mode === "add" + ? "Add time" + : mode === "subtract" + ? "Subtract time" + : mode === "multiply" + ? "Multiply time" + : mode === "divide" + ? "Divide time" + : "Time between dates"; + + return ( +
+
+
+
+
+
+
+
+
+
+
+
Calculator
+
{modeTitle}
+
+ +
+ +
+ + +
+ + {mode === "between" ? ( +
+
+ + setBetweenStart(e.target.value)} + className="w-full bg-black border border-[#222222] rounded-xl px-4 py-3 text-white focus:outline-none focus:border-primary" + /> +
+
+ + setBetweenEnd(e.target.value)} + className="w-full bg-black border border-[#222222] rounded-xl px-4 py-3 text-white focus:outline-none focus:border-primary" + /> +
+
+ ) : ( +
+
Enter values (up to 20 rows)
+
3 ? "bb-thin-scroll max-h-[420px] overflow-auto pr-1" : "" + }`} + style={rows.length > 3 ? { scrollbarWidth: "thin" } : undefined} + > + {rows.slice(0, 20).map((r, idx) => ( +
+
+
+ {idx === 0 ? "Time 1" : idx === 1 ? "Time 2" : `Time ${idx + 1}`} +
+ +
+ +
+
+
+
hrs
+ updateRow(idx, { h: Number(e.target.value) || 0 })} + className="w-full bg-transparent outline-none text-white text-sm" + /> +
+
+
min
+ updateRow(idx, { m: Number(e.target.value) || 0 })} + className="w-full bg-transparent outline-none text-white text-sm" + /> +
+
+
sec
+ updateRow(idx, { s: Number(e.target.value) || 0 })} + className="w-full bg-transparent outline-none text-white text-sm" + /> +
+
+
+
+ ))} +
+ +
+ + + {mode === "multiply" && ( +
+ × + setMultiplier(Number(e.target.value) || 0)} + className="w-28 bg-black border border-[#222222] rounded-lg px-3 py-2 text-white focus:outline-none focus:border-primary" + /> +
+ )} + + {mode === "divide" && ( +
+ ÷ + setDivisor(Number(e.target.value) || 0)} + className="w-28 bg-black border border-[#222222] rounded-lg px-3 py-2 text-white focus:outline-none focus:border-primary" + /> +
+ )} +
+ +
+ Tip: Use multiple rows for add/subtract. Multiply/divide applies to the total. +
+
+ )} + + {error &&
{error}
} +
+
+ +
+
+
+
Result
+
View as formatted time and totals
+
+ +
+
Pretty
+
{pretty}
+
+ +
+
+
+
In units
+ +
+
+ {Number.isFinite(resultInUnit) ? resultInUnit.toFixed(6).replace(/\.?0+$/, "") : "—"} +
+
+ +
+
Breakdown
+
+ {parts.sign < 0 ? "-" : ""} + {parts.days}d {pad2(parts.hours)}h {pad2(parts.minutes)}m {pad2(parts.seconds)}s +
+
{parts.milliseconds} ms
+
+
+ +
+ + + +
+
+
+
+
+
+
+
+
+ +
+ ); +}; + +export default TimeCalculator; + diff --git a/app/developmentToolsStyles.module.scss b/app/developmentToolsStyles.module.scss index cb04ee0..eefe24c 100644 --- a/app/developmentToolsStyles.module.scss +++ b/app/developmentToolsStyles.module.scss @@ -1,4 +1,5 @@ @import "./styles/variables.scss"; + // serach box css .searchInput { display: flex; @@ -8,8 +9,6 @@ input { background: #ffffff1a; - border: 1px solid #ffffff66; - color: #ffffff; border-radius: 50px; padding: 2px 24px; height: 40px; @@ -22,6 +21,7 @@ &:focus { opacity: 1; + &::placeholder { opacity: 0%; } @@ -32,6 +32,7 @@ font-size: 16px; transition: all 0.3s linear; } + @media (max-width: 600px) { width: 370px; opacity: 1; @@ -39,163 +40,13 @@ padding: 2px 20px; padding-right: 95px; } + @media (min-width: 768px) { height: 50px; } } } -:global([data-theme="light"]) .pageContainer { - color: #111827; -} - -:global([data-theme="light"]) .contentWrapper { - color: #111827; -} - -:global([data-theme="light"]) .searchInput { - input { - background: #ffffff; - border: 1px solid #e5e7eb; - color: #111827; - opacity: 1; - - &::placeholder { - color: #6b7280; - } - } -} - -:global([data-theme="light"]) .promoPanel { - background: #f9fafb; - border: 1px solid #e5e7eb; - color: #111827; -} - -:global([data-theme="light"]) .filterSidebar { - background: #f9fafb; - border: 1px solid #e5e7eb; -} - -:global([data-theme="light"]) .favoriteButton { - background: #ffffff; - border-color: #e5e7eb; - color: #111827; - - &:hover { - background: #f3f4f6; - border-color: #d1d5db; - } - - &[data-active="true"] { - background: #e6f9f2; - border-color: #10b981; - color: #065f46; - } -} - -:global([data-theme="light"]) .favoriteCount { - color: #4b5563; -} - -:global([data-theme="light"]) .favoriteButton[data-active="true"] .favoriteCount { - color: #065f46; -} - -:global([data-theme="light"]) .filterHeading { - color: #111827; -} - -:global([data-theme="light"]) .filterSubLabel { - color: #4b5563; -} - -:global([data-theme="light"]) .filterCategoryButton { - background: #ffffff; - border-color: #e5e7eb; - color: #111827; - - &:hover { - background: #f6f7f8; - border-color: #d1d5db; - } - - &[data-active="true"] { - background: #e6f9f2; - border-color: #10b981; - color: #065f46; - } -} - -:global([data-theme="light"]) .filterBasisButton { - background: #ffffff; - border-color: #e5e7eb; - color: #111827; - - &:hover { - background: #f6f7f8; - border-color: #d1d5db; - } - - &[data-active="true"] { - background: #e6f9f2; - border-color: #10b981; - color: #065f46; - } -} - -:global([data-theme="light"]) .showingCount { - color: #4b5563; -} - -:global([data-theme="light"]) .activeFilterPill { - background: #f3f4f6; - border-color: #e5e7eb; - color: #111827; - - &:hover { - background: #e5e7eb; - } -} - -:global([data-theme="light"]) .sidePanel { - background: #f9fafb; - border: 1px solid #e5e7eb; - border-radius: 0.75rem; - color: #111827; - padding: 1rem; -} - -:global([data-theme="light"]) .sidePanelItem { - background: #ffffff; - border-color: #e5e7eb; - color: #111827; - - &:hover { - background: #f3f4f6; - border-color: #10b981; - } -} - -:global([data-theme="light"]) .toolCard { - background: #ffffff; - border: 1px solid #e5e7eb; -} - -:global([data-theme="light"]) .toolCardDescription { - color: #4b5563; -} - -:global([data-theme="light"]) .toolCardMeta { - color: #6b7280; -} - -:global([data-theme="light"]) .contentCardHoverEffect { - &:hover { - box-shadow: 2px 2px 4px rgba(16, 185, 129, 0.18); - } -} - // tab background color .tabBackgroundColor { background: linear-gradient(91.15deg, #11e498 11.3%, #05bae2 101.69%); @@ -213,13 +64,16 @@ // content card hover effect .contentCardHoverEffect { border-left: 2px solid #11e498; - div > p > svg { + + div>p>svg { color: #11e498; } + &:hover { - div > p > svg { + div>p>svg { color: black; } + background: linear-gradient(92.9deg, #00d1ff 23.92%, #16fca9 100.19%); transform: scale(0.4); -webkit-transform: scale(1.1); @@ -237,23 +91,22 @@ .converterButton { background: $primary; } + .clearButton { background: rgb(255, 79, 108); } + .copyButton { background: #00d0ff9a; } -.addToChromeButton { - background: #000000; - color: #ffffff; -} - /* Webkit custom scrollbar styles */ .scrollbar { overflow: auto; - scrollbar-width: thin; /* Firefox */ - scrollbar-color: rgba(255, 255, 255, 0.3) rgba(255, 255, 255, 0.05); /* Firefox */ + scrollbar-width: thin; + /* Firefox */ + scrollbar-color: rgba(255, 255, 255, 0.3) rgba(255, 255, 255, 0.05); + /* Firefox */ } /* Scrollbar track (background of the scrollbar) */ @@ -285,8 +138,10 @@ /* Modern scrollbar for code blocks */ .modernScrollbar { overflow: auto; - scrollbar-width: thin; /* Firefox */ - scrollbar-color: rgba(17, 228, 152, 0.4) rgba(255, 255, 255, 0.05); /* Firefox - using primary color */ + scrollbar-width: thin; + /* Firefox */ + scrollbar-color: rgba(17, 228, 152, 0.4) rgba(255, 255, 255, 0.05); + /* Firefox - using primary color */ } .modernScrollbar::-webkit-scrollbar { @@ -309,4 +164,4 @@ .modernScrollbar::-webkit-scrollbar-track { background-color: rgba(255, 255, 255, 0.05); border-radius: 10px; -} +} \ No newline at end of file diff --git a/app/libs/constants.tsx b/app/libs/constants.tsx index 5e558a0..2e38a8f 100644 --- a/app/libs/constants.tsx +++ b/app/libs/constants.tsx @@ -144,6 +144,7 @@ import RgbToCmykConverter from '../components/developmentToolsComponent/rgbToCmy import RgbToHexConverter from '../components/developmentToolsComponent/rgbToHexConverter'; import Rot13EncoderDecoderComponent from '../components/developmentToolsComponent/rot13EncoderDecoderComponent'; import RotateImageTool from '../components/developmentToolsComponent/rotateImageTool'; +import ImageResizer from '../components/developmentToolsComponent/imageResizer'; import RotationCalculatorComponent from '../components/developmentToolsComponent/rotationCalculatorComponent'; import ScssToCssConverter from '../components/developmentToolsComponent/scssToCssConverter'; import ShuffleLetters from '../components/developmentToolsComponent/shuffleLetters'; @@ -190,6 +191,7 @@ import XorCalculator from '../components/developmentToolsComponent/xorCalculator import CurlToCodeConverter from '../components/developmentToolsComponent/curlToCodeConverter'; import YAMLFormatterAndBeautifier from '../components/developmentToolsComponent/yamlFormatterAndBeautifier'; import EpochConverter from '../components/developmentToolsComponent/epochConverter'; +import TimeCalculator from '../components/developmentToolsComponent/timeCalculator'; export const WEB_URL = 'https://www.betterbugs.io'; @@ -1624,6 +1626,12 @@ export const developmentToolsCategoryContent: any = { title: 'Unix Timestamp Converter', description: 'Convert Unix timestamps to readable dates and vice versa.', }, + { + url: '/time-calculator', + title: 'Time Calculator', + description: + 'Add, subtract, multiply, divide time, or calculate the time between dates.', + }, ], Category179: [ { @@ -1633,6 +1641,19 @@ export const developmentToolsCategoryContent: any = { 'Decompose complex URLs into legible components and edit query parameters in a visual table.', }, ], + Category180: [ + { + url: '/url-encode', + title: 'URL Encode', + description: 'Encode URLs.', + }, + { + url: '/image-resizer', + title: 'Image Resizer', + description: + 'Resize images locally in your browser. Keep aspect ratio, choose format, and download.', + }, + ], }; export const PATHS = { @@ -1817,6 +1838,8 @@ export const PATHS = { MORSE_CODE_TRANSLATOR: '/morse-code-translator', CURL_TO_CODE_CONVERTER: '/curl-to-code-converter', UNIX_TIMESTAMP_CONVERTER: '/unix-timestamp-converter', + IMAGE_RESIZER: '/image-resizer', + TIME_CALCULATOR: '/time-calculator', }; export const developmentToolsRoutes = [ @@ -2075,6 +2098,10 @@ export const developmentToolsRoutes = [ path: PATHS.ROTATE_IMAGE_TOOL, component: , }, + { + path: PATHS.IMAGE_RESIZER, + component: , + }, { path: PATHS.CSV_TO_EXCEL_FILE_CONVERTOR, component: , @@ -2540,6 +2567,7 @@ export const developmentToolsRoutes = [ path: PATHS.UNIX_TIMESTAMP_CONVERTER, component: , }, + { path: PATHS.TIME_CALCULATOR, component: }, ]; // lorem ipsum text diff --git a/app/libs/developmentToolsConstant.tsx b/app/libs/developmentToolsConstant.tsx index 48a7d67..d80d449 100644 --- a/app/libs/developmentToolsConstant.tsx +++ b/app/libs/developmentToolsConstant.tsx @@ -11683,6 +11683,192 @@ console.log(encoded); // "SGVsbG8gV29ybGQh"`, og_image: '/images/og-images/Cover.png', }, }, + [`image-resizer`]: { + hero_section: { + title: 'Image Resizer', + description: + 'Resize images locally in your browser. Keep aspect ratio, choose output format (PNG/JPG/WebP), and download the resized file.', + }, + development_tools_list: [ + { tool: 'Rotate Image Tool', url: PATHS.ROTATE_IMAGE_TOOL }, + { tool: 'Placeholder Image Generator', url: PATHS.PLACEHOLDER_IMAGE_GENERATOR }, + { tool: 'Color Picker Tool', url: PATHS.COLOR_PICKER_TOOL }, + { tool: 'SVG to React/CSS Utility', url: PATHS.SVG_CONVERTER }, + { tool: 'CSS Minify', url: PATHS.CSS_MINIFY }, + { tool: 'URL Encode', url: PATHS.URL_ENCODE }, + ], + development_tools_about_details: { + about_title: 'What is the Image Resizer tool?', + about_description: [ + { + description: + 'The Image Resizer helps you change an image’s pixel dimensions (width and height) without uploading it to a server. Everything runs locally in your browser.', + }, + { + description: + 'Use it to prepare assets for websites, emails, social previews, or product listings, and to quickly generate smaller image variants for performance.', + }, + ], + }, + development_tools_steps_guide: { + guide_title: 'How to use the Image Resizer', + guide_description: 'Resize an image in a few simple steps:', + steps: [ + { + step_key: 'Step 1:', + step_title: 'Upload an image', + step_description: + 'Drag and drop an image file (or choose a file) to load it into the resizer.', + }, + { + step_key: 'Step 2:', + step_title: 'Set the target size', + step_description: + 'Enter the width and height in pixels. Enable “Keep aspect ratio” to automatically calculate the other dimension.', + }, + { + step_key: 'Step 3:', + step_title: 'Pick output format and quality', + step_description: + 'Choose PNG, JPG, or WebP. For JPG/WebP, adjust quality to balance file size and clarity.', + }, + { + step_key: 'Step 4:', + step_title: 'Download the resized image', + step_description: + 'Preview the result and download the resized image with the selected settings.', + }, + ], + }, + development_tools_how_use: { + how_use_title: 'How It’s Used', + how_use_description: 'Common use cases for resizing images:', + point: [ + { + title: 'Preparing web assets', + description: + 'Resize hero images, thumbnails, and blog illustrations to the exact dimensions your layout needs.', + }, + { + title: 'Performance optimization', + description: + 'Create smaller variants to reduce page weight and improve Core Web Vitals (especially LCP).', + }, + { + title: 'Consistent content sizing', + description: + 'Standardize image sizes for product grids, cards, and social media previews.', + }, + { + title: 'Fast QA & debugging', + description: + 'Quickly generate test images at specific dimensions when validating responsive UI behavior.', + }, + ], + }, + meta_data: { + meta_title: 'Image Resizer – Resize Images Online (PNG/JPG/WebP)', + meta_description: + 'Resize images locally in your browser. Keep aspect ratio, choose PNG/JPG/WebP output, adjust quality, and download the resized image instantly.', + og_title: 'Image Resizer – Online Image Resize Tool', + og_description: + 'Resize images to exact pixel dimensions with optional aspect ratio lock. Export as PNG, JPG, or WebP and download immediately.', + og_image: '/images/og-images/Cover.png', + }, + }, + [`time-calculator`]: { + hero_section: { + title: 'Time Calculator', + description: + 'Add, subtract, multiply, divide time, or calculate the time between dates. Useful for planning tasks, estimating durations, and working with timestamps.', + }, + development_tools_list: [ + { tool: 'Unix Timestamp Converter', url: PATHS.UNIX_TIMESTAMP_CONVERTER }, + { tool: 'Random Date Generator', url: PATHS.RANDOM_DATE_GENERATOR }, + { tool: 'Random Time Generator', url: PATHS.RANDOM_CLOCK_TIME_GENERATOR }, + { tool: 'URL Parser & Query String Editor', url: PATHS.URL_PARSER }, + { tool: 'JSON Prettifier', url: PATHS.JSON_PRETTIFIER }, + { tool: 'Code Compare Tool', url: PATHS.CODE_COMPARE_TOOL }, + ], + development_tools_about_details: { + about_title: 'What is the Time Calculator?', + about_description: [ + { + description: + 'The Time Calculator helps you perform common operations on time values—adding, subtracting, multiplying, dividing, and finding the duration between dates.', + }, + { + description: + 'Use it for planning tasks, estimating project durations, tracking SLAs, or quickly converting totals into a readable time breakdown.', + }, + ], + }, + development_tools_steps_guide: { + guide_title: 'How to use the Time Calculator', + guide_description: 'Calculate time in a few steps:', + steps: [ + { + step_key: 'Step 1:', + step_title: 'Choose an operation', + step_description: + 'Select whether you want to add, subtract, multiply, divide time, or find the time between dates.', + }, + { + step_key: 'Step 2:', + step_title: 'Enter time values or dates', + step_description: + 'Add one or more rows of time values (hours, minutes, etc.), or choose start/end dates for a duration calculation.', + }, + { + step_key: 'Step 3:', + step_title: 'Adjust multipliers/units (optional)', + step_description: + 'For multiply/divide, set the multiplier or divisor. Choose a result unit to see totals in seconds, hours, days, and more.', + }, + { + step_key: 'Step 4:', + step_title: 'Copy the output', + step_description: + 'Copy a pretty formatted result, milliseconds, or seconds for use in docs, tickets, spreadsheets, or code.', + }, + ], + }, + development_tools_how_use: { + how_use_title: 'How It’s Used', + how_use_description: 'Common scenarios:', + point: [ + { + title: 'Planning & estimation', + description: + 'Add up multiple task durations to estimate total time required.', + }, + { + title: 'SLA / time windows', + description: + 'Compute allowed windows by subtracting or dividing time budgets.', + }, + { + title: 'Between two dates', + description: + 'Find the exact duration between a start and end timestamp.', + }, + { + title: 'Engineering & QA', + description: + 'Convert totals into readable breakdowns when debugging timers and intervals.', + }, + ], + }, + meta_data: { + meta_title: 'Time Calculator – Add, Subtract, Multiply & Divide Time', + meta_description: + 'A free time calculator to add, subtract, multiply, divide time, and calculate the time between dates. Get pretty results and copy seconds/milliseconds.', + og_title: 'Time Calculator – Online Tool', + og_description: + 'Calculate time instantly: add/subtract durations, multiply/divide time, or find the time between dates. Copy pretty output, seconds, or ms.', + og_image: '/images/og-images/Cover.png', + }, + }, [`text-to-html-entities-convertor`]: { hero_section: { title: 'Text to HTML Entities Converter', diff --git a/app/page.tsx b/app/page.tsx index 2413337..09e17c6 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -304,7 +304,7 @@ const Page = () => {
{/* Sidebar */}