From 6cd25a743e32fceeaec8c1f8b94927a9c5d901f1 Mon Sep 17 00:00:00 2001 From: Corentin Thomasset Date: Sun, 24 Jul 2022 10:38:28 +0200 Subject: [PATCH 001/440] fix(typo): fix few typos --- src/layouts/base.layout.vue | 4 ++-- src/pages/404.page.vue | 2 +- src/pages/About.vue | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/layouts/base.layout.vue b/src/layouts/base.layout.vue index 0210a633..9171ecb6 100644 --- a/src/layouts/base.layout.vue +++ b/src/layouts/base.layout.vue @@ -107,7 +107,7 @@ const menuOptions: MenuGroupOption[] = toolsByCategory.map((category) => ({ :size="styleStore.isSmallScreen ? 'medium' : 'large'" circle quaternary - aria-label="Toogle menu" + aria-label="Toggle menu" @click="styleStore.isMenuCollapsed = !styleStore.isMenuCollapsed" > @@ -147,7 +147,7 @@ const menuOptions: MenuGroupOption[] = toolsByCategory.map((category) => ({ Sponsor - ❤ Support IT Tools developement ! + ❤ Support IT Tools development ! diff --git a/src/pages/404.page.vue b/src/pages/404.page.vue index ba814d41..b8cba46c 100644 --- a/src/pages/404.page.vue +++ b/src/pages/404.page.vue @@ -6,7 +6,7 @@ useHead({ title: 'Page not found - IT Tools' }); diff --git a/src/pages/Home.page.vue b/src/pages/Home.page.vue index 88086ee4..4c80494a 100644 --- a/src/pages/Home.page.vue +++ b/src/pages/Home.page.vue @@ -1,10 +1,12 @@ @@ -32,8 +34,34 @@ useHead({ title: 'IT Tools - Handy online tools for developers' }); - - + + + +
+ Your favorite tools + + + + + +
+
+ +
+ Newest tools + + + + + +
+ + All the tools + + + + + @@ -43,4 +71,23 @@ useHead({ title: 'IT Tools - Handy online tools for developers' }); .home-page { padding-top: 50px; } + +::v-deep(.n-grid) { + margin-bottom: 12px; +} + +.height-enter-active, +.height-leave-active { + transition: all 0.5s ease-in-out; + overflow: hidden; + max-height: 500px; +} + +.height-enter-from, +.height-leave-to { + max-height: 42px; + overflow: hidden; + opacity: 0; + margin-bottom: 0; +} diff --git a/src/tools/index.ts b/src/tools/index.ts index 60ad21d0..38975f61 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -1,5 +1,4 @@ import { LockOpen } from '@vicons/tabler'; -import type { ToolCategory } from './tool'; import { tool as chmodCalculator } from './chmod-calculator'; import { tool as mimeTypes } from './mime-types'; @@ -36,16 +35,15 @@ import { tool as tokenGenerator } from './token-generator'; import { tool as urlEncoder } from './url-encoder'; import { tool as urlParser } from './url-parser'; import { tool as uuidGenerator } from './uuid-generator'; +import type { ToolCategory } from './tools.types'; export const toolsByCategory: ToolCategory[] = [ { name: 'Crypto', - icon: LockOpen, components: [tokenGenerator, hashText, bcrypt, uuidGenerator, cypher, bip39, hmacGenerator], }, { name: 'Converter', - icon: LockOpen, components: [ dateTimeConverter, baseConverter, @@ -58,7 +56,6 @@ export const toolsByCategory: ToolCategory[] = [ }, { name: 'Web', - icon: LockOpen, components: [ urlEncoder, htmlEntities, @@ -72,27 +69,22 @@ export const toolsByCategory: ToolCategory[] = [ }, { name: 'Images', - icon: LockOpen, components: [qrCodeGenerator, svgPlaceholderGenerator], }, { name: 'Development', - icon: LockOpen, components: [gitMemo, randomPortGenerator, crontabGenerator, jsonViewer, sqlPrettify, chmodCalculator], }, { name: 'Math', - icon: LockOpen, components: [mathEvaluator, etaCalculator], }, { name: 'Measurement', - icon: LockOpen, components: [chronometer], }, { name: 'Text', - icon: LockOpen, components: [loremIpsumGenerator, textStatistics], }, ]; diff --git a/src/tools/tool.ts b/src/tools/tool.ts index b2ebf497..8289aa33 100644 --- a/src/tools/tool.ts +++ b/src/tools/tool.ts @@ -1,27 +1,10 @@ import { config } from '@/config'; -import type { Component } from 'vue'; - -export interface ITool { - name: string; - path: string; - description: string; - keywords: string[]; - component: () => Promise; - icon: Component; - redirectFrom?: string[]; - isNew: boolean; -} - -export interface ToolCategory { - name: string; - icon: Component; - components: ITool[]; -} +import type { Tool } from './tools.types'; type WithOptional = Omit & Partial>; export function defineTool( - tool: WithOptional, + tool: WithOptional, { newTools }: { newTools: string[] } = { newTools: config.tools.newTools }, ) { const isNew = newTools.includes(tool.name); diff --git a/src/tools/tools.store.ts b/src/tools/tools.store.ts new file mode 100644 index 00000000..2b0826c1 --- /dev/null +++ b/src/tools/tools.store.ts @@ -0,0 +1,44 @@ +import { get, useStorage, type MaybeRef } from '@vueuse/core'; +import { defineStore } from 'pinia'; +import type { Ref } from 'vue'; +import { toolsWithCategory } from './index'; +import type { Tool, ToolWithCategory } from './tools.types'; + +export const useToolStore = defineStore('tools', { + state: () => ({ + favoriteToolsName: useStorage('favoriteToolsName', []) as Ref, + }), + getters: { + favoriteTools(state) { + return state.favoriteToolsName + .map((favoriteName) => toolsWithCategory.find(({ name }) => name === favoriteName)) + .filter(Boolean) as ToolWithCategory[]; // cast because .filter(Boolean) does not remove undefined from type + }, + + notFavoriteTools(state): ToolWithCategory[] { + return toolsWithCategory.filter((tool) => !state.favoriteToolsName.includes(tool.name)); + }, + + tools(): ToolWithCategory[] { + return toolsWithCategory; + }, + + newTools(): ToolWithCategory[] { + return this.tools.filter(({ isNew }) => isNew); + }, + }, + + actions: { + addToolToFavorites({ tool }: { tool: MaybeRef }) { + this.favoriteToolsName.push(get(tool).name); + }, + + removeToolFromFavorites({ tool }: { tool: MaybeRef }) { + this.favoriteToolsName = this.favoriteToolsName.filter((name) => get(tool).name !== name); + }, + + isToolFavorite({ tool }: { tool: MaybeRef }) { + return this.favoriteToolsName.includes(get(tool).name); + }, + }, +}); diff --git a/src/tools/tools.types.ts b/src/tools/tools.types.ts new file mode 100644 index 00000000..5630a12e --- /dev/null +++ b/src/tools/tools.types.ts @@ -0,0 +1,19 @@ +import type { Component } from 'vue'; + +export type Tool = { + name: string; + path: string; + description: string; + keywords: string[]; + component: () => Promise; + icon: Component; + redirectFrom?: string[]; + isNew: boolean; +}; + +export type ToolCategory = { + name: string; + components: Tool[]; +}; + +export type ToolWithCategory = Tool & { category: string }; From 679dd1c1f6265227cc9db60c55d83f8eaf8f72b4 Mon Sep 17 00:00:00 2001 From: Corentin Thomasset Date: Sat, 17 Dec 2022 01:30:27 +0100 Subject: [PATCH 076/440] refactor(menu): improve support button --- src/layouts/base.layout.vue | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/layouts/base.layout.vue b/src/layouts/base.layout.vue index 23e23d22..aa7ef8f0 100644 --- a/src/layouts/base.layout.vue +++ b/src/layouts/base.layout.vue @@ -7,7 +7,7 @@ import { toolsByCategory } from '@/tools'; import { useStyleStore } from '@/stores/style.store'; import { config } from '@/config'; import MenuIconItem from '@/components/MenuIconItem.vue'; -import type { ITool } from '@/tools/tool'; +import type { Tool } from '@/tools/tools.types'; import SearchBar from '../components/SearchBar.vue'; import HeroGradient from '../assets/hero-gradient.svg?component'; import MenuLayout from '../components/MenuLayout.vue'; @@ -19,8 +19,8 @@ const styleStore = useStyleStore(); const version = config.app.version; const commitSha = config.app.lastCommitSha.slice(0, 7); -const makeLabel = (tool: ITool) => () => h(RouterLink, { to: tool.path }, { default: () => tool.name }); -const makeIcon = (tool: ITool) => () => h(MenuIconItem, { tool }); +const makeLabel = (tool: Tool) => () => h(RouterLink, { to: tool.path }, { default: () => tool.name }); +const makeIcon = (tool: Tool) => () => h(MenuIconItem, { tool }); const menuOptions: MenuGroupOption[] = toolsByCategory.map((category) => ({ label: category.name, @@ -145,9 +145,12 @@ const menuOptions: MenuGroupOption[] = toolsByCategory.map((category) => ({ href="https://github.com/sponsors/CorentinTh" rel="noopener" target="_blank" + class="support-button" + :bordered="false" > Buy me a coffee - + + ❤ Support IT Tools development ! @@ -170,6 +173,19 @@ const menuOptions: MenuGroupOption[] = toolsByCategory.map((category) => ({ // background-size: @size @size; // } +.support-button { + background: rgb(37, 99, 108); + background: linear-gradient(48deg, rgba(37, 99, 108, 1) 0%, rgba(59, 149, 111, 1) 60%, rgba(20, 160, 88, 1) 100%); + color: #fff; + transition: all ease 0.2s; + + &:hover { + color: #fff; + padding-left: 30px; + padding-right: 30px; + } +} + .footer { text-align: center; color: #838587; From 274ff02b5492c7a2ac01c22064b07892dad42f18 Mon Sep 17 00:00:00 2001 From: Corentin Thomasset Date: Sat, 17 Dec 2022 11:42:47 +0100 Subject: [PATCH 077/440] chore(git): added .env to gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 38adffa6..cd1e2011 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,5 @@ coverage *.njsproj *.sln *.sw? + +.env \ No newline at end of file From af075dccccec959a0863e6d11516206860bed91f Mon Sep 17 00:00:00 2001 From: Corentin Thomasset Date: Sat, 17 Dec 2022 15:33:52 +0100 Subject: [PATCH 078/440] feat(tool): improved favorite tool management --- src/layouts/base.layout.vue | 33 +++++++++----- src/layouts/tool.layout.vue | 31 ++++++------- src/pages/Home.page.vue | 90 ++++++++++++++++++++----------------- 3 files changed, 83 insertions(+), 71 deletions(-) diff --git a/src/layouts/base.layout.vue b/src/layouts/base.layout.vue index aa7ef8f0..e2132185 100644 --- a/src/layouts/base.layout.vue +++ b/src/layouts/base.layout.vue @@ -1,6 +1,6 @@ ❤ Support IT Tools development ! diff --git a/src/layouts/tool.layout.vue b/src/layouts/tool.layout.vue index bb3665ea..6cccbb05 100644 --- a/src/layouts/tool.layout.vue +++ b/src/layouts/tool.layout.vue @@ -3,22 +3,22 @@ import { useRoute } from 'vue-router'; import { useHead } from '@vueuse/head'; import type { HeadObject } from '@vueuse/head'; import { computed } from 'vue'; -import { useThemeVars } from 'naive-ui'; +import FavoriteButton from '@/components/FavoriteButton.vue'; +import type { Tool } from '@/tools/tools.types'; import BaseLayout from './base.layout.vue'; const route = useRoute(); -const theme = useThemeVars(); const head = computed(() => ({ title: `${route.meta.name} - IT Tools`, meta: [ { name: 'description', - content: route.meta.description, + content: route.meta?.description as string, }, { name: 'keywords', - content: route.meta.keywords, + content: ((route.meta.keywords ?? []) as string[]).join(','), }, ], })); @@ -29,22 +29,18 @@ useHead(head);
- - {{ route.meta.name }} + + + {{ route.meta.name }} + - - New tool - - - +
+ +
+
+
{{ route.meta.description }}
@@ -92,6 +88,7 @@ useHead(head); width: 200px; height: 2px; background: rgb(161, 161, 161); + opacity: 0.2; margin: 10px 0; } diff --git a/src/pages/Home.page.vue b/src/pages/Home.page.vue index 4c80494a..b0b9fc00 100644 --- a/src/pages/Home.page.vue +++ b/src/pages/Home.page.vue @@ -12,58 +12,60 @@ useHead({ title: 'IT Tools - Handy online tools for developers' }); @@ -72,8 +74,12 @@ useHead({ title: 'IT Tools - Handy online tools for developers' }); padding-top: 50px; } +.n-h3 { + margin-bottom: 10px; +} + ::v-deep(.n-grid) { - margin-bottom: 12px; + margin-bottom: 30px; } .height-enter-active, From 7f964941d3ea259120e876445e61e764d41a8a23 Mon Sep 17 00:00:00 2001 From: Corentin Thomasset Date: Tue, 20 Dec 2022 20:57:24 +0100 Subject: [PATCH 079/440] chore(docs): updated readme --- README.md | 48 ++++++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index efcc5538..0ba0dcc6 100644 --- a/README.md +++ b/README.md @@ -10,46 +10,53 @@ You have an idea of a tool? Submit a [feature request](https://github.com/Corent ## Contribute -### Recommended IDE Setup +## Recommended IDE Setup -[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.vscode-typescript-vue-plugin). +[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin). -### Node version +## Type Support for `.vue` Imports in TS -Ensure you have the correct node/npm version +TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types. + +If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps: + +1. Disable the built-in TypeScript Extension + 1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette + 2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)` +2. Reload the VSCode window by running `Developer: Reload Window` from the command palette. + +## Customize configuration + +See [Vite Configuration Reference](https://vitejs.dev/config/). + +## Project Setup ```sh -nvm use +pnpm install ``` -### Project Setup +### Compile and Hot-Reload for Development ```sh -npm install +pnpm dev ``` -#### Compile and Hot-Reload for Development +### Type-Check, Compile and Minify for Production ```sh -npm run dev +pnpm build ``` -#### Type-Check, Compile and Minify for Production +### Run Unit Tests with [Vitest](https://vitest.dev/) ```sh -npm run build +pnpm test ``` -#### Run Unit Tests with [Vitest](https://vitest.dev/) +### Lint with [ESLint](https://eslint.org/) ```sh -npm run test -``` - -#### Lint with [ESLint](https://eslint.org/) - -```sh -npm run lint +pnpm lint ``` ### Create a new tool @@ -68,12 +75,9 @@ Coded with ❤️ by [Corentin Thomasset](//corentin-thomasset.fr). This project is continuously deployed using [vercel.com](https://vercel.com). - - IT Tools - Collection of handy online tools for devs, with great UX | Product Hunt IT Tools - Collection of handy online tools for devs, with great UX | Product Hunt - ## License This project is under the [GNU GPLv3](LICENSE). From cf723f144ee865b6de7323d3be58eb7a9586fa56 Mon Sep 17 00:00:00 2001 From: Corentin Thomasset Date: Tue, 20 Dec 2022 21:01:34 +0100 Subject: [PATCH 080/440] refactor(clean): removed empty style tag --- src/components/FavoriteButton.vue | 2 -- src/components/SearchBar.vue | 2 -- src/tools/base64-string-converter/base64-string-converter.vue | 2 -- src/tools/hmac-generator/hmac-generator.vue | 2 -- src/tools/math-evaluator/math-evaluator.vue | 2 -- src/tools/mime-types/mime-types.vue | 2 -- 6 files changed, 12 deletions(-) diff --git a/src/components/FavoriteButton.vue b/src/components/FavoriteButton.vue index 26791f3a..4b7f561f 100644 --- a/src/components/FavoriteButton.vue +++ b/src/components/FavoriteButton.vue @@ -36,5 +36,3 @@ function toggleFavorite(event: MouseEvent) { toolStore.addToolToFavorites({ tool }); } - - diff --git a/src/components/SearchBar.vue b/src/components/SearchBar.vue index 95919d5d..22842a42 100644 --- a/src/components/SearchBar.vue +++ b/src/components/SearchBar.vue @@ -82,5 +82,3 @@ function renderOption({ tool }: { tool: Tool }) {
- - diff --git a/src/tools/base64-string-converter/base64-string-converter.vue b/src/tools/base64-string-converter/base64-string-converter.vue index d725117c..649f9d39 100644 --- a/src/tools/base64-string-converter/base64-string-converter.vue +++ b/src/tools/base64-string-converter/base64-string-converter.vue @@ -53,5 +53,3 @@ const b64Validation = useValidation({ rules: [{ message: 'Invalid base64 string', validator: (value) => isValidBase64(value.trim()) }], }); - - diff --git a/src/tools/hmac-generator/hmac-generator.vue b/src/tools/hmac-generator/hmac-generator.vue index 3c524259..9cf2c9bf 100644 --- a/src/tools/hmac-generator/hmac-generator.vue +++ b/src/tools/hmac-generator/hmac-generator.vue @@ -94,5 +94,3 @@ const hmac = computed(() => ); const { copy } = useCopy({ source: hmac }); - - diff --git a/src/tools/math-evaluator/math-evaluator.vue b/src/tools/math-evaluator/math-evaluator.vue index 59754de6..16aa7c47 100644 --- a/src/tools/math-evaluator/math-evaluator.vue +++ b/src/tools/math-evaluator/math-evaluator.vue @@ -29,5 +29,3 @@ const expression = ref(''); const result = computed(() => withDefaultOnError(() => evaluate(expression.value) ?? '', '')); - - diff --git a/src/tools/mime-types/mime-types.vue b/src/tools/mime-types/mime-types.vue index 0c7a5eb0..eb08124f 100644 --- a/src/tools/mime-types/mime-types.vue +++ b/src/tools/mime-types/mime-types.vue @@ -95,5 +95,3 @@ const selectedExtension = ref(undefined); const mimeTypeFound = computed(() => (selectedExtension.value ? extensionToMimeType[selectedExtension.value] : [])); - - From 40872859a580a20bb838b79db2b3c88c00995e37 Mon Sep 17 00:00:00 2001 From: Corentin Thomasset Date: Tue, 20 Dec 2022 21:15:00 +0100 Subject: [PATCH 081/440] refactor(clean): removed unused import --- src/tools/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/tools/index.ts b/src/tools/index.ts index 38975f61..3b94cb4c 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -1,5 +1,3 @@ -import { LockOpen } from '@vicons/tabler'; - import { tool as chmodCalculator } from './chmod-calculator'; import { tool as mimeTypes } from './mime-types'; import { tool as otpCodeGeneratorAndValidator } from './otp-code-generator-and-validator'; From bfc2e24bbfc08f67ed9c9b1d93474029bc01dc8b Mon Sep 17 00:00:00 2001 From: Corentin Thomasset Date: Wed, 21 Dec 2022 00:03:31 +0100 Subject: [PATCH 082/440] feat(tracker): added actions monitoring --- src/components/SearchBar.vue | 1 + src/layouts/base.layout.vue | 1 + src/modules/tracker/tracker.services.ts | 11 +++++++++++ src/modules/tracker/tracker.types.ts | 3 +++ src/pages/About.vue | 1 + src/plugins/plausible.plugin.ts | 3 ++- src/shims.d.ts | 7 +++++++ 7 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/modules/tracker/tracker.services.ts create mode 100644 src/modules/tracker/tracker.types.ts diff --git a/src/components/SearchBar.vue b/src/components/SearchBar.vue index 22842a42..a93f46a1 100644 --- a/src/components/SearchBar.vue +++ b/src/components/SearchBar.vue @@ -61,6 +61,7 @@ function renderOption({ tool }: { tool: Tool }) { :render-label="renderOption" :default-value="'aa'" :get-show="() => true" + :on-focus="() => $tracker.trackEvent({ eventName: 'Search-bar focused' })" >