1
0
mirror of https://github.com/XFox111/my-website.git synced 2026-07-02 19:52:45 +03:00

119 Commits

Author SHA1 Message Date
xfox111 82b487537c fix: npm audit hotfixes 2026-06-03 06:48:48 +00:00
dependabot[bot] 527a96481f chore(deps): bump the all group with 11 updates
Bumps the all group with 11 updates:

| Package | From | To |
| --- | --- | --- |
| [@fluentui/svg-icons](https://github.com/microsoft/fluentui-system-icons) | `1.1.326` | `1.1.328` |
| [next](https://github.com/vercel/next.js) | `16.2.6` | `16.2.7` |
| [nodemailer](https://github.com/nodemailer/nodemailer) | `8.0.7` | `8.0.10` |
| [react](https://github.com/facebook/react/tree/HEAD/packages/react) | `19.2.6` | `19.2.7` |
| [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) | `19.2.14` | `19.2.16` |
| [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) | `19.2.6` | `19.2.7` |
| [@next/eslint-plugin-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-plugin-next) | `16.2.6` | `16.2.7` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `25.7.0` | `25.9.1` |
| [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next) | `16.2.6` | `16.2.7` |
| [sass](https://github.com/sass/dart-sass) | `1.99.0` | `1.100.0` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.59.3` | `8.60.1` |


Updates `@fluentui/svg-icons` from 1.1.326 to 1.1.328
- [Changelog](https://github.com/microsoft/fluentui-system-icons/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/fluentui-system-icons/compare/1.1.326...1.1.328)

Updates `next` from 16.2.6 to 16.2.7
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v16.2.6...v16.2.7)

Updates `nodemailer` from 8.0.7 to 8.0.10
- [Release notes](https://github.com/nodemailer/nodemailer/releases)
- [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodemailer/nodemailer/compare/v8.0.7...v8.0.10)

Updates `react` from 19.2.6 to 19.2.7
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.7/packages/react)

Updates `@types/react` from 19.2.14 to 19.2.16
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `react-dom` from 19.2.6 to 19.2.7
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.7/packages/react-dom)

Updates `@next/eslint-plugin-next` from 16.2.6 to 16.2.7
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v16.2.7/packages/eslint-plugin-next)

Updates `@types/node` from 25.7.0 to 25.9.1
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@types/react` from 19.2.14 to 19.2.16
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `eslint-config-next` from 16.2.6 to 16.2.7
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v16.2.7/packages/eslint-config-next)

Updates `sass` from 1.99.0 to 1.100.0
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.99.0...1.100.0)

Updates `typescript-eslint` from 8.59.3 to 8.60.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.60.1/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: "@fluentui/svg-icons"
  dependency-version: 1.1.328
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: next
  dependency-version: 16.2.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: nodemailer
  dependency-version: 8.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: react
  dependency-version: 19.2.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: "@types/react"
  dependency-version: 19.2.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: react-dom
  dependency-version: 19.2.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: "@next/eslint-plugin-next"
  dependency-version: 16.2.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: "@types/node"
  dependency-version: 25.9.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: all
- dependency-name: "@types/react"
  dependency-version: 19.2.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: eslint-config-next
  dependency-version: 16.2.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: sass
  dependency-version: 1.100.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: all
- dependency-name: typescript-eslint
  dependency-version: 8.60.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: all
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-03 16:31:46 +12:00
dependabot[bot] e4638ec833 chore(deps): bump ghcr.io/devcontainers/features/docker-in-docker
Bumps the all group with 1 update: ghcr.io/devcontainers/features/docker-in-docker.


Updates `ghcr.io/devcontainers/features/docker-in-docker` from 2.17.0 to 3.0.1

---
updated-dependencies:
- dependency-name: ghcr.io/devcontainers/features/docker-in-docker
  dependency-version: 3.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-03 16:31:07 +12:00
xfox111 e50babc71d chore(deps): npm audit fix 2026-05-14 09:21:35 +00:00
dependabot[bot] f26b99cd8d chore(deps): bump node from 25-alpine to 26-alpine in the all group
Bumps the all group with 1 update: node.


Updates `node` from 25-alpine to 26-alpine

---
updated-dependencies:
- dependency-name: node
  dependency-version: 26-alpine
  dependency-type: direct:production
  dependency-group: all
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-14 21:01:04 +12:00
dependabot[bot] e446a215bb chore(deps): bump the all group across 1 directory with 16 updates
Bumps the all group with 15 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@fluentui/svg-icons](https://github.com/microsoft/fluentui-system-icons) | `1.1.316` | `1.1.326` |
| [next](https://github.com/vercel/next.js) | `16.1.1` | `16.2.6` |
| [nodemailer](https://github.com/nodemailer/nodemailer) | `7.0.12` | `8.0.7` |
| [@types/nodemailer](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/nodemailer) | `7.0.4` | `8.0.0` |
| [react](https://github.com/facebook/react/tree/HEAD/packages/react) | `19.2.3` | `19.2.6` |
| [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) | `19.2.7` | `19.2.14` |
| [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) | `19.2.3` | `19.2.6` |
| [react-social-icons](https://github.com/couetilc/react-social-icons) | `6.25.0` | `6.26.0` |
| [react-turnstile](https://github.com/Le0developer/react-turnstile) | `1.1.4` | `1.1.5` |
| [zod](https://github.com/colinhacks/zod) | `4.3.4` | `4.4.3` |
| [@next/eslint-plugin-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-plugin-next) | `16.1.1` | `16.2.6` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `25.0.3` | `25.7.0` |
| [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next) | `16.1.1` | `16.2.6` |
| [sass](https://github.com/sass/dart-sass) | `1.97.1` | `1.99.0` |
| [typescript](https://github.com/microsoft/TypeScript) | `5.9.3` | `6.0.3` |



Updates `@fluentui/svg-icons` from 1.1.316 to 1.1.326
- [Changelog](https://github.com/microsoft/fluentui-system-icons/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/fluentui-system-icons/compare/1.1.316...1.1.326)

Updates `next` from 16.1.1 to 16.2.6
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v16.1.1...v16.2.6)

Updates `nodemailer` from 7.0.12 to 8.0.7
- [Release notes](https://github.com/nodemailer/nodemailer/releases)
- [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodemailer/nodemailer/compare/v7.0.12...v8.0.7)

Updates `@types/nodemailer` from 7.0.4 to 8.0.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/nodemailer)

Updates `react` from 19.2.3 to 19.2.6
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.6/packages/react)

Updates `@types/react` from 19.2.7 to 19.2.14
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `react-dom` from 19.2.3 to 19.2.6
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.6/packages/react-dom)

Updates `react-social-icons` from 6.25.0 to 6.26.0
- [Release notes](https://github.com/couetilc/react-social-icons/releases)
- [Changelog](https://github.com/couetilc/react-social-icons/blob/main/CHANGELOG.md)
- [Commits](https://github.com/couetilc/react-social-icons/compare/v6.25.0...v6.26.0)

Updates `react-turnstile` from 1.1.4 to 1.1.5
- [Release notes](https://github.com/Le0developer/react-turnstile/releases)
- [Changelog](https://github.com/Le0Developer/react-turnstile/blob/main/HISTORY.md)
- [Commits](https://github.com/Le0developer/react-turnstile/compare/v1.1.4...v1.1.5)

Updates `zod` from 4.3.4 to 4.4.3
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](https://github.com/colinhacks/zod/compare/v4.3.4...v4.4.3)

Updates `@next/eslint-plugin-next` from 16.1.1 to 16.2.6
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v16.2.6/packages/eslint-plugin-next)

Updates `@types/node` from 25.0.3 to 25.7.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@types/nodemailer` from 7.0.4 to 8.0.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/nodemailer)

Updates `@types/react` from 19.2.7 to 19.2.14
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `eslint-config-next` from 16.1.1 to 16.2.6
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v16.2.6/packages/eslint-config-next)

Updates `sass` from 1.97.1 to 1.99.0
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.97.1...1.99.0)

Updates `typescript` from 5.9.3 to 6.0.3
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.9.3...v6.0.3)

Updates `typescript-eslint` from 8.51.0 to 8.59.3
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.3/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: "@fluentui/svg-icons"
  dependency-version: 1.1.326
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: next
  dependency-version: 16.2.6
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all
- dependency-name: nodemailer
  dependency-version: 8.0.7
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all
- dependency-name: "@types/nodemailer"
  dependency-version: 8.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: all
- dependency-name: react
  dependency-version: 19.2.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: "@types/react"
  dependency-version: 19.2.14
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: react-dom
  dependency-version: 19.2.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: react-social-icons
  dependency-version: 6.26.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all
- dependency-name: react-turnstile
  dependency-version: 1.1.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: zod
  dependency-version: 4.4.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all
- dependency-name: "@next/eslint-plugin-next"
  dependency-version: 16.2.6
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: all
- dependency-name: "@types/node"
  dependency-version: 25.7.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: all
- dependency-name: "@types/nodemailer"
  dependency-version: 8.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: all
- dependency-name: "@types/react"
  dependency-version: 19.2.14
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: eslint-config-next
  dependency-version: 16.2.6
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: all
- dependency-name: sass
  dependency-version: 1.99.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: all
- dependency-name: typescript
  dependency-version: 6.0.3
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: all
- dependency-name: typescript-eslint
  dependency-version: 8.59.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: all
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-14 21:00:34 +12:00
dependabot[bot] 6351a9db55 chore(deps): bump ghcr.io/devcontainers/features/node in the all group
Bumps the all group with 1 update: ghcr.io/devcontainers/features/node.


Updates `ghcr.io/devcontainers/features/node` from 1.7.1 to 2.0.0

---
updated-dependencies:
- dependency-name: ghcr.io/devcontainers/features/node
  dependency-version: 2.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-14 20:59:54 +12:00
dependabot[bot] a2e2ad6f88 chore(deps-dev): bump @smithy/config-resolver
Bumps the npm_and_yarn group with 1 update in the / directory: [@smithy/config-resolver](https://github.com/smithy-lang/smithy-typescript/tree/HEAD/packages/config-resolver).


Updates `@smithy/config-resolver` from 4.1.5 to 4.4.5
- [Release notes](https://github.com/smithy-lang/smithy-typescript/releases)
- [Changelog](https://github.com/smithy-lang/smithy-typescript/blob/main/packages/config-resolver/CHANGELOG.md)
- [Commits](https://github.com/smithy-lang/smithy-typescript/commits/@smithy/config-resolver@4.4.5/packages/config-resolver)

---
updated-dependencies:
- dependency-name: "@smithy/config-resolver"
  dependency-version: 4.4.5
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-14 20:48:17 +12:00
dependabot[bot] 60a069e1f6 chore(deps): bump the all group with 3 updates
Bumps the all group with 3 updates: [docker/build-push-action](https://github.com/docker/build-push-action), [docker/metadata-action](https://github.com/docker/metadata-action) and [docker/login-action](https://github.com/docker/login-action).


Updates `docker/build-push-action` from 6 to 7
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v6...v7)

Updates `docker/metadata-action` from 5 to 6
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/v5...v6)

Updates `docker/login-action` from 3 to 4
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all
- dependency-name: docker/metadata-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all
- dependency-name: docker/login-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-14 20:47:37 +12:00
xfox111 2000dbe8d4 chore(ci): Change target branch from 'next' to 'main' in dependabot 2026-01-03 20:24:13 +03:00
dependabot[bot] e344c163bc chore(deps): bump the all group with 10 updates
Bumps the all group with 10 updates:

| Package | From | To |
| --- | --- | --- |
| [next](https://github.com/vercel/next.js) | `16.0.10` | `16.1.1` |
| [nodemailer](https://github.com/nodemailer/nodemailer) | `7.0.11` | `7.0.12` |
| [react](https://github.com/facebook/react/tree/HEAD/packages/react) | `19.2.1` | `19.2.3` |
| [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) | `19.2.1` | `19.2.3` |
| [zod](https://github.com/colinhacks/zod) | `4.1.13` | `4.3.4` |
| [@next/eslint-plugin-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-plugin-next) | `16.0.8` | `16.1.1` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `25.0.0` | `25.0.3` |
| [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next) | `16.0.8` | `16.1.1` |
| [sass](https://github.com/sass/dart-sass) | `1.96.0` | `1.97.1` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.49.0` | `8.51.0` |


Updates `next` from 16.0.10 to 16.1.1
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v16.0.10...v16.1.1)

Updates `nodemailer` from 7.0.11 to 7.0.12
- [Release notes](https://github.com/nodemailer/nodemailer/releases)
- [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodemailer/nodemailer/compare/v7.0.11...v7.0.12)

Updates `react` from 19.2.1 to 19.2.3
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.3/packages/react)

Updates `react-dom` from 19.2.1 to 19.2.3
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.3/packages/react-dom)

Updates `zod` from 4.1.13 to 4.3.4
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](https://github.com/colinhacks/zod/compare/v4.1.13...v4.3.4)

Updates `@next/eslint-plugin-next` from 16.0.8 to 16.1.1
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v16.1.1/packages/eslint-plugin-next)

Updates `@types/node` from 25.0.0 to 25.0.3
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `eslint-config-next` from 16.0.8 to 16.1.1
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v16.1.1/packages/eslint-config-next)

Updates `sass` from 1.96.0 to 1.97.1
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.96.0...1.97.1)

Updates `typescript-eslint` from 8.49.0 to 8.51.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.51.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 16.1.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all
- dependency-name: nodemailer
  dependency-version: 7.0.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: react
  dependency-version: 19.2.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: react-dom
  dependency-version: 19.2.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: zod
  dependency-version: 4.3.4
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all
- dependency-name: "@next/eslint-plugin-next"
  dependency-version: 16.1.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: all
- dependency-name: "@types/node"
  dependency-version: 25.0.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: eslint-config-next
  dependency-version: 16.1.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: all
- dependency-name: sass
  dependency-version: 1.97.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: all
- dependency-name: typescript-eslint
  dependency-version: 8.51.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: all
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-03 20:24:13 +03:00
dependabot[bot] bd0ac821c2 chore(deps): bump next in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [next](https://github.com/vercel/next.js).


Updates `next` from 16.0.9 to 16.0.10
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v16.0.9...v16.0.10)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 16.0.10
  dependency-type: direct:production
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-12 20:33:32 +03:00
dependabot[bot] e694ec53c9 chore(deps): bump next in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [next](https://github.com/vercel/next.js).


Updates `next` from 16.0.8 to 16.0.9
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v16.0.8...v16.0.9)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 16.0.9
  dependency-type: direct:production
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-12 10:12:11 +03:00
xfox111 2c8fe6b540 chore(pr): Merge pull request #202 from XFox111/dependabot/npm_and_yarn/next/all-d81df28d2d
chore(deps-dev): bump the all group with 2 updates
2025-12-11 09:10:38 +03:00
xfox111 2ff4ebd7d5 chore(pr): Merge pull request #201 from XFox111/dependabot/github_actions/next/all-44aa17bcce
chore(deps): bump the all group with 2 updates
2025-12-11 09:10:04 +03:00
xfox111 8291ae2444 chore(deps): bump node from 24-alpine to 25-alpine in the all group #200 2025-12-11 06:08:35 +00:00
dependabot[bot] 3a81a81d56 chore(deps-dev): bump the all group with 2 updates
Bumps the all group with 2 updates: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) and [sass](https://github.com/sass/dart-sass).


Updates `@types/node` from 24.10.2 to 25.0.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `sass` from 1.95.1 to 1.96.0
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.95.1...1.96.0)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 25.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: all
- dependency-name: sass
  dependency-version: 1.96.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: all
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-11 06:06:03 +00:00
dependabot[bot] f2a65c3b47 chore(deps): bump the all group with 2 updates
Bumps the all group with 2 updates: [actions/checkout](https://github.com/actions/checkout) and [github/codeql-action](https://github.com/github/codeql-action).


Updates `actions/checkout` from 5 to 6
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

Updates `github/codeql-action` from 3 to 4
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all
- dependency-name: github/codeql-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-11 06:05:33 +00:00
dependabot[bot] 371bd05238 chore(deps): bump node from 24-alpine to 25-alpine in the all group
Bumps the all group with 1 update: node.


Updates `node` from 24-alpine to 25-alpine

---
updated-dependencies:
- dependency-name: node
  dependency-version: 25-alpine
  dependency-type: direct:production
  dependency-group: all
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-11 06:05:14 +00:00
xfox111 569433b587 feat: website refresh + monthly dependency bump (December 2025) 2025-12-11 09:02:54 +03:00
xfox111 7fc12af5ab chore(ci): group dependabot bumps 2025-12-11 05:57:03 +00:00
xfox111 adb0b4b1b2 feat(dev): migrated from yarn to npm 2025-12-11 05:52:27 +00:00
xfox111 57b3a72fa2 feat!: site refresh + dependency update 2025-12-11 05:51:44 +00:00
xfox111 aac9140830 deps: monthly dependency bump (October 2025)
Merge pull request #184 from XFox111/next
2025-10-05 16:31:49 +05:00
xfox111 0600862bfe chore(deps): bump react-dom, react, @types/react and @types/react-dom
Merge pull request #183 from XFox111/deps/react
2025-10-05 16:28:07 +05:00
xfox111 63895dfef3 chore(deps): bump react and @types/react
Merge pull request #181 from XFox111/dependabot/npm_and_yarn/next/multi-dcae87122d
2025-10-05 16:23:57 +05:00
xfox111 05a4e7f28e Merge branch 'deps/react' into dependabot/npm_and_yarn/next/multi-dcae87122d 2025-10-05 16:23:19 +05:00
dependabot[bot] 7140bff0f6 chore(deps): bump react and @types/react
Bumps [react](https://github.com/facebook/react/tree/HEAD/packages/react) and [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react). These dependencies needed to be updated together.

Updates `react` from 19.1.1 to 19.2.0
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.0/packages/react)

Updates `@types/react` from 19.1.12 to 19.2.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: react
  dependency-version: 19.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: "@types/react"
  dependency-version: 19.2.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-05 11:16:53 +00:00
dependabot[bot] 22b7115b81 chore(deps): bump react-dom and @types/react-dom
Bumps [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) and [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom). These dependencies needed to be updated together.

Updates `react-dom` from 19.1.1 to 19.2.0
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.0/packages/react-dom)

Updates `@types/react-dom` from 19.1.9 to 19.2.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

---
updated-dependencies:
- dependency-name: react-dom
  dependency-version: 19.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: "@types/react-dom"
  dependency-version: 19.2.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-05 16:14:59 +05:00
dependabot[bot] b87f5ed0c4 chore(deps-dev): bump @next/eslint-plugin-next from 15.5.2 to 15.5.4
Bumps [@next/eslint-plugin-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-plugin-next) from 15.5.2 to 15.5.4.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v15.5.4/packages/eslint-plugin-next)

---
updated-dependencies:
- dependency-name: "@next/eslint-plugin-next"
  dependency-version: 15.5.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-05 13:17:51 +05:00
dependabot[bot] 1315353383 chore(deps): bump next from 15.5.2 to 15.5.4
Bumps [next](https://github.com/vercel/next.js) from 15.5.2 to 15.5.4.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v15.5.2...v15.5.4)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 15.5.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-05 13:14:00 +05:00
dependabot[bot] 3603d1d2ea chore(deps-dev): bump typescript from 5.8.3 to 5.9.3
Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.8.3 to 5.9.3.
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release-publish.yml)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.8.3...v5.9.3)

---
updated-dependencies:
- dependency-name: typescript
  dependency-version: 5.9.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-05 13:10:09 +05:00
dependabot[bot] 5ca5723aef chore(deps-dev): bump @types/node from 24.3.0 to 24.6.1
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.3.0 to 24.6.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.6.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-05 13:04:48 +05:00
dependabot[bot] 89ea9bf534 chore(deps): bump zod from 4.1.5 to 4.1.11
Bumps [zod](https://github.com/colinhacks/zod) from 4.1.5 to 4.1.11.
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](https://github.com/colinhacks/zod/compare/v4.1.5...v4.1.11)

---
updated-dependencies:
- dependency-name: zod
  dependency-version: 4.1.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-05 12:59:28 +05:00
dependabot[bot] 8fd98638de chore(deps-dev): bump sass from 1.91.0 to 1.93.2
Bumps [sass](https://github.com/sass/dart-sass) from 1.91.0 to 1.93.2.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.91.0...1.93.2)

---
updated-dependencies:
- dependency-name: sass
  dependency-version: 1.93.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-05 12:40:44 +05:00
dependabot[bot] 21d1f04c3a chore(deps): bump react-social-icons from 6.24.0 to 6.25.0
Bumps [react-social-icons](https://github.com/couetilc/react-social-icons) from 6.24.0 to 6.25.0.
- [Release notes](https://github.com/couetilc/react-social-icons/releases)
- [Changelog](https://github.com/couetilc/react-social-icons/blob/main/CHANGELOG.md)
- [Commits](https://github.com/couetilc/react-social-icons/compare/v6.24.0...v6.25.0)

---
updated-dependencies:
- dependency-name: react-social-icons
  dependency-version: 6.25.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-05 12:34:08 +05:00
dependabot[bot] 72867edab5 chore(deps): bump sharp from 0.34.3 to 0.34.4
Bumps [sharp](https://github.com/lovell/sharp) from 0.34.3 to 0.34.4.
- [Release notes](https://github.com/lovell/sharp/releases)
- [Commits](https://github.com/lovell/sharp/compare/v0.34.3...v0.34.4)

---
updated-dependencies:
- dependency-name: sharp
  dependency-version: 0.34.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-05 12:33:59 +05:00
dependabot[bot] ff24ae5443 chore(deps-dev): bump eslint-config-next from 15.5.2 to 15.5.4
Bumps [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next) from 15.5.2 to 15.5.4.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v15.5.4/packages/eslint-config-next)

---
updated-dependencies:
- dependency-name: eslint-config-next
  dependency-version: 15.5.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-05 12:33:49 +05:00
dependabot[bot] 835a2dd359 chore(deps-dev): bump typescript-eslint from 8.42.0 to 8.45.0
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.42.0 to 8.45.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.45.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-version: 8.45.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-05 12:33:29 +05:00
dependabot[bot] 9c1ff8eb90 chore(deps): bump @fluentui/react-icons from 2.0.309 to 2.0.311
Bumps [@fluentui/react-icons](https://github.com/microsoft/fluentui-system-icons) from 2.0.309 to 2.0.311.
- [Changelog](https://github.com/microsoft/fluentui-system-icons/blob/main/fluentui-android-system-icons-release.yml)
- [Commits](https://github.com/microsoft/fluentui-system-icons/commits)

---
updated-dependencies:
- dependency-name: "@fluentui/react-icons"
  dependency-version: 2.0.311
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-05 12:33:18 +05:00
dependabot[bot] 4eac9d7b36 chore(deps-dev): bump @types/nodemailer from 7.0.1 to 7.0.2
Bumps [@types/nodemailer](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/nodemailer) from 7.0.1 to 7.0.2.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/nodemailer)

---
updated-dependencies:
- dependency-name: "@types/nodemailer"
  dependency-version: 7.0.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-05 12:33:09 +05:00
dependabot[bot] 39bf1c6d3d chore(deps-dev): bump typescript-eslint from 8.41.0 to 8.42.0
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.41.0 to 8.42.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.42.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-version: 8.42.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-02 20:26:39 +03:00
xfox111 a5999e49f0 Revert "fix(ci): codeql fix"
This reverts commit 4d547111ca.
2025-09-02 20:26:39 +03:00
xfox111 fe611095a1 Revert "fix(ci): codeql fix (attempt 2)"
This reverts commit 3859063795.
2025-09-02 20:26:39 +03:00
xfox111 c81f13880d Revert "fix(ci): codeql fix (attempt 3)"
This reverts commit 4145f207a9.
2025-09-02 20:26:39 +03:00
dependabot[bot] d30785eb03 chore(deps): bump zod from 4.0.14 to 4.1.5
Bumps [zod](https://github.com/colinhacks/zod) from 4.0.14 to 4.1.5.
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](https://github.com/colinhacks/zod/compare/v4.0.14...v4.1.5)

---
updated-dependencies:
- dependency-name: zod
  dependency-version: 4.1.5
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-02 20:26:39 +03:00
dependabot[bot] 3559b717cb chore(deps-dev): bump sass from 1.89.2 to 1.91.0
Bumps [sass](https://github.com/sass/dart-sass) from 1.89.2 to 1.91.0.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.89.2...1.91.0)

---
updated-dependencies:
- dependency-name: sass
  dependency-version: 1.91.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-02 20:26:39 +03:00
dependabot[bot] 7aa509f3bb chore(deps-dev): bump @next/eslint-plugin-next from 15.4.5 to 15.5.2
Bumps [@next/eslint-plugin-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-plugin-next) from 15.4.5 to 15.5.2.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v15.5.2/packages/eslint-plugin-next)

---
updated-dependencies:
- dependency-name: "@next/eslint-plugin-next"
  dependency-version: 15.5.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-02 20:26:39 +03:00
dependabot[bot] 5a7119c755 chore(deps): bump nodemailer and @types/nodemailer
Bumps [nodemailer](https://github.com/nodemailer/nodemailer) and [@types/nodemailer](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/nodemailer). These dependencies needed to be updated together.

Updates `nodemailer` from 7.0.5 to 7.0.6
- [Release notes](https://github.com/nodemailer/nodemailer/releases)
- [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodemailer/nodemailer/compare/v7.0.5...v7.0.6)

Updates `@types/nodemailer` from 6.4.17 to 7.0.1
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/nodemailer)

---
updated-dependencies:
- dependency-name: nodemailer
  dependency-version: 7.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: "@types/nodemailer"
  dependency-version: 7.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-02 20:26:39 +03:00
dependabot[bot] c76579341c chore(deps): bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-02 20:26:39 +03:00
dependabot[bot] fedc5f0f1a chore(deps-dev): bump @types/node from 24.2.0 to 24.3.0
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.2.0 to 24.3.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-02 20:26:39 +03:00
dependabot[bot] a4fbdbc5bd chore(deps-dev): bump @types/react-dom from 19.1.7 to 19.1.9
Bumps [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom) from 19.1.7 to 19.1.9.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

---
updated-dependencies:
- dependency-name: "@types/react-dom"
  dependency-version: 19.1.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-02 20:26:39 +03:00
dependabot[bot] 1c9809abea chore(deps-dev): bump eslint-config-next from 15.4.5 to 15.5.2
Bumps [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next) from 15.4.5 to 15.5.2.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v15.5.2/packages/eslint-config-next)

---
updated-dependencies:
- dependency-name: eslint-config-next
  dependency-version: 15.5.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-02 20:26:39 +03:00
dependabot[bot] 99d0eeb491 chore(deps-dev): bump typescript-eslint from 8.39.0 to 8.41.0
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.39.0 to 8.41.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.41.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-version: 8.41.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-02 20:26:39 +03:00
dependabot[bot] 80892ba176 chore(deps): bump @fluentui/react-icons from 2.0.307 to 2.0.309
Bumps [@fluentui/react-icons](https://github.com/microsoft/fluentui-system-icons) from 2.0.307 to 2.0.309.
- [Changelog](https://github.com/microsoft/fluentui-system-icons/blob/main/fluentui-android-system-icons-release.yml)
- [Commits](https://github.com/microsoft/fluentui-system-icons/commits)

---
updated-dependencies:
- dependency-name: "@fluentui/react-icons"
  dependency-version: 2.0.309
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-02 20:26:39 +03:00
dependabot[bot] 411d58204d chore(deps-dev): bump @types/react from 19.1.9 to 19.1.12
Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 19.1.9 to 19.1.12.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: "@types/react"
  dependency-version: 19.1.12
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-02 20:26:39 +03:00
dependabot[bot] 6f45d3908d chore(deps): bump next from 15.4.5 to 15.5.2
Bumps [next](https://github.com/vercel/next.js) from 15.4.5 to 15.5.2.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v15.4.5...v15.5.2)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 15.5.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-02 20:26:39 +03:00
xfox111 4e8489a719 fix(ci): codeql fix (attempt 3) 2025-09-02 20:26:39 +03:00
xfox111 b7f4894d7e fix(ci): codeql fix (attempt 2) 2025-09-02 20:26:39 +03:00
xfox111 6fdd88ab8d fix(ci): codeql fix 2025-09-02 20:26:39 +03:00
xfox111 f601664382 fix: incorrect cookie value return 2025-09-02 20:26:39 +03:00
xfox111 725b9cebd9 fix(dev): include corepack enable in devcontainer postCreateCommand 2025-09-02 20:26:39 +03:00
xfox111 e16ab1f6f6 feat!: remove Clarity implicit consent option (EU compliance) 2025-09-02 20:26:39 +03:00
xfox111 ac7a3e2213 chore(deps): react, react-dom, @next/eslint-plugin-next dependency update 2025-08-05 13:43:20 +03:00
dependabot[bot] 4a0c497144 chore(deps): bump sharp from 0.34.2 to 0.34.3
Bumps [sharp](https://github.com/lovell/sharp) from 0.34.2 to 0.34.3.
- [Release notes](https://github.com/lovell/sharp/releases)
- [Commits](https://github.com/lovell/sharp/compare/v0.34.2...v0.34.3)

---
updated-dependencies:
- dependency-name: sharp
  dependency-version: 0.34.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-05 13:43:20 +03:00
dependabot[bot] b3e639e718 chore(deps-dev): bump typescript-eslint from 8.35.1 to 8.39.0
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.35.1 to 8.39.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.39.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-version: 8.39.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-05 13:43:20 +03:00
dependabot[bot] d29265687c chore(deps): bump next from 15.3.4 to 15.4.5
Bumps [next](https://github.com/vercel/next.js) from 15.3.4 to 15.4.5.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v15.3.4...v15.4.5)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 15.4.5
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-05 13:43:20 +03:00
dependabot[bot] d90b3a4bc1 chore(deps): bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-05 13:43:20 +03:00
dependabot[bot] af05da5f59 chore(deps-dev): bump eslint-config-next from 15.3.4 to 15.4.5
Bumps [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next) from 15.3.4 to 15.4.5.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v15.4.5/packages/eslint-config-next)

---
updated-dependencies:
- dependency-name: eslint-config-next
  dependency-version: 15.4.5
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-05 13:43:20 +03:00
dependabot[bot] 70e6fb0e45 chore(deps): bump @fluentui/react-icons from 2.0.305 to 2.0.307
Bumps [@fluentui/react-icons](https://github.com/microsoft/fluentui-system-icons) from 2.0.305 to 2.0.307.
- [Changelog](https://github.com/microsoft/fluentui-system-icons/blob/main/fluentui-android-system-icons-release.yml)
- [Commits](https://github.com/microsoft/fluentui-system-icons/commits)

---
updated-dependencies:
- dependency-name: "@fluentui/react-icons"
  dependency-version: 2.0.307
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-05 13:43:20 +03:00
dependabot[bot] a5e30b31c4 chore(deps-dev): bump @types/node from 24.0.8 to 24.2.0
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.0.8 to 24.2.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.2.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-05 13:43:20 +03:00
dependabot[bot] e24927770c chore(deps): bump nodemailer from 7.0.4 to 7.0.5
Bumps [nodemailer](https://github.com/nodemailer/nodemailer) from 7.0.4 to 7.0.5.
- [Release notes](https://github.com/nodemailer/nodemailer/releases)
- [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodemailer/nodemailer/compare/v7.0.4...v7.0.5)

---
updated-dependencies:
- dependency-name: nodemailer
  dependency-version: 7.0.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-05 13:43:20 +03:00
dependabot[bot] 4c7fb5c743 chore(deps): bump zod from 3.25.67 to 4.0.14
Bumps [zod](https://github.com/colinhacks/zod) from 3.25.67 to 4.0.14.
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](https://github.com/colinhacks/zod/compare/v3.25.67...v4.0.14)

---
updated-dependencies:
- dependency-name: zod
  dependency-version: 4.0.14
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-05 13:43:20 +03:00
xfox111 dd8cd590a1 chore(ci): delete base codeql workflow 2025-08-05 13:43:20 +03:00
xfox111 f6cd9490f3 chore(ci): codeql advanced workflow 2025-08-05 13:43:20 +03:00
xfox111 1aaecad076 chore(ci): codeql workflow 2025-08-05 13:43:20 +03:00
xfox111 84dc498bf4 chore: project url update 2025-07-31 12:47:33 +03:00
xfox111 7b442739d6 fix(ci): code scanning alerts 2025-07-23 08:54:25 +00:00
xfox111 fd96fd3343 fix(ci): push on publish 2025-07-23 08:53:16 +00:00
xfox111 03b9201b7f fix(ci): enable corepack and run yarn install 2025-07-23 08:44:21 +00:00
xfox111 223309d9a6 chore(ci): ci workflow update 2025-07-23 08:37:13 +00:00
xfox111 bcb22a7740 chore(dev): migration to Yarn berry 2025-07-23 08:36:32 +00:00
xfox111 536c4559cb chore(dev): devcontainer config update 2025-07-23 08:14:45 +00:00
xfox111 40e188991f chore: docker run vscode task 2025-07-22 14:52:55 +00:00
xfox111 3dc42cbf8d chore: personal info update 2025-07-22 14:52:42 +00:00
xfox111 2e3bf0b63b feat: use JSX instead of strings for bio 2025-07-22 14:52:11 +00:00
xfox111 6d4c931091 chore(ui): pre-wrap for alert message 2025-07-22 14:50:28 +00:00
xfox111 1992ee8f29 fix: alert icon shrinking if there's a lot of text 2025-07-22 14:49:59 +00:00
xfox111 d0bd5db044 chore: replace priority attribute with loading="eager" for images 2025-07-22 14:47:49 +00:00
dependabot[bot] 1b95c8546e chore(deps-dev): bump @types/react from 19.1.6 to 19.1.8
Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 19.1.6 to 19.1.8.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: "@types/react"
  dependency-version: 19.1.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-01 12:31:21 +03:00
xfox111 08706f8c4e fix(ci): CI not triggering on 'next' branch PRs 2025-07-01 12:31:21 +03:00
dependabot[bot] c6f026aef5 chore(deps-dev): bump eslint-config-next from 15.3.3 to 15.3.4
Bumps [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next) from 15.3.3 to 15.3.4.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v15.3.4/packages/eslint-config-next)

---
updated-dependencies:
- dependency-name: eslint-config-next
  dependency-version: 15.3.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-01 12:31:21 +03:00
dependabot[bot] ef3e81c308 chore(deps): bump @fluentui/react-icons from 2.0.302 to 2.0.305
Bumps [@fluentui/react-icons](https://github.com/microsoft/fluentui-system-icons) from 2.0.302 to 2.0.305.
- [Changelog](https://github.com/microsoft/fluentui-system-icons/blob/main/fluentui-android-system-icons-release.yml)
- [Commits](https://github.com/microsoft/fluentui-system-icons/commits)

---
updated-dependencies:
- dependency-name: "@fluentui/react-icons"
  dependency-version: 2.0.305
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-01 12:31:21 +03:00
dependabot[bot] e2cf91f45d chore(deps): bump nodemailer from 7.0.3 to 7.0.4
Bumps [nodemailer](https://github.com/nodemailer/nodemailer) from 7.0.3 to 7.0.4.
- [Release notes](https://github.com/nodemailer/nodemailer/releases)
- [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodemailer/nodemailer/compare/v7.0.3...v7.0.4)

---
updated-dependencies:
- dependency-name: nodemailer
  dependency-version: 7.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-01 12:31:21 +03:00
dependabot[bot] 13bd78e176 chore(deps-dev): bump @next/eslint-plugin-next from 15.3.3 to 15.3.4
Bumps [@next/eslint-plugin-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-plugin-next) from 15.3.3 to 15.3.4.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v15.3.4/packages/eslint-plugin-next)

---
updated-dependencies:
- dependency-name: "@next/eslint-plugin-next"
  dependency-version: 15.3.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-01 12:31:21 +03:00
dependabot[bot] ce217459ef chore(deps-dev): bump @types/react-dom from 19.1.5 to 19.1.6
Bumps [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom) from 19.1.5 to 19.1.6.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

---
updated-dependencies:
- dependency-name: "@types/react-dom"
  dependency-version: 19.1.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-01 12:31:21 +03:00
dependabot[bot] ad88ed9915 chore(deps-dev): bump sass from 1.89.1 to 1.89.2
Bumps [sass](https://github.com/sass/dart-sass) from 1.89.1 to 1.89.2.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.89.1...1.89.2)

---
updated-dependencies:
- dependency-name: sass
  dependency-version: 1.89.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-01 12:31:21 +03:00
dependabot[bot] bc61f061fd chore(deps-dev): bump @types/node from 22.15.29 to 24.0.8
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.15.29 to 24.0.8.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.0.8
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-01 12:31:21 +03:00
dependabot[bot] e0a5bf4ea4 chore(deps-dev): bump typescript-eslint from 8.33.1 to 8.35.1
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.33.1 to 8.35.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.35.1/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-version: 8.35.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-01 12:31:21 +03:00
dependabot[bot] 95c1202844 chore(deps): bump zod from 3.25.49 to 3.25.67
Bumps [zod](https://github.com/colinhacks/zod) from 3.25.49 to 3.25.67.
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](https://github.com/colinhacks/zod/compare/v3.25.49...v3.25.67)

---
updated-dependencies:
- dependency-name: zod
  dependency-version: 3.25.67
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-01 12:31:21 +03:00
dependabot[bot] b12c4e95db chore(deps): bump next from 15.3.3 to 15.3.4
Bumps [next](https://github.com/vercel/next.js) from 15.3.3 to 15.3.4.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v15.3.3...v15.3.4)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 15.3.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-01 12:31:21 +03:00
xfox111 3658a90424 feat: exclude *.module.scss from github stats 2025-06-03 18:36:07 +03:00
xfox111 eb879594a9 chore: dependabot reviewers deprecation 2025-06-03 18:20:52 +03:00
dependabot[bot] 1109a66a0d chore(deps-dev): bump typescript-eslint from 8.33.0 to 8.33.1
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.33.0 to 8.33.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.33.1/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-version: 8.33.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-03 18:13:54 +03:00
dependabot[bot] f3d9becc80 chore(deps-dev): bump @types/node from 22.15.3 to 22.15.29
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.15.3 to 22.15.29.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 22.15.29
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-03 18:13:54 +03:00
dependabot[bot] aea740b21e chore(deps): bump next from 15.3.1 to 15.3.3
Bumps [next](https://github.com/vercel/next.js) from 15.3.1 to 15.3.3.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v15.3.1...v15.3.3)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 15.3.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-03 18:13:54 +03:00
dependabot[bot] 3ecdb75032 chore(deps-dev): bump eslint-config-next from 15.3.1 to 15.3.3
Bumps [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next) from 15.3.1 to 15.3.3.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v15.3.3/packages/eslint-config-next)

---
updated-dependencies:
- dependency-name: eslint-config-next
  dependency-version: 15.3.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-03 18:13:54 +03:00
dependabot[bot] cec7852c8f chore(deps-dev): bump @types/react from 19.1.2 to 19.1.6
Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 19.1.2 to 19.1.6.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: "@types/react"
  dependency-version: 19.1.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-03 18:13:54 +03:00
dependabot[bot] d4336af44b chore(deps): bump zod from 3.24.3 to 3.25.46
Bumps [zod](https://github.com/colinhacks/zod) from 3.24.3 to 3.25.46.
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](https://github.com/colinhacks/zod/compare/v3.24.3...v3.25.46)

---
updated-dependencies:
- dependency-name: zod
  dependency-version: 3.25.46
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-03 18:13:54 +03:00
dependabot[bot] 510e6220e2 chore(deps): bump node from 23-alpine to 24-alpine
Bumps node from 23-alpine to 24-alpine.

---
updated-dependencies:
- dependency-name: node
  dependency-version: 24-alpine
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-03 18:13:54 +03:00
dependabot[bot] 4bdb31c884 chore(deps-dev): bump @next/eslint-plugin-next from 15.3.1 to 15.3.3
Bumps [@next/eslint-plugin-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-plugin-next) from 15.3.1 to 15.3.3.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v15.3.3/packages/eslint-plugin-next)

---
updated-dependencies:
- dependency-name: "@next/eslint-plugin-next"
  dependency-version: 15.3.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-03 18:13:54 +03:00
dependabot[bot] 6e2986f4d6 chore(deps-dev): bump @types/react-dom from 19.1.3 to 19.1.5
Bumps [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom) from 19.1.3 to 19.1.5.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

---
updated-dependencies:
- dependency-name: "@types/react-dom"
  dependency-version: 19.1.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-03 18:13:54 +03:00
dependabot[bot] d1707fc53e chore(deps): bump @fluentui/react-icons from 2.0.298 to 2.0.302
Bumps [@fluentui/react-icons](https://github.com/microsoft/fluentui-system-icons) from 2.0.298 to 2.0.302.
- [Changelog](https://github.com/microsoft/fluentui-system-icons/blob/main/fluentui-android-system-icons-release.yml)
- [Commits](https://github.com/microsoft/fluentui-system-icons/commits)

---
updated-dependencies:
- dependency-name: "@fluentui/react-icons"
  dependency-version: 2.0.302
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-03 18:13:54 +03:00
dependabot[bot] 52c3caa395 chore(deps): bump sharp from 0.34.1 to 0.34.2
Bumps [sharp](https://github.com/lovell/sharp) from 0.34.1 to 0.34.2.
- [Release notes](https://github.com/lovell/sharp/releases)
- [Commits](https://github.com/lovell/sharp/compare/v0.34.1...v0.34.2)

---
updated-dependencies:
- dependency-name: sharp
  dependency-version: 0.34.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-03 18:13:54 +03:00
dependabot[bot] 492659043a chore(deps-dev): bump sass from 1.87.0 to 1.89.1
Bumps [sass](https://github.com/sass/dart-sass) from 1.87.0 to 1.89.1.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.87.0...1.89.1)

---
updated-dependencies:
- dependency-name: sass
  dependency-version: 1.89.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-03 18:13:54 +03:00
dependabot[bot] 5f84634687 chore(deps-dev): bump typescript-eslint from 8.31.1 to 8.33.0
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.31.1 to 8.33.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.33.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-version: 8.33.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-03 18:13:54 +03:00
dependabot[bot] db3b76c1eb chore(deps): bump nodemailer from 7.0.0 to 7.0.3
Bumps [nodemailer](https://github.com/nodemailer/nodemailer) from 7.0.0 to 7.0.3.
- [Release notes](https://github.com/nodemailer/nodemailer/releases)
- [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodemailer/nodemailer/compare/v7.0.0...v7.0.3)

---
updated-dependencies:
- dependency-name: nodemailer
  dependency-version: 7.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-03 18:13:54 +03:00
xfox111 20a5fef75c fix: cloudflare script refuses to load because of cors 2025-05-14 13:28:00 +00:00
xfox111 9a4d6966d0 feat: ATS-compliant resume download links 2025-05-11 17:21:53 +00:00
71 changed files with 15531 additions and 4731 deletions
+10 -4
View File
@@ -2,16 +2,22 @@
// README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node // README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node
{ {
"name": "my-website", "name": "my-website",
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-20-bullseye", "image": "mcr.microsoft.com/devcontainers/base:bookworm",
"features": { "features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": { "ghcr.io/devcontainers/features/docker-in-docker:3": {
"installDockerBuildx": true,
"version": "latest", "version": "latest",
"dockerDashComposeVersion": "none" "dockerDashComposeVersion": "v2"
},
"ghcr.io/devcontainers/features/node:2": {
"version": "latest",
"pnpmVersion": "none",
"nvmVersion": "latest"
} }
}, },
"postCreateCommand": "yarn install", "postCreateCommand": "npm install",
// Configure tool-specific properties. // Configure tool-specific properties.
"customizations": { "customizations": {
+2 -2
View File
@@ -11,10 +11,10 @@ SMTP_TO_EMAIL=email # Email to which emails will be sent
DOMAIN_NAME=example.com # Your domain name DOMAIN_NAME=example.com # Your domain name
RESUME_URL=URL # Location of the resume PDF RESUME_URL=URL # Location of the resume PDF
RESUME_HAS_REFS=false # Appends last page of the resume to a result PDF file ATS_RESUME_URL=URL # Location of the ATS-compatible resume PDF (optional, remove to disable)
RESUME_HAS_REFS=false # Appends last page of the resume to a result PDF file (only appies to non-ATS version)
ALERT_TEXT_URL=URL # URL of a txt file with urgent message to be displayed (see app/_components/AlertMessage.tsx) ALERT_TEXT_URL=URL # URL of a txt file with urgent message to be displayed (see app/_components/AlertMessage.tsx)
CLARITY_ID=string # Clarity Analytics ID (optional, remove to disable) CLARITY_ID=string # Clarity Analytics ID (optional, remove to disable)
CLARITY_CONSENT=1 # 1 if you need to request explicit consent from user, 0 if not (requires CLARITY_ID)
CF_SITEKEY=3x00000000000000000000FF # Cloudflare Turnstile captcha sitekey for contact form (optional, remove to siable) CF_SITEKEY=3x00000000000000000000FF # Cloudflare Turnstile captcha sitekey for contact form (optional, remove to siable)
CF_SECRET=1x0000000000000000000000000000000AA # Secret for token validation (requries CF_SITEKEY) CF_SECRET=1x0000000000000000000000000000000AA # Secret for token validation (requries CF_SITEKEY)
+1
View File
@@ -0,0 +1 @@
*.module.scss linguist-detectable=false
+1
View File
@@ -0,0 +1 @@
* @XFox111
+24 -20
View File
@@ -8,48 +8,52 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/" directory: "/"
target-branch: "next" target-branch: "main"
assignees: assignees:
- "xfox111" - "XFox111"
reviewers:
- "xfox111"
schedule: schedule:
interval: monthly interval: monthly
rebase-strategy: disabled rebase-strategy: disabled
open-pull-requests-limit: 20 groups:
all:
patterns:
- "*"
- package-ecosystem: "github-actions" - package-ecosystem: "github-actions"
directory: "/" directory: "/"
target-branch: "next" target-branch: "main"
assignees: assignees:
- "xfox111" - "XFox111"
reviewers:
- "xfox111"
schedule: schedule:
interval: monthly interval: monthly
rebase-strategy: disabled rebase-strategy: disabled
open-pull-requests-limit: 20 groups:
all:
patterns:
- "*"
- package-ecosystem: "devcontainers" - package-ecosystem: "devcontainers"
directory: "/" directory: "/"
target-branch: "next" target-branch: "main"
assignees: assignees:
- "xfox111" - "XFox111"
reviewers:
- "xfox111"
schedule: schedule:
interval: monthly interval: monthly
rebase-strategy: disabled rebase-strategy: disabled
open-pull-requests-limit: 20 groups:
all:
patterns:
- "*"
- package-ecosystem: "docker" - package-ecosystem: "docker"
directory: "/" directory: "/"
target-branch: "next" target-branch: "main"
assignees: assignees:
- "xfox111" - "XFox111"
reviewers:
- "xfox111"
schedule: schedule:
interval: monthly interval: monthly
rebase-strategy: disabled rebase-strategy: disabled
open-pull-requests-limit: 20 groups:
all:
patterns:
- "*"
+52
View File
@@ -0,0 +1,52 @@
name: Audit pipeline
on:
push:
paths-ignore:
- '.devcontainer/*'
- '.github/*'
- '!.github/workflows/audit.yml'
- '.vscode/*'
- '**.md'
- '.env*'
- 'LICENSE'
- 'COPYING'
- '.git*'
pull_request:
paths-ignore:
- '.devcontainer/*'
- '.github/*'
- '!.github/workflows/audit.yml'
- '.vscode/*'
- '**.md'
- '.env*'
- 'LICENSE'
- 'COPYING'
- '.git*'
workflow_dispatch:
jobs:
audit:
runs-on: ubuntu-latest
container: node:24
permissions:
contents: read
steps:
- uses: actions/checkout@v6
- run: npm install
- run: npm audit
build:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v6
- uses: docker/build-push-action@v7
with:
context: .
tags: "my-website:ci"
+10 -37
View File
@@ -1,35 +1,10 @@
name: "CI pipeline" name: "CI pipeline"
on: on:
push: release:
branches: [ "main" ] types:
paths-ignore: - published
- '.devcontainer/*'
- '.github/*'
- '!.github/workflows/ci.yml'
- '.vscode/*'
- '**.md'
- '.env*'
- 'LICENSE'
- 'COPYING'
pull_request:
branches: [ "main", "deps" ]
paths-ignore:
- '.devcontainer/*'
- '.github/*'
- '!.github/workflows/ci.yml'
- '.vscode/*'
- '**.md'
- '.env*'
- 'LICENSE'
- 'COPYING'
workflow_dispatch: workflow_dispatch:
inputs:
push:
type: boolean
required: false
default: false
description: "Push to Docker Hub"
jobs: jobs:
build: build:
@@ -39,9 +14,9 @@ jobs:
packages: write packages: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- uses: docker/metadata-action@v5 - uses: docker/metadata-action@v6
id: meta id: meta
with: with:
images: | images: |
@@ -49,25 +24,23 @@ jobs:
ghcr.io/${{ github.repository }} ghcr.io/${{ github.repository }}
tags: | tags: |
latest latest
${{ github.sha }} ${{ github.ref_name }}
- name: "Login to Docker Hub" - name: "Login to Docker Hub"
if: github.event_name != 'pull_request' || github.event.inputs.push == 'true' uses: docker/login-action@v4
uses: docker/login-action@v3
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: "Login to GitHub Container Registry" - name: "Login to GitHub Container Registry"
if: github.event_name != 'pull_request' || github.event.inputs.push == 'true' uses: docker/login-action@v4
uses: docker/login-action@v3
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.repository_owner }} username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v6 - uses: docker/build-push-action@v7
with: with:
context: . context: .
push: ${{ github.event_name != 'pull_request' || github.event.inputs.push == 'true' }} push: true
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
+111
View File
@@ -0,0 +1,111 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL Advanced"
on:
push:
branches: [ "main", "next" ]
paths-ignore:
- '**.md'
- 'LICENSE'
- '**/ci.yml'
- '.vscode/*'
pull_request:
# The branches below must be a subset of the branches above
branches: [ "main", "next" ]
paths-ignore:
- '**.md'
- 'LICENSE'
- '**/ci.yml'
- '.vscode/*'
schedule:
- cron: '23 22 * * 1'
jobs:
analyze:
name: Analyze (${{ matrix.language }})
# Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners (GitHub.com only)
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
permissions:
# required for all workflows
security-events: write
# required to fetch internal or private CodeQL packs
packages: read
# only required for workflows in private repositories
actions: read
contents: read
strategy:
fail-fast: false
matrix:
include:
- language: actions
build-mode: none
- language: javascript-typescript
build-mode: none
# CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift'
# Use `c-cpp` to analyze code written in C, C++ or both
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
steps:
- name: Checkout repository
uses: actions/checkout@v6
# Add any setup steps before running the `github/codeql-action/init` action.
# This includes steps like installing compilers or runtimes (`actions/setup-node`
# or others). This is typically only required for manual builds.
# - name: Setup runtime (example)
# uses: actions/setup-example@v1
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# If the analyze step fails for one of the languages you are analyzing with
# "We were unable to automatically build your code", modify the matrix above
# to set the build mode to "manual" for that language. Then modify this step
# to build your code.
# ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
- if: matrix.build-mode == 'manual'
shell: bash
run: |
echo 'If you are using a "manual" build mode for one or more of the' \
'languages you are analyzing, replace this with the commands to build' \
'your code, for example:'
echo ' make bootstrap'
echo ' make release'
exit 1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
with:
category: "/language:${{matrix.language}}"
+4
View File
@@ -34,3 +34,7 @@ yarn-error.log*
# typescript # typescript
*.tsbuildinfo *.tsbuildinfo
next-env.d.ts next-env.d.ts
# yarn
.pnp.*
.yarn
+21 -4
View File
@@ -9,7 +9,7 @@
"isDefault": true "isDefault": true
}, },
"problemMatcher": [], "problemMatcher": [],
"label": "yarn: build", "label": "npm: build",
"detail": "Build project" "detail": "Build project"
}, },
{ {
@@ -17,7 +17,7 @@
"script": "install", "script": "install",
"group": "build", "group": "build",
"problemMatcher": [], "problemMatcher": [],
"label": "yarn: install", "label": "npm: install",
"detail": "Restore dependencies" "detail": "Restore dependencies"
}, },
{ {
@@ -28,7 +28,7 @@
"isDefault": true "isDefault": true
}, },
"problemMatcher": [], "problemMatcher": [],
"label": "yarn: dev", "label": "npm: dev",
"detail": "Start development server" "detail": "Start development server"
}, },
{ {
@@ -36,7 +36,7 @@
"script": "lint", "script": "lint",
"group": "test", "group": "test",
"problemMatcher": [], "problemMatcher": [],
"label": "yarn: lint", "label": "npm: lint",
"detail": "Run ESLint" "detail": "Run ESLint"
}, },
{ {
@@ -56,5 +56,22 @@
"label": "docker: build", "label": "docker: build",
"detail": "Build a Docker image" "detail": "Build a Docker image"
}, },
{
"type": "shell",
"command": "docker",
"args": [
"run",
"--rm",
"--env-file",
".env.local",
"-p",
"3000:3000",
"my-website"
],
"group": "test",
"problemMatcher": [],
"label": "docker: run",
"detail": "Run the Docker container"
}
] ]
} }
+5 -5
View File
@@ -3,18 +3,18 @@
Following files and directories are excempt from MIT license coverage Following files and directories are excempt from MIT license coverage
and are subjects to general copyright law: and are subjects to general copyright law:
- /app/_assets - /app/_assets/
- /app/_data - /app/_data/
- /app/apple-icon.png - /app/apple-icon.png
- /app/favicon.ico - /app/favicon.ico
- /app/icon.svg - /app/icon.svg
- /app/opengraph-image.alt.txt - /app/opengraph-image.alt.txt
- /app/opengraph-image.png - /app/opengraph-image.png
You must obtain written permission from the author to use any You must obtain written a permission from the author to use any
copyrighted material. copyrighted materials.
You may use copyrighted material without excplicit permission You may use copyrighted materials without excplicit permission
in following cases: in following cases:
- Educational purposes. - Educational purposes.
+5 -5
View File
@@ -1,4 +1,4 @@
FROM node:23-alpine AS base FROM node:26-alpine AS base
# Install dependencies only when needed # Install dependencies only when needed
FROM base AS deps FROM base AS deps
@@ -7,8 +7,8 @@ RUN apk add --no-cache libc6-compat
WORKDIR /app WORKDIR /app
# Install dependencies # Install dependencies
COPY package.json yarn.lock ./ COPY package.json package-lock.json ./
RUN yarn --frozen-lockfile RUN npm install
# Rebuild the source code only when needed # Rebuild the source code only when needed
FROM base AS builder FROM base AS builder
@@ -21,8 +21,8 @@ COPY . .
# Uncomment the following line in case you want to disable telemetry during the build. # Uncomment the following line in case you want to disable telemetry during the build.
# ENV NEXT_TELEMETRY_DISABLED 1 # ENV NEXT_TELEMETRY_DISABLED 1
RUN yarn lint RUN npm run lint
RUN yarn build RUN npm run build
# Production image, copy all the files and run next # Production image, copy all the files and run next
FROM base AS runner FROM base AS runner
+4 -5
View File
@@ -33,7 +33,6 @@ This repository contains the source code for my personal website, built using Ne
For development you can use [Dev Containers](https://devcontainers.io/) or [GitHub Codespaces](https://github.com/features/codespaces). Otherwise you will need to install following tools: For development you can use [Dev Containers](https://devcontainers.io/) or [GitHub Codespaces](https://github.com/features/codespaces). Otherwise you will need to install following tools:
- [Node.js](https://nodejs.org/en/) - [Node.js](https://nodejs.org/en/)
- [Yarn](https://yarnpkg.com/)
- [Docker](https://www.docker.com/) - [Docker](https://www.docker.com/)
@@ -41,10 +40,10 @@ For development you can use [Dev Containers](https://devcontainers.io/) or [GitH
Here're some commonly used commands: Here're some commonly used commands:
```bash ```bash
yarn install # Install dependencies npm install # Install dependencies
yarn dev # Start the development server at http://localhost:3000 npm run dev # Start the development server at http://localhost:3000
yarn lint # Lint the project with ESLint npm run lint # Lint the project with ESLint
yarn build # Build the project for production npm run build # Build the project for production
``` ```
To build a Docker image, run: To build a Docker image, run:
@@ -3,13 +3,13 @@
<defs> <defs>
<style> <style>
.cls-1 { .cls-1 {
fill: #e0e0e0; fill: #f5f5f5;
stroke-width: 0px; stroke-width: 0px;
} }
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
.cls-1 { .cls-1 {
fill: #525252; fill: #3d3d3d;
} }
} }
</style> </style>

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

+2 -2
View File
@@ -3,14 +3,14 @@
<defs> <defs>
<style> <style>
.cls-1 { .cls-1 {
fill: #e0e0e0; fill: #f5f5f5;
stroke-width: 0px; stroke-width: 0px;
} }
@media (prefers-color-scheme: dark) @media (prefers-color-scheme: dark)
{ {
.cls-1 { .cls-1 {
fill: #525252; fill: #3d3d3d;
} }
} }
</style> </style>

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

+8
View File
@@ -6,6 +6,7 @@ import designSkills from "./skills/design-skills.svg";
import devopsSkills from "./skills/devops-skills.svg"; import devopsSkills from "./skills/devops-skills.svg";
import dotnetSkills from "./skills/dotnet-skills.svg"; import dotnetSkills from "./skills/dotnet-skills.svg";
import nodejsSkills from "./skills/nodejs-skills.svg"; import nodejsSkills from "./skills/nodejs-skills.svg";
import securitySkills from "./skills/security-skills.svg";
export const admin: ImageExport = export const admin: ImageExport =
{ {
@@ -49,6 +50,12 @@ export const nodejs: ImageExport =
alt: "Cartoon fox lifted by balloons representing TypeScript, JavaScript, and React, with a laptop below." alt: "Cartoon fox lifted by balloons representing TypeScript, JavaScript, and React, with a laptop below."
}; };
export const security: ImageExport =
{
src: securitySkills,
alt: ""
};
const skills = const skills =
{ {
nodejs, nodejs,
@@ -58,6 +65,7 @@ const skills =
design, design,
devops, devops,
admin, admin,
security,
}; };
export default skills; export default skills;
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<svg id="admin-skills" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600"> <svg id="admin-skills" xmlns="http://www.w3.org/2000/svg" viewBox="81 86 477 457">
<defs> <defs>
<style> <style>
.cls-1 { .cls-1 {

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<svg id="architecture-skills" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600"> <svg id="architecture-skills" xmlns="http://www.w3.org/2000/svg" viewBox="70 170 500 396">
<defs> <defs>
<style> <style>
.cls-1 { .cls-1 {

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<svg id="databases-skills" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" <svg id="databases-skills" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 600 600"> viewBox="24 72 577 520">
<defs> <defs>
<style> <style>
.cls-1, .cls-1,

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<svg id="design-skills" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600"> <svg id="design-skills" xmlns="http://www.w3.org/2000/svg" viewBox="0 107 600 491">
<defs> <defs>
<style> <style>
.cls-1 { .cls-1 {

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 61 KiB

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 600 600"> <!-- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 206 600 254"> -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="4 206 585 254">
<defs> <defs>
<style> <style>
.cls-1 { .cls-1 {

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<svg id="nodejs-skills" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 600"> <!-- <svg id="nodejs-skills" xmlns="http://www.w3.org/2000/svg" viewBox="0 55 400 483"> -->
<svg id="nodejs-skills" xmlns="http://www.w3.org/2000/svg" viewBox="12 55 331 483">
<defs> <defs>
<style> <style>
.cls-1 { .cls-1 {

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

@@ -0,0 +1,343 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="100%" height="100%" viewBox="0 0 2500 1179" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/"
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1,0,0,1,-40636,0)">
<g id="security-skills" transform="matrix(1,0,0,0.471372,-0.86131,0)">
<rect x="40636.9" y="0" width="2500" height="2500" style="fill:none;" />
<g transform="matrix(-1,0,0,2.12147,43146.9,-3685.62)">
<g transform="matrix(4.16667,0,0,4.16667,760.506,1748.2)">
<path
d="M119.739,185.823C113.148,185.823 105.712,183.233 97.496,178.059L104.586,166.802C110.497,170.522 118.66,174.362 123.977,171.515C130.231,168.17 132.735,156.106 132.982,146.797L146.282,147.149C146.063,155.545 144.058,175.868 130.254,183.252C127.037,184.963 123.526,185.823 119.739,185.823Z"
style="fill:rgb(143,125,221);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(4.16667,0,0,4.16667,760.506,1748.2)">
<path
d="M162.704,180.173C166.116,168.897 171.176,145.999 165.137,126.773L151.756,133.635C157.239,151.069 152.122,171.363 149.295,180.216C149.062,180.943 155.69,181.641 162.704,180.173Z"
style="fill:url(#_Linear1);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(4.16667,0,0,4.16667,760.506,1748.2)">
<path
d="M162.704,180.173C166.116,168.897 171.176,145.999 165.137,126.773L151.756,133.635C157.239,151.069 152.122,171.363 149.295,180.216C149.062,180.943 155.69,181.641 162.704,180.173Z"
style="fill:rgb(143,125,221);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(4.16667,0,0,4.16667,760.506,1748.2)">
<path
d="M149.337,180.088L159.881,180.088C160.067,183.49 156.185,198.244 180.053,223.637L176.793,236.477L132.155,236.448C130.544,236.448 129.679,235.198 130.254,233.587L149.337,180.088Z"
style="fill:rgb(82,44,213);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(4.16667,0,0,4.16667,760.506,1748.2)">
<path
d="M183.683,221.822C185.26,223.1 184.41,225.624 183.74,227.52L181.331,234.272C180.898,235.479 179.558,236.467 178.347,236.467L174.512,236.467C173.144,236.467 172.426,235.355 172.915,233.987L175.101,226.987C176.009,224.445 176.232,222.834 174.16,221.105C161.896,210.855 149.632,196.947 154.246,180.088L162.723,180.088C160.932,188.726 162.97,205.006 183.683,221.822Z"
style="fill:rgb(143,125,221);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(4.16667,0,0,4.16667,760.506,1748.2)">
<path
d="M184.5,223.257L175.652,223.257C175.919,224.322 175.638,225.491 175.106,226.987L172.92,233.987C172.431,235.355 173.143,236.467 174.517,236.467L178.351,236.467C179.563,236.467 180.903,235.479 181.335,234.272L183.745,227.52C184.21,226.189 184.752,224.559 184.5,223.257Z"
style="fill:rgb(143,125,221);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(1.83297,3.74184,-3.74184,1.83297,1585.03,1262.23)">
<path
d="M189.176,105.177L196.156,94.984C205.593,101.442 214.365,103.252 220.856,100.078C228.563,96.31 233.338,85.571 234.303,69.838L246.634,70.594C245.032,96.695 234.683,107.073 226.277,111.178C215.619,116.386 202.443,114.257 189.176,105.177Z"
style="fill:rgb(143,125,221);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(3.37072,2.44936,-2.44936,3.37072,1126.86,1473.36)">
<path
d="M231.167,46.925L230.364,64.169C230.221,67.244 232.597,69.848 235.667,69.99C238.741,70.133 241.345,67.757 241.488,64.687L242.291,47.443C242.433,44.369 240.057,41.765 236.988,41.622C233.913,41.475 231.309,43.851 231.167,46.925Z"
style="fill:rgb(143,125,221);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(3.37072,2.44936,-2.44936,3.37072,1126.86,1473.36)">
<path
d="M245.874,66.136L256.076,53.782C258.047,51.401 257.72,47.871 255.339,45.899C252.958,43.927 249.428,44.255 247.456,46.635L237.064,59.218L245.874,66.136Z"
style="fill:rgb(143,125,221);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(3.37072,2.44936,-2.44936,3.37072,1126.86,1473.36)">
<path
d="M251.252,70.365L263.978,60.658C266.43,58.771 266.89,55.255 265.004,52.803C263.118,50.351 259.601,49.89 257.149,51.777L247.665,58.966L251.252,70.365Z"
style="fill:rgb(143,125,221);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(3.37072,2.44936,-2.44936,3.37072,1126.86,1473.36)">
<path
d="M248.249,75.878L259.563,73.293C262.571,72.585 264.439,69.567 263.726,66.555C263.018,63.542 260,61.679 256.988,62.392L245.384,65.043L248.249,75.878Z"
style="fill:rgb(143,125,221);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(3.37072,2.44936,-2.44936,3.37072,1126.86,1473.36)">
<path
d="M242.224,78.016C248.698,78.016 253.947,72.767 253.947,66.293C253.947,59.819 248.698,54.571 242.224,54.571C235.75,54.571 230.502,59.819 230.502,66.293C230.502,72.767 235.75,78.016 242.224,78.016Z"
style="fill:rgb(82,44,213);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(4.16667,0,0,4.16667,760.506,1748.2)">
<path
d="M200.015,118.572C206.895,103.789 206.553,90.921 206.553,90.921L210.207,91.591L210.312,91.539C210.288,62.097 189.285,35.949 159.288,30.465C125.493,24.278 93.086,46.664 86.909,80.463C80.727,114.257 103.113,146.664 136.907,152.841C163.574,157.716 189.371,144.806 202.105,122.539C202.533,121.575 202.847,119.755 200.015,118.572Z"
style="fill:rgb(143,125,221);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(4.16667,0,0,4.16667,760.506,1748.2)">
<path
d="M200.015,118.572C206.814,103.97 206.562,91.245 206.553,90.936L143.07,79.327C143.07,79.327 139.145,78.192 138.475,81.841C137.805,85.495 136.071,95.844 133.98,107.263C133.552,109.61 135.268,111.092 136.779,111.373C136.783,111.368 198.884,120.463 200.015,118.572Z"
style="fill:url(#_Radial2);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(4.16667,0,0,4.16667,760.506,1748.2)">
<path
d="M162.409,111.991C162.409,111.991 173.585,106.046 175.752,104.968C177.919,103.889 179.601,104.112 181.069,105.942C182.542,107.771 190.92,117.208 190.92,117.208L162.409,111.991Z"
style="fill:rgb(160,139,232);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(4.16667,0,0,4.16667,760.506,1748.2)">
<path
d="M201.73,123.2C201.73,123.2 204.02,120.249 200.015,118.572C200.024,118.557 137.605,107.106 137.605,107.106C136.151,106.84 134.441,105.633 134.536,104.193C134.355,105.2 134.17,106.227 133.98,107.253C133.59,109.382 134.968,110.798 136.356,111.249C136.493,111.292 136.636,111.335 136.779,111.359L141.046,112.138L201.73,123.2Z"
style="fill:rgb(82,44,213);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(4.16667,0,0,4.16667,760.506,1748.2)">
<path
d="M195.192,132.29L89.675,112.993C91.309,117.45 93.443,121.689 96.018,125.642L184.781,141.874C188.591,139.09 192.084,135.877 195.192,132.29Z"
style="fill:rgb(216,207,247);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(4.16667,0,0,4.16667,760.506,1748.2)">
<path
d="M32.041,88.759L39.468,98.634C49.812,90.855 60.128,86.835 70.131,86.697C78.931,86.574 87.727,89.439 96.275,95.222L103.193,84.987C87.304,74.243 62.062,66.179 32.041,88.759Z"
style="fill:rgb(143,125,221);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(4.16667,0,0,4.16667,760.506,1748.2)">
<path
d="M29.779,83.765L18.503,86.521C15.505,87.277 13.685,90.318 14.441,93.321C15.196,96.319 18.237,98.139 21.24,97.384L32.801,94.561L29.779,83.765Z"
style="fill:rgb(143,125,221);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(4.16667,0,0,4.16667,760.506,1748.2)">
<path
d="M27.788,89.367L17.268,94.266C14.474,95.592 13.281,98.933 14.607,101.727C15.933,104.521 19.273,105.713 22.067,104.388L32.858,99.365L27.788,89.367Z"
style="fill:rgb(143,125,221);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(4.16667,0,0,4.16667,760.506,1748.2)">
<path
d="M32.065,100.121L29.214,111.373C28.477,114.376 30.311,117.407 33.314,118.149C36.317,118.885 39.349,117.051 40.09,114.048L43.013,102.511L32.065,100.121Z"
style="fill:rgb(143,125,221);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(4.16667,0,0,4.16667,760.506,1748.2)">
<path
d="M31.186,96.685L20.794,101.85C18.033,103.247 16.926,106.616 18.323,109.377C19.72,112.138 23.089,113.245 25.849,111.848L42.318,103.662L31.186,96.685Z"
style="fill:rgb(143,125,221);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(4.16667,0,0,4.16667,760.506,1748.2)">
<path
d="M35.757,105.419C42.231,105.419 47.479,100.171 47.479,93.696C47.479,87.222 42.231,81.974 35.757,81.974C29.283,81.974 24.034,87.222 24.034,93.696C24.034,100.171 29.283,105.419 35.757,105.419Z"
style="fill:rgb(82,44,213);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(4.16667,0,0,4.16667,760.506,1748.2)">
<path
d="M100.2,101.37C106.509,101.37 111.623,96.256 111.623,89.947C111.623,83.638 106.509,78.524 100.2,78.524C93.891,78.524 88.777,83.638 88.777,89.947C88.777,96.256 93.891,101.37 100.2,101.37Z"
style="fill:rgb(82,44,213);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(4.16667,0,0,4.16667,760.506,1748.2)">
<path
d="M109.675,169.724L106.31,179.717C103.027,178.809 90.283,170.413 58.598,184.929L47.475,177.74L61.754,135.445C62.267,133.92 63.725,133.497 65.07,134.556L109.675,169.724Z"
style="fill:rgb(82,44,213);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(4.16667,0,0,4.16667,760.506,1748.2)">
<path
d="M59.159,188.949C57.444,190.033 55.324,188.422 53.737,187.187L48.106,182.748C47.099,181.955 46.591,180.368 46.98,179.223L48.206,175.588C48.644,174.29 49.926,173.967 51.067,174.865L57.002,179.17C59.121,180.843 60.575,181.565 62.88,180.154C76.508,171.8 93.604,164.621 108.107,174.376L105.398,182.411C97.791,177.954 81.711,174.685 59.159,188.949Z"
style="fill:rgb(143,125,221);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(4.16667,0,0,4.16667,760.506,1748.2)">
<path
d="M57.539,189.263L60.361,180.881C59.268,180.796 58.247,180.154 57.002,179.17L51.067,174.865C49.926,173.967 48.644,174.286 48.206,175.588L46.98,179.223C46.596,180.368 47.104,181.955 48.106,182.748L53.737,187.187C54.854,188.051 56.227,189.083 57.539,189.263Z"
style="fill:rgb(143,125,221);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(4.09372,0.776247,-0.776247,4.09372,816.991,1626.92)">
<path
d="M196.907,94.912C196.84,95.416 196.802,95.939 196.793,96.471C196.726,100.99 198.85,104.682 201.535,104.724C204.22,104.762 206.453,101.137 206.524,96.618C206.543,95.473 206.415,94.385 206.177,93.392L196.907,94.912Z"
style="fill:rgb(35,31,32);fill-rule:nonzero;" />
</g>
<g transform="matrix(4.09372,0.776247,-0.776247,4.09372,828.618,1631.56)">
<path
d="M157.919,93.558C157.7,94.513 157.586,95.558 157.605,96.651C157.672,101.17 159.905,104.8 162.594,104.758C165.284,104.715 167.403,101.023 167.337,96.504C167.327,96.019 167.294,95.544 167.237,95.083L157.919,93.558Z"
style="fill:rgb(35,31,32);fill-rule:nonzero;" />
</g>
<g transform="matrix(0.942641,0.333807,-0.333807,0.942641,796.569,-431.565)">
<g transform="matrix(-4.16667,0,0,4.16667,2268.44,1795.39)">
<path d="M160.075,140.954L180.137,144.43L183.211,126.685L163.149,123.21L160.075,140.954Z"
style="fill:rgb(81,43,212);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(-4.16667,0,0,4.16667,2268.44,1795.39)">
<path
d="M164.719,134.932C164.586,134.908 164.481,134.846 164.4,134.737C164.324,134.628 164.296,134.514 164.32,134.386C164.343,134.257 164.41,134.157 164.519,134.081C164.628,134.005 164.752,133.982 164.885,134.005C165.023,134.029 165.127,134.096 165.203,134.2C165.284,134.31 165.313,134.428 165.289,134.552C165.265,134.675 165.199,134.775 165.089,134.851C164.98,134.932 164.857,134.956 164.719,134.932Z"
style="fill:white;fill-rule:nonzero;" />
</g>
<g transform="matrix(-4.16667,0,0,4.16667,2268.44,1795.39)">
<path
d="M170.064,135.797L169.2,135.645L167.551,131.639C167.508,131.539 167.479,131.435 167.456,131.33L167.437,131.325C167.437,131.435 167.403,131.658 167.346,132.005L166.781,135.217L166.016,135.084L166.876,130.18L167.798,130.342L169.385,134.248C169.451,134.409 169.494,134.519 169.513,134.58L169.527,134.58C169.527,134.447 169.556,134.224 169.608,133.915L170.164,130.755L170.929,130.888L170.064,135.797Z"
style="fill:white;fill-rule:nonzero;" />
</g>
<g transform="matrix(-4.16667,0,0,4.16667,2268.44,1795.39)">
<path
d="M173.799,136.452L171.115,135.982L171.975,131.078L174.55,131.53L174.427,132.219L172.645,131.905L172.402,133.293L174.046,133.582L173.928,134.271L172.284,133.982L172.027,135.431L173.918,135.763L173.799,136.452Z"
style="fill:white;fill-rule:nonzero;" />
</g>
<g transform="matrix(-4.16667,0,0,4.16667,2268.44,1795.39)">
<path
d="M178.356,132.912L176.983,132.67L176.242,136.88L175.448,136.742L176.189,132.532L174.821,132.29L174.944,131.601L178.485,132.223L178.356,132.912Z"
style="fill:white;fill-rule:nonzero;" />
</g>
</g>
<g transform="matrix(-0.994983,-0.100047,-0.100047,0.994983,2908.92,373.608)">
<g transform="matrix(-4.16667,0,0,4.16667,1690.36,1513.15)">
<path
d="M109.464,36.08C115.765,42.247 109.018,48.52 95.152,50.354C81.287,52.188 64.561,48.458 58.716,43.103L109.464,36.08Z"
style="fill:rgb(96,93,90);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(-4.16667,0,0,4.16667,1690.36,1513.15)">
<path
d="M109.593,26.719L121.467,14.426C122.052,13.822 122.038,12.863 121.434,12.278L113.195,4.243C112.962,4.015 112.658,3.868 112.334,3.825L88.747,0.679C88.528,0.651 88.305,0.67 88.091,0.736L41.61,15.191C41.396,15.257 41.196,15.371 41.03,15.528L31.812,24.043C31.028,24.77 31.213,26.058 32.173,26.529L50.914,35.728C51.194,35.866 51.508,35.913 51.817,35.866L108.728,27.165C109.056,27.118 109.36,26.961 109.593,26.719Z"
style="fill:rgb(121,118,115);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(-4.16667,0,0,4.16667,1690.36,1513.15)">
<path
d="M31.555,25.963C31.698,26.196 31.902,26.395 32.173,26.529L50.914,35.728C51.194,35.866 51.508,35.913 51.817,35.866L108.728,27.165C109.056,27.113 109.36,26.956 109.593,26.719L121.467,14.426C121.581,14.307 121.667,14.174 121.733,14.036L31.555,25.963Z"
style="fill:rgb(96,93,90);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(-4.16667,0,0,4.16667,1690.36,1513.15)">
<path
d="M50.453,34.008L108.082,26.386C108.875,26.281 109.597,26.837 109.702,27.631L110.776,35.737C110.88,36.531 110.325,37.253 109.531,37.358L51.902,44.979C51.109,45.084 50.386,44.528 50.282,43.734L49.208,35.628C49.103,34.835 49.659,34.112 50.453,34.008Z"
style="fill:rgb(51,49,45);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
<g transform="matrix(-4.16667,0,0,4.16667,1690.36,1513.15)">
<path
d="M100.788,29.394L99.134,29.612L96.055,30.021L91.313,30.648L90.282,32.958C90.282,32.958 92.002,36.878 97.096,37.942L97.105,37.914L97.11,37.942C101.748,35.59 102.394,31.356 102.394,31.356L100.788,29.394Z"
style="fill:rgb(138,111,232);fill-rule:nonzero;stroke:rgb(35,31,32);stroke-width:1.9px;" />
</g>
</g>
</g>
<g transform="matrix(0.60863,0.302355,-0.142522,1.29119,40719.3,-924.931)">
<g transform="matrix(0.585311,0.643775,-0.784755,0.713489,1345.72,1066.8)">
<path
d="M450.208,1255.32C450.208,1255.32 450.208,1322.99 450.208,1376.64C450.208,1393.73 441.935,1410.11 427.208,1422.19C412.481,1434.27 392.507,1441.06 371.68,1441.06C371.678,1441.06 371.677,1441.06 371.675,1441.06C350.848,1441.06 330.874,1434.27 316.147,1422.19C301.42,1410.11 293.147,1393.73 293.147,1376.64C293.147,1322.99 293.147,1255.32 293.147,1255.32L450.208,1255.32Z"
style="fill:rgb(237,27,36);stroke:black;stroke-width:13.06px;stroke-linecap:round;stroke-miterlimit:1.5;" />
</g>
<g transform="matrix(1.13783,0,0,1.19444,-7.9274,394.343)">
<path
d="M677.69,1266.74C702.159,1266.74 725.625,1276 742.927,1292.48C760.229,1308.96 769.949,1331.32 769.949,1354.62L769.949,1412.93C769.949,1436.24 760.229,1458.59 742.927,1475.07C725.625,1491.56 702.159,1500.81 677.69,1500.81C650.763,1500.81 628.424,1500.81 628.424,1500.81L628.424,1266.74C628.424,1266.74 650.763,1266.74 677.69,1266.74Z"
style="fill:rgb(237,27,36);stroke:black;stroke-width:10.86px;stroke-linecap:round;stroke-miterlimit:1.5;" />
</g>
<g transform="matrix(0.897185,0,0,0.974809,153.516,950.692)">
<path
d="M518.887,894.288C599.547,894.786 664.65,955.108 664.65,1029.35L664.65,1183.36C664.65,1271.47 587.036,1342.91 491.295,1342.91C488.887,1342.91 486.504,1342.91 484.15,1342.91C440.744,1342.91 404.489,1312.46 400.518,1272.68C395.267,1225.32 389.445,1164.47 389.445,1124.83C389.445,1085.28 401.425,1022.74 412.687,972.695C423.029,926.791 467.13,893.981 518.066,894.295C518.34,894.284 518.613,894.286 518.887,894.288Z"
style="fill:rgb(237,27,36);" />
<path
d="M518.981,881.296C607.401,881.842 678.766,947.966 678.766,1029.35L678.766,1183.36C678.766,1278.65 594.832,1355.9 491.295,1355.9L484.151,1355.9C433.476,1355.9 391.146,1320.38 386.469,1273.94C381.172,1226.17 375.329,1164.81 375.329,1124.83C375.329,1084.6 387.409,1020.97 398.864,970.061L398.865,970.057C410.555,918.174 460.339,881.066 517.858,881.303C518.232,881.294 518.607,881.294 518.981,881.296ZM518.887,894.288C518.613,894.286 518.34,894.284 518.066,894.295C467.13,893.981 423.029,926.791 412.687,972.695C401.425,1022.74 389.445,1085.28 389.445,1124.83C389.445,1164.47 395.267,1225.32 400.518,1272.68C404.489,1312.46 440.744,1342.91 484.15,1342.91L491.295,1342.91C587.036,1342.91 664.65,1271.47 664.65,1183.36L664.65,1029.35C664.65,955.108 599.547,894.786 518.887,894.288Z" />
</g>
<g transform="matrix(1.1026,0,0,1,0.341586,923.067)">
<path
d="M734.957,1263.92C755.37,1263.35 798.683,1340.85 779.007,1365.92C750.652,1402.04 731.181,1406.53 694.602,1411.19C637.245,1418.51 617.071,1363.77 591.679,1315.52C564.83,1264.5 656.577,1263.92 656.577,1263.92L689.855,1315.64C689.855,1315.64 714.543,1264.48 734.957,1263.92Z"
style="fill:rgb(237,27,36);stroke:black;stroke-width:12.03px;stroke-linecap:round;stroke-miterlimit:1.5;" />
</g>
<g transform="matrix(0.897185,0,0,0.974809,153.516,950.692)">
<path
d="M518.887,894.288C599.547,894.786 664.65,955.108 664.65,1029.35L664.65,1183.36C664.65,1271.47 587.036,1342.91 491.295,1342.91C488.887,1342.91 486.504,1342.91 484.15,1342.91C440.744,1342.91 404.489,1312.46 400.518,1272.68C395.267,1225.32 389.445,1164.47 389.445,1124.83C389.445,1085.28 401.425,1022.74 412.687,972.695C423.029,926.791 467.13,893.981 518.066,894.295C518.34,894.284 518.613,894.286 518.887,894.288Z"
style="fill:rgb(237,27,36);" />
</g>
<g transform="matrix(1,0,0,1,98.6988,927.211)">
<path
d="M529.594,963.925C562.277,974.625 591.862,991.803 591.862,1026.19L591.862,1040.93C591.862,1061.89 583.533,1082 568.708,1096.82C553.884,1111.65 531.688,1129.1 512.812,1119.98C482.569,1105.36 444.953,1102.14 409.185,1119.98C374.305,1137.37 338.615,1088.38 338.615,1049.41C338.615,1049.4 338.615,1049.4 338.615,1049.4C338.615,1002.2 379.748,980.114 424.095,963.925C463.949,949.375 501.192,954.626 529.594,963.925Z"
style="fill:rgb(153,199,223);stroke:black;stroke-width:12.66px;stroke-linecap:round;stroke-miterlimit:1.5;" />
</g>
</g>
<g transform="matrix(1,0,0,2.12147,176.281,-2621.99)">
<g transform="matrix(0.762898,0,0,0.690977,10349.6,1763.66)">
<path
d="M41567.4,915.063C41543.5,880.995 41530.2,843.306 41530.2,803.673C41530.2,651.585 41611.6,521.382 41852.5,521.382C42064.7,521.382 42304.4,627.652 42381.4,752.339C42283.6,721.292 42131.8,709.57 41968.4,709.57C41694.3,709.57 41572.1,810.591 41567.4,915.063Z"
style="fill:rgb(255,117,69);stroke:rgb(36,36,36);stroke-width:7.92px;stroke-linecap:round;stroke-miterlimit:1.5;" />
</g>
<g transform="matrix(-0.690977,0,0,0.690977,71318.5,1357.23)">
<g transform="matrix(0.972486,0,0,0.972486,41482.2,832.843)">
<path
d="M0,362.84C-107.798,362.84 -211.681,332.601 -292.512,277.692C-326.552,254.568 -355.695,227.695 -379.133,197.821C-410.081,158.378 -430.018,115.3 -438.406,69.751C-435.667,65.624 -425.171,51.234 -403.418,36.73C-379.701,20.916 -337.367,1.726 -270.373,0.11C-267.147,0.036 -264.093,0 -261.04,0C-217.266,0 -174.484,14.88 -130.252,45.488C-91.415,72.363 -56.57,107.817 -25.828,139.096C-1.234,164.119 21.996,187.756 43.953,203.763C106.222,249.159 166.61,271.637 206.305,282.499C232.837,289.767 253.648,292.952 266.003,294.337C230.346,315.047 191.102,331.385 149.17,342.962C101.396,356.153 51.208,362.84 0,362.84"
style="fill:rgb(255,117,69);fill-rule:nonzero;stroke:rgb(36,36,36);stroke-width:8.14px;" />
</g>
<g transform="matrix(0.972486,0,0,0.972486,41111.7,833.025)">
<path
d="M0,195.298C-29.913,156.491 -49.232,114.216 -57.456,69.564C-54.717,65.437 -44.221,51.046 -22.468,36.542C0.916,20.95 42.397,2.076 107.771,0L159.485,133.527L0,195.298Z"
style="fill:white;fill-rule:nonzero;stroke:rgb(36,36,36);stroke-width:8.14px;" />
</g>
</g>
<g transform="matrix(0.625147,0.294349,-0.294349,0.625147,15863,-10620.1)">
<g transform="matrix(0.972486,0,0,0.972486,42173.3,325.218)">
<path
d="M0,65.081C-29.006,39.207 -78.842,31.846 -78.842,31.846C-78.842,31.846 -41.567,-6.603 5.149,-30.414C51.796,-54.19 107.883,-63.329 107.883,-63.329C107.883,-63.329 81.545,-17.043 64.122,29.791C45.063,81.021 41.769,128.41 41.769,128.41C41.769,128.41 27.775,89.857 0,65.081"
style="fill:rgb(255,117,69);fill-rule:nonzero;stroke:rgb(36,36,36);stroke-width:8.14px;" />
</g>
<g transform="matrix(-0.615542,-0.752886,-0.752886,0.615542,41920.1,478.653)">
<path
d="M-118.444,-237.827C-182.638,-237.827 -234.678,-185.786 -234.678,-121.592C-234.678,-57.398 -182.638,60.807 -118.444,60.807C-54.25,60.806 -2.21,-57.399 -2.21,-121.593C-2.21,-185.787 -54.25,-237.826 -118.444,-237.827Z"
style="fill:rgb(255,117,69);fill-rule:nonzero;stroke:rgb(36,36,36);stroke-width:8px;stroke-linecap:round;stroke-miterlimit:10;" />
</g>
<g transform="matrix(0.972486,0,0,0.972486,41992.5,573.011)">
<path
d="M0,50.115C1.062,20.242 -22.293,-4.837 -52.167,-5.899C-54.484,-5.981 -56.767,-5.9 -59.017,-5.697C-58.262,9.301 -54.12,22.707 -45.546,33.194C-35.151,45.909 -19.263,53.099 -0.551,56.096C-0.264,54.135 -0.072,52.142 0,50.115Z"
style="fill:rgb(36,36,36);fill-rule:nonzero;stroke:rgb(36,36,36);stroke-width:8px;stroke-linecap:round;stroke-miterlimit:10;" />
</g>
<g transform="matrix(-0.836373,-0.859909,-0.859909,0.836373,42013.7,509.799)">
<path
d="M-7.306,-17.301C-17.206,-17.301 -25.232,-12.738 -25.233,-7.107C-25.232,-1.477 -17.206,3.086 -7.306,3.086C2.595,3.086 10.62,-1.478 10.62,-7.107C10.62,-12.737 2.595,-17.301 -7.306,-17.301"
style="fill:rgb(36,36,36);fill-rule:nonzero;" />
</g>
<g transform="matrix(0.176456,-0.984308,0.984308,0.176456,32642.6,41322)">
<rect x="41797.8" y="2013.34" width="70.372" height="17.202" style="fill:rgb(255,117,69);" />
</g>
</g>
<g transform="matrix(0.229694,-0.531887,0.470724,0.203281,32139.2,23845)">
<path
d="M41146.4,895.707L41144.2,931.073L41144.2,938.54C41166.3,949.851 41181.4,972.839 41181.4,999.332C41181.4,1037.01 41150.8,1067.59 41113.1,1067.59C41075.5,1067.59 41044.9,1037.01 41044.9,999.332C41044.9,972.839 41060,949.851 41082.1,938.54L41082.1,931.073L41036.9,222C41035.6,200.94 41043,180.263 41057.4,164.875C41071.9,149.486 41092,140.756 41113.1,140.756C41134.2,140.756 41154.4,149.486 41168.8,164.875C41183.3,180.263 41190.7,200.94 41189.4,222L41161,667.531C41150.6,669.934 41141.2,674.442 41133.1,681.43C41096.1,713.403 41096.1,789.741 41112.3,858.783C41122.2,873.946 41133.8,886.441 41146.4,895.707Z"
style="fill:rgb(255,195,116);stroke:rgb(36,36,36);stroke-width:7.92px;stroke-linecap:round;stroke-miterlimit:1.5;" />
</g>
</g>
<g transform="matrix(0.292038,0,0,0.619548,28687.3,949.449)">
<path d="M42112.6,1148.3L42752.7,1148.3"
style="fill:none;stroke:black;stroke-width:27.11px;stroke-linecap:round;stroke-miterlimit:1.5;" />
</g>
<g transform="matrix(0.292038,0,0,0.619548,29722.2,-465.602)">
<path d="M42112.6,1148.3L42752.7,1148.3"
style="fill:none;stroke:black;stroke-width:27.11px;stroke-linecap:round;stroke-miterlimit:1.5;" />
</g>
<g transform="matrix(0.292038,0,0,0.619548,28741.9,1044.94)">
<path d="M42112.6,1148.3L42752.7,1148.3"
style="fill:none;stroke:black;stroke-width:27.11px;stroke-linecap:round;stroke-miterlimit:1.5;" />
</g>
<g transform="matrix(0.292038,0,0,0.619548,29781.1,-355.741)">
<path d="M42112.6,1148.3L42752.7,1148.3"
style="fill:none;stroke:black;stroke-width:27.11px;stroke-linecap:round;stroke-miterlimit:1.5;" />
</g>
<g transform="matrix(0.292038,0,0,0.619548,28703.4,1183.63)">
<path d="M42112.6,1148.3L42752.7,1148.3"
style="fill:none;stroke:black;stroke-width:27.11px;stroke-linecap:round;stroke-miterlimit:1.5;" />
</g>
<g transform="matrix(0.292038,0,0,0.619548,29815.7,-228.546)">
<path d="M42112.6,1148.3L42752.7,1148.3"
style="fill:none;stroke:black;stroke-width:27.11px;stroke-linecap:round;stroke-miterlimit:1.5;" />
</g>
<g transform="matrix(0.292038,0,0,0.619548,30142.9,1021.62)">
<path d="M42112.6,1148.3L42752.7,1148.3"
style="fill:none;stroke:black;stroke-width:27.11px;stroke-linecap:round;stroke-miterlimit:1.5;" />
</g>
<g transform="matrix(0.292038,0,0,0.619548,30177.4,790.308)">
<path d="M42112.6,1148.3L42752.7,1148.3"
style="fill:none;stroke:black;stroke-width:27.11px;stroke-linecap:round;stroke-miterlimit:1.5;" />
</g>
<g transform="matrix(0.292038,0,0,0.619548,30236.3,900.17)">
<path d="M42112.6,1148.3L42752.7,1148.3"
style="fill:none;stroke:black;stroke-width:27.11px;stroke-linecap:round;stroke-miterlimit:1.5;" />
</g>
</g>
</g>
<defs>
<linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse"
gradientTransform="matrix(9.887,51.017,-51.017,9.887,161.167,127.469)">
<stop offset="0" style="stop-color:rgb(82,44,213);stop-opacity:1" />
<stop offset="0.44" style="stop-color:rgb(138,111,232);stop-opacity:1" />
<stop offset="1" style="stop-color:rgb(138,111,232);stop-opacity:1" />
</linearGradient>
<radialGradient id="_Radial2" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse"
gradientTransform="matrix(56.9774,0,0,56.9774,205.245,60.4787)">
<stop offset="0" style="stop-color:rgb(225,223,221);stop-opacity:1" />
<stop offset="0.48" style="stop-color:rgb(225,223,221);stop-opacity:1" />
<stop offset="1" style="stop-color:white;stop-opacity:1" />
</radialGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 28 KiB

+6
View File
@@ -14,10 +14,16 @@
{ {
font-size: $fontSizeHero900; font-size: $fontSizeHero900;
color: $colorStatusWarningForeground1; color: $colorStatusWarningForeground1;
flex-shrink: 0;
} }
.title .title
{ {
@include body1Stronger; @include body1Stronger;
} }
.message
{
white-space: pre-wrap;
}
} }
+25 -13
View File
@@ -1,6 +1,6 @@
import ChatWarningRegular from "@fluentui/svg-icons/icons/chat_warning_24_regular.svg";
import React from "react"; import React from "react";
import cls from "./AlertMessage.module.scss"; import cls from "./AlertMessage.module.scss";
import { ChatWarningRegular } from "@fluentui/react-icons";
/** /**
* This alert box displays a custom message at the top of the homepage. * This alert box displays a custom message at the top of the homepage.
@@ -13,7 +13,7 @@ import { ChatWarningRegular } from "@fluentui/react-icons";
* - The file located at ALERT_TEXT_URL is accessible, not empty, and returns successfull HTTP status code (2xx) * - The file located at ALERT_TEXT_URL is accessible, not empty, and returns successfull HTTP status code (2xx)
*/ */
const AlertMessage: React.FC = async () => async function fetchAlert(): Promise<[string, string, string] | null>
{ {
if (!process.env.ALERT_TEXT_URL) if (!process.env.ALERT_TEXT_URL)
return null; return null;
@@ -26,23 +26,35 @@ const AlertMessage: React.FC = async () =>
if (!response.ok || !alertText) if (!response.ok || !alertText)
return null; return null;
const title: string = alertText.split("\n", 1)[0]; const title: string = alertText.split("\n", 1)[0].trim();
const message: string = alertText.substring(title.length); const message: string = alertText.substring(title.length + 1).trim();
return ( return [alertText, title, message];
<div role="alert" className={ cls.alertBox } aria-label={ alertText }>
<ChatWarningRegular className={ cls.icon } />
<div>
<p className={ cls.title }>{ title }</p>
<p dangerouslySetInnerHTML={ { __html: message } } />
</div>
</div>
);
} }
catch catch
{ {
return null; return null;
} }
}
const AlertMessage: React.FC = async () =>
{
const result = await fetchAlert();
if (!result)
return null;
const [alertText, title, message] = result;
return (
<div role="alert" className={ cls.alertBox } aria-label={ alertText }>
<ChatWarningRegular className={ cls.icon } />
<div>
<p className={ cls.title }>{ title }</p>
<p className={ cls.message } dangerouslySetInnerHTML={ { __html: message } } />
</div>
</div>
);
}; };
export default AlertMessage; export default AlertMessage;
+8 -16
View File
@@ -41,11 +41,6 @@
} }
} }
.dismiss
{
border-left: none;
}
.controls .controls
{ {
display: grid; display: grid;
@@ -65,19 +60,16 @@
width: 100%; width: 100%;
bottom: 0; bottom: 0;
&:not(:has(> .dismiss)) flex-flow: column;
.learnMore
{ {
flex-flow: column; border-bottom: none;
}
.learnMore .controls > button:last-child
{ {
border-bottom: none; border-left: none;
}
.controls > button:last-child
{
border-left: none;
}
} }
} }
} }
+7 -19
View File
@@ -1,12 +1,11 @@
"use client"; "use client";
import { acceptCookies, dismissCookies, getCookieChoice, rejectCookies } from "@/_utils/analytics/client"; import { acceptCookies, getCookieChoice, rejectCookies } from "@/_utils/analytics/client";
import { Dismiss24Regular } from "@fluentui/react-icons";
import React, { useCallback, useEffect, useState } from "react"; import React, { useCallback, useEffect, useState } from "react";
import Button from "./Button"; import Button from "./Button";
import cls from "./CookieBanner.module.scss"; import cls from "./CookieBanner.module.scss";
const CookieBanner: React.FC<{ askForConsent: boolean; }> = props => const CookieBanner: React.FC = () =>
{ {
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
@@ -16,6 +15,7 @@ const CookieBanner: React.FC<{ askForConsent: boolean; }> = props =>
return; return;
const choice = getCookieChoice(); const choice = getCookieChoice();
// eslint-disable-next-line react-hooks/set-state-in-effect
setVisible(choice === "none"); setVisible(choice === "none");
// Since Clarity cookies expiration dates extend well beyond 60 days, // Since Clarity cookies expiration dates extend well beyond 60 days,
@@ -36,12 +36,6 @@ const CookieBanner: React.FC<{ askForConsent: boolean; }> = props =>
setVisible(false); setVisible(false);
}, []); }, []);
const dismiss = useCallback(() =>
{
dismissCookies();
setVisible(false);
}, []);
if (!visible) if (!visible)
return null; return null;
@@ -59,16 +53,10 @@ const CookieBanner: React.FC<{ askForConsent: boolean; }> = props =>
</p> </p>
</Button> </Button>
{ props.askForConsent ? <div className={ cls.controls }>
<div className={ cls.controls }> <Button onClick={ accept }>Accept</Button>
<Button onClick={ accept }>Accept</Button> <Button onClick={ reject }>Reject</Button>
<Button onClick={ reject }>Reject</Button> </div>
</div>
:
<Button
title="Dismiss" icon={ <Dismiss24Regular /> }
onClick={ dismiss } className={ cls.dismiss } />
}
</div> </div>
); );
+1
View File
@@ -10,6 +10,7 @@ const RevokeConsentButton: React.FC = () =>
useEffect(() => useEffect(() =>
{ {
// eslint-disable-next-line react-hooks/set-state-in-effect
setHasConsent(getCookieChoice() === "accepted"); setHasConsent(getCookieChoice() === "accepted");
}, []); }, []);
+2 -1
View File
@@ -2,7 +2,8 @@
import links from "@/_data/links"; import links from "@/_data/links";
import socials from "@/_data/socials"; import socials from "@/_data/socials";
import { Dismiss24Regular, Navigation24Regular } from "@fluentui/react-icons"; import Dismiss24Regular from "@fluentui/svg-icons/icons/dismiss_24_regular.svg";
import Navigation24Regular from "@fluentui/svg-icons/icons/navigation_24_regular.svg";
import React, { useCallback, useEffect, useRef, useState } from "react"; import React, { useCallback, useEffect, useRef, useState } from "react";
import Button, { ButtonProps } from "./Button"; import Button, { ButtonProps } from "./Button";
import NavigationLinks from "./NavigationLinks"; import NavigationLinks from "./NavigationLinks";
-13
View File
@@ -30,19 +30,6 @@
} }
} }
.highlight
{
color: $colorNeutralForegroundInverted;
background-color: $colorNeutralBackgroundInverted;
padding: $spacingXXS $spacingNone;
&::selection
{
color: $colorNeutralForegroundInverted;
background-color: $colorBrandForeground1;
}
}
.illustrations .illustrations
{ {
justify-self: center; justify-self: center;
+6 -7
View File
@@ -9,12 +9,11 @@ import Package from "@/../package.json";
const FrontSection: React.FC = () => ( const FrontSection: React.FC = () => (
<section className={ cls.section }> <section className={ cls.section }>
<div className={ cls.content }> <div className={ cls.content }>
<h1>Hello World!</h1> <h1>Hello there!</h1>
<h2>{ Package.author.name } is here!</h2> <h2>My name is <span className="hl">{ Package.author.name }</span></h2>
<p role="text"> <p role="text">
I am a software engineer with extensive experience in<br aria-hidden /> I am a <span className="hl">software engineer</span> from Russia<br aria-hidden /> with extensive experience
<span className={ cls.highlight }>.NET and React development</span><br aria-hidden /> in <span className="hl">.NET and React</span> development
and you are on my website!
</p> </p>
<div className={ cls.ctaButtons }> <div className={ cls.ctaButtons }>
<Button as="next" href={ links.resume }>Download resume</Button> <Button as="next" href={ links.resume }>Download resume</Button>
@@ -23,8 +22,8 @@ const FrontSection: React.FC = () => (
</div> </div>
<div className={ cls.illustrations }> <div className={ cls.illustrations }>
<Image className={ cls.main } src={ profilePicture.src } alt={ profilePicture.alt } priority /> <Image className={ cls.main } src={ profilePicture.src } alt={ profilePicture.alt } loading="eager" />
<Image className={ cls.secondary } src={ homeDecor.src } alt={ homeDecor.alt } /> <Image className={ cls.secondary } src={ homeDecor.src } alt={ homeDecor.alt } loading="eager" />
</div> </div>
</section> </section>
); );
+1 -1
View File
@@ -9,7 +9,7 @@ const TitleLogo: React.FC = () => (
<Image src={ logo } <Image src={ logo }
alt="A fox jumping down, and a diagonal stripe in the background, forming letters X and F" alt="A fox jumping down, and a diagonal stripe in the background, forming letters X and F"
aria-hidden aria-hidden
priority /> loading="eager" />
<p> <p>
<span>xfox111</span> <span>xfox111</span>
<sub>.net</sub> <sub>.net</sub>
-16
View File
@@ -1,16 +0,0 @@
export const bio: string[] =
[
"My name is Eugene Fox. I am a professional software developer primarily focused on .NET and React projects.",
"My journey as a programmer started in 2018 from a silly free-time hobby. Since then, I have released a couple of personal projects, some of which have become quite popular.",
"Graduated from Bonch-Bruevich University of Telecommunications in 2023 where I got my bachelor's degree in computer science. It was fun. Took part in a number of hackathons (usually first place for us) as well as science conferences (including those hosted by IEEE).",
"Also, before graduation I managed to work in several different companies in different IT fields (mostly software development, of course).",
"Out-of-box thinking, and constant self-improvement is my life strategy. New tool released? - Yes, please! GitHub is hosting another conference? - Sign me up! There is a new challenging task to complete? - Oh, boy, here we go again! So many things to learn, so little time to spare...",
"Overall, enthusiastic, fast learning and energetic person. Love coding and creating something new. Like to draw and compose music. Proud member of the furry community."
];
export default bio;
+11
View File
@@ -0,0 +1,11 @@
export const Bio: React.FC = () => <>
<p>I am a software engineer who loves desiging and building complex services, creating nice intuitive applications, and solving engineering challenges.</p>
<p>I started programming in 2018 because I am not a good artist, and programming allows to bring my visions and ideas to life. My specialty is React and .NET in web development, but I always look out for other fields and tools as well.</p>
<p>Thanks to my quick adaptation and communication skills, I can either be a good team player, or handle tasks independently.</p>
<p>Graduated from <a href="https://sut.ru/eng" target="_blank">Bonch-Bruevich University of Telecommunications</a>. In 2023 received Bachelor&apos;s degree in Computer science, then in 2025 Master&apos;s in Radiotechnology. Despite that, I began my career path much earlier and consider myself a self-taught developer.</p>
<p>In my free time I like to play some instruments, pilot a 737 in a flightsim, or just keep working, but on my own pet projects.</p>
</>;
export const bioPremise: string = "My name is Eugene Fox. I am a professional software developer primarily focused on .NET and React projects.";
export default Bio;
-20
View File
@@ -1,20 +0,0 @@
const experience: WorkplaceEntry[] =
[
{ title: "IT/VR tutor", year: "2020", place: "Quantorium", tech: "Unity, STEM" },
{ title: "System administrator", year: "2021", place: "Quantorium", tech: "M365, Intune, Azure" },
{ title: "Software Engineer", place: "[nordcloud]", tech: "ASP.NET, EF Core" },
{ title: "CTO", year: "2022", place: "FoxDev Studio", tech: "Unity, Xamarin, .NET, React, Azure" },
{ title: "Senior Software Engineer", year: "2023", place: "A-rial", tech: ".NET, React, DevOps" },
{ title: "Senior Software Architect", year: "2024", place: "Ubitel", tech: ".NET, React, Embedded devices" },
{ title: "Here", place: "Your company" },
];
export default experience;
export type WorkplaceEntry =
{
year?: string;
place?: string;
title: string;
tech?: string;
};
+95
View File
@@ -0,0 +1,95 @@
import Button from "@/_components/Button";
import { ReactElement } from "react";
const experience: WorkplaceEntry[] =
[
{
place: "Nordcloud, Saint-Petersburg, RU",
title: "Software Engineer",
summary: "Working on MightyCall cloud call center product",
year: "2021",
description: <>
<p>Implementing new features and fixing bugs in large-scale distributed VoIP system with ASP.NET and Angular</p>
<ul>
<li>Completed 2 week onboarding in 3 days.</li>
<li>Found and fixed a critical issue in system&apos;s build process, improving performance by 40%</li>
</ul>
</>
},
{
place: "Quantorium, Saint-Petersburg, RU",
title: "System administrator",
summary: "Administration of school's IT infrastructure",
year: "2021",
description: <ul>
<li>Integrated Microsoft Azure and M365 services which reduced overall workload of the staff by 30%.</li>
<li>Implemented Azure Intune services for management of 100+ school devices.</li>
<li>Integrated modern interactive solutions into education process during COVID-19 pandemic.</li>
<li>Implemented storage inventory system which helped to track 100% of school&apos;s inventory.</li>
</ul>
},
{
place: "A-rial, Saint-Petersburg, RU",
title: "Software Engineer",
summary: "Legacy software support and DevOps",
year: "2023",
description: <>
<p>Supporting legacy WLAN controller system, as well as maintaining company&apos;s IT infrastructure</p>
<p className="hl">Stack: .NET, React, Golang, Vue, Mongo</p>
<ul>
<li>Built company&apos;s IT infrastructure from scratch (email, cloud, git, etc.)</li>
<li>Found and fixed several critical bugs in one of the projects which allowed the company to receive next round of investments.</li>
<li>Designed and implemented web interface for wireless routers using React</li>
<li>Lead critical QA field tests for WLAN controller product.</li>
</ul>
</>
},
{
place: "A-rial, Saint-Petersburg, RU",
title: "Lead Software Engineer",
summary: "Working on software for RF Analyzer hardware",
year: "2024",
description: <>
<p>Creating, desiging and implementing RF analyzer software, as well as participating in hardware design.</p>
<p className="hl">Stack: ASP.NET (RESTFul API), React, Linux</p>
<ul>
<li>Implemented both frontend and backend as modular components with ASP.NET and React.</li>
<li>Wrote abstraction layers for managing Wi-Fi and SDR hardware in C#.</li>
<li>Set up a complete CI/CD pipeline with GitHub Actions.</li>
</ul>
</>
},
{
place: "A-rial, Saint-Petersburg, RU",
title: "Lead System Architect",
summary: "Working on WLAN Controller system",
year: "2025",
description: <>
<p>Designing and implementing large-scale distributed WLAN controller system</p>
<p className="hl">Stack: React, ASP.NET (RESTFul API), MongoDB, Postges (EF Core), RabbitMQ (MassTransit), MQTT, Docker.</p>
<ul>
<li>Designed an architecture of a new event-driven microservice-based system to replace legacy monolith from scratch (HLD + LLD).</li>
<li>Wrote a comprehensive techref for each of 16 components.</li>
<li>Solo implemented the whole system from start to finish in just 3 months.</li>
<li>Designed and wrote an agent service with .NET NativeAOT to operate OpenWRT routers.</li>
</ul>
</>
},
{
place: "Your company",
title: "Here",
summary: "Working on new and exciting projects",
description: <Button href="/resume">Download resume</Button>
},
];
export default experience;
export type WorkplaceEntry =
{
year?: string;
place?: string;
title: string;
summary?: string;
description?: ReactElement;
};
+3 -3
View File
@@ -1,7 +1,7 @@
import Package from "@/../package.json"; import Package from "@/../package.json";
import { Metadata } from "next"; import { Metadata } from "next";
import { unstable_noStore } from "next/cache"; import { unstable_noStore } from "next/cache";
import bio from "./bio"; import { bioPremise } from "./bio";
import socials from "./socials"; import socials from "./socials";
export const canonicalName: URL = new URL(`https://${process.env.DOMAIN_NAME}`); export const canonicalName: URL = new URL(`https://${process.env.DOMAIN_NAME}`);
@@ -18,12 +18,12 @@ export async function generateMetadata(): Promise<Metadata>
unstable_noStore(); unstable_noStore();
return { return {
title: baseTitle, title: baseTitle,
description: bio[0], description: bioPremise,
metadataBase: canonicalName, metadataBase: canonicalName,
openGraph: openGraph:
{ {
title: baseTitle, title: baseTitle,
description: bio[0], description: bioPremise,
type: "profile", type: "profile",
firstName: Package.author.name.split(" ")[0], firstName: Package.author.name.split(" ")[0],
lastName: Package.author.name.split(" ")[1], lastName: Package.author.name.split(" ")[1],
+63 -49
View File
@@ -9,7 +9,19 @@ import passwordGeneratorLight from "@/_assets/illustrations/projects/PasswordGen
import simpleOtpImg from "@/_assets/illustrations/projects/SimpleOTP.svg"; import simpleOtpImg from "@/_assets/illustrations/projects/SimpleOTP.svg";
import tabsAsideDark from "@/_assets/illustrations/projects/TabsAside/dark.webp"; import tabsAsideDark from "@/_assets/illustrations/projects/TabsAside/dark.webp";
import tabsAsideLight from "@/_assets/illustrations/projects/TabsAside/light.webp"; import tabsAsideLight from "@/_assets/illustrations/projects/TabsAside/light.webp";
import * as ic from "@fluentui/react-icons"; import Beaker24Regular from "@fluentui/svg-icons/icons/beaker_24_regular.svg";
import Branch24Regular from "@fluentui/svg-icons/icons/branch_24_regular.svg";
import Code24Regular from "@fluentui/svg-icons/icons/code_24_regular.svg";
import Color24Regular from "@fluentui/svg-icons/icons/color_24_regular.svg";
import Database24Regular from "@fluentui/svg-icons/icons/database_24_regular.svg";
import Desktop24Regular from "@fluentui/svg-icons/icons/desktop_24_regular.svg";
import FlashFlow24Regular from "@fluentui/svg-icons/icons/flash_flow_24_regular.svg";
import FlashSettings24Regular from "@fluentui/svg-icons/icons/flash_settings_24_regular.svg";
import Globe24Regular from "@fluentui/svg-icons/icons/globe_24_regular.svg";
import HeartPulse24Regular from "@fluentui/svg-icons/icons/heart_pulse_24_regular.svg";
import Phone24Regular from "@fluentui/svg-icons/icons/phone_24_regular.svg";
import PhoneDesktop24Regular from "@fluentui/svg-icons/icons/phone_desktop_24_regular.svg";
import Server24Regular from "@fluentui/svg-icons/icons/server_24_regular.svg";
import { StaticImageData } from "next/image"; import { StaticImageData } from "next/image";
const projects: Project[] = const projects: Project[] =
@@ -20,21 +32,20 @@ const projects: Project[] =
description: description:
[ [
"During one of the classes at university I struggled to log into my account on a lab computer. I have long random passwords, so I had to type them manually from my phone which took about 5 minutes. I thought that there must be a better way to do this.", "During one of the classes at university I struggled to log into my account on a lab computer. I have long random passwords, so I had to type them manually from my phone which took about 5 minutes. I thought that there must be a better way to do this.",
"So, I came up with this idea where you can easily send your credentials to any computer by simply scanning a QR code with a password manager app.", "So, I came up with this idea where you can easily send your credentials to any computer by simply scanning a QR code with a password manager app (this was before WebAuthn became widely adopted).",
"In the end, I have created a big web service with mobile app and a customer portal, that could authenticate users on any website, and any device within a few seconds." "In the end, I have created a big web service with mobile app and a customer portal, that could authenticate users on any website, and any device within a few seconds."
], ],
image: ezlogImg, image: ezlogImg,
link: "https://ezlog.app/about", link: "https://github.com/xfox111/easylogon-web",
stack: stack:
[ [
{ text: "C#/TypeScript", icon: ic.Code24Regular }, { text: "C#/TypeScript", icon: Code24Regular },
{ text: ".NET 6", icon: ic.Server24Regular }, { text: ".NET 6", icon: Server24Regular },
{ text: "ReactJS", icon: ic.PhoneDesktop24Regular }, { text: "React/Vite", icon: PhoneDesktop24Regular },
{ text: "Xamarin.Forms", icon: ic.Phone24Regular }, { text: "Xamarin.Forms", icon: Phone24Regular },
{ text: "SQL Server", icon: ic.Database24Regular }, { text: "SQL Server", icon: Database24Regular },
{ text: "Azure DevOps", icon: ic.Branch24Regular }, { text: "Azure DevOps", icon: Branch24Regular },
{ text: "Azure Pipelines/AppCenter", icon: ic.FlashFlow24Regular }, { text: "Azure Pipelines/GitHub Actions", icon: FlashFlow24Regular }
{ text: "AppCenter", icon: ic.HeartPulse24Regular }
] ]
}, },
{ {
@@ -50,12 +61,12 @@ const projects: Project[] =
link: "https://github.com/xfox111/TabsAsideExtension", link: "https://github.com/xfox111/TabsAsideExtension",
stack: stack:
[ [
{ text: "ReactJS", icon: ic.Desktop24Regular }, { text: "React/WXT", icon: Desktop24Regular },
{ text: "TypeScript/SASS", icon: ic.Code24Regular }, { text: "TypeScript", icon: Code24Regular },
{ text: "Chrome/WebExt", icon: ic.FlashSettings24Regular }, { text: "Browser extension", icon: FlashSettings24Regular },
{ text: "Fluent UI", icon: ic.Color24Regular }, { text: "Fluent UI", icon: Color24Regular },
{ text: "GitHub", icon: ic.Branch24Regular }, { text: "GitHub", icon: Branch24Regular },
{ text: "GitHub Actions", icon: ic.FlashFlow24Regular }, { text: "GitHub Actions", icon: FlashFlow24Regular },
] ]
}, },
{ {
@@ -70,10 +81,10 @@ const projects: Project[] =
link: "https://github.com/xfox111/SimpleOTP", link: "https://github.com/xfox111/SimpleOTP",
stack: stack:
[ [
{ text: ".NET/C#", icon: ic.Code24Regular }, { text: ".NET/C#", icon: Code24Regular },
{ text: "MSTest", icon: ic.Beaker24Regular }, { text: "MSTest", icon: Beaker24Regular },
{ text: "GitHub", icon: ic.Branch24Regular }, { text: "GitHub", icon: Branch24Regular },
{ text: "GitHub Actions", icon: ic.FlashFlow24Regular }, { text: "GitHub Actions", icon: FlashFlow24Regular },
] ]
}, },
{ {
@@ -89,32 +100,35 @@ const projects: Project[] =
link: "https://github.com/xfox111/PasswordGeneratorExtension", link: "https://github.com/xfox111/PasswordGeneratorExtension",
stack: stack:
[ [
{ text: "React/Vite", icon: ic.Desktop24Regular }, { text: "React/Vite", icon: Desktop24Regular },
{ text: "TypeScript", icon: ic.Code24Regular }, { text: "TypeScript", icon: Code24Regular },
{ text: "Chrome/WebExt", icon: ic.FlashSettings24Regular }, { text: "Browser extension", icon: FlashSettings24Regular },
{ text: "Fluent UI", icon: ic.Color24Regular }, { text: "Fluent UI", icon: Color24Regular },
{ text: "GitHub", icon: ic.Branch24Regular }, { text: "GitHub", icon: Branch24Regular },
{ text: "GitHub Actions", icon: ic.FlashFlow24Regular }, { text: "GitHub Actions", icon: FlashFlow24Regular },
] ]
}, },
{ {
title: "GUT.Schedule", title: "GUT.Schedule / Bonch.Calendar",
subtitle: "Mobile app that exports Bonch university schedule to e-calendar", subtitle: "Mobile app that exports Bonch university schedule to e-calendar",
description: description:
[ [
"[2019]", "I created this app in 2019 during my time in Bonch-Bruevich University of Telecommunications as a BS student.",
"I created this app during my time in Bonch-Bruevich University of Telecommunications as a BS student.", "It was designed to help students to manage their timetable in a more convenient and effective way by exporting their schedule to any calendar app on their Android phones.",
"It was designed to help students to manage their timetable in a more convenient and effective way." "In 2025 I made it into a web-service that can generate web calendars the students can subscribe to directly from their calendar apps, regardless of the platform they are using.",
], ],
image: gutScheduleImg, image: gutScheduleImg,
link: "https://github.com/xfox111/GUTSchedule", link: "https://github.com/stars/XFox111/lists/bonch",
stack: stack:
[ [
{ text: ".NET/C#", icon: ic.Code24Regular }, { text: ".NET/C#", icon: Code24Regular },
{ text: "Xamarin.Android", icon: ic.Phone24Regular }, { text: "Xamarin.Android", icon: Phone24Regular },
{ text: "GitHub", icon: ic.Branch24Regular }, { text: "GitHub", icon: Branch24Regular },
{ text: "NUnit 3", icon: ic.Beaker24Regular }, { text: "NUnit", icon: Beaker24Regular },
{ text: "Azure Pipelines", icon: ic.FlashFlow24Regular }, { text: "Azure Pipelines", icon: FlashFlow24Regular },
{ text: "React/Vite", icon: Globe24Regular },
{ text: "Typescript", icon: Code24Regular },
{ text: "GitHub Actions", icon: FlashFlow24Regular },
] ]
}, },
{ {
@@ -124,19 +138,19 @@ const projects: Project[] =
[ [
"[2019]", "[2019]",
"My first published app.", "My first published app.",
"I like to watch videos while working on my projects, but at the time YouTube didn not have a proper picture-in-picture mode and overall had a lot of issues with the UX, so this was my way to fix this.", "I like to watch videos while working on my projects, but at the time YouTube didn't have a proper picture-in-picture mode and overall had a lot of issues with the UX, so this was my way to fix it.",
"Unfortunately, Google doesn't like third-party YouTube clients." "Unfortunately, Google doesn't like third-party YouTube clients, so soon after publishing, they revoked app's API access :("
], ],
image: foxTubeLight, image: foxTubeLight,
imageDark: foxTubeDark, imageDark: foxTubeDark,
link: "https://www.youtube.com/watch?v=Mio9FbxmbhM", link: "https://www.youtube.com/watch?v=Mio9FbxmbhM",
stack: stack:
[ [
{ text: ".NET/C#", icon: ic.Code24Regular }, { text: ".NET/C#", icon: Code24Regular },
{ text: "UWP", icon: ic.Desktop24Regular }, { text: "UWP", icon: Desktop24Regular },
{ text: "Azure DevOps", icon: ic.Branch24Regular }, { text: "Azure DevOps", icon: Branch24Regular },
{ text: "AppCenter", icon: ic.HeartPulse24Regular }, { text: "AppCenter", icon: HeartPulse24Regular },
{ text: "Azure Pipelines", icon: ic.FlashFlow24Regular }, { text: "Azure Pipelines", icon: FlashFlow24Regular },
] ]
}, },
{ {
@@ -153,10 +167,10 @@ const projects: Project[] =
link: "https://github.com/xfox111/MotionDecoder", link: "https://github.com/xfox111/MotionDecoder",
stack: stack:
[ [
{ text: ".NET/C#", icon: ic.Code24Regular }, { text: ".NET/C#", icon: Code24Regular },
{ text: "WinForms", icon: ic.Desktop24Regular }, { text: "WinForms", icon: Desktop24Regular },
{ text: "Accord.NET", icon: ic.FlashSettings24Regular }, { text: "Accord.NET", icon: FlashSettings24Regular },
{ text: "GitHub", icon: ic.Branch24Regular }, { text: "GitHub", icon: Branch24Regular },
] ]
} }
]; ];
@@ -176,6 +190,6 @@ export type Project =
type TechStackItem = type TechStackItem =
{ {
icon: ic.FluentIcon; icon: React.FC;
text: string; text: string;
}; };
-60
View File
@@ -1,60 +0,0 @@
import { ImageExport } from "@/_assets/assets";
import imgs from "@/_assets/illustrations/skills";
import * as ic from "@fluentui/react-icons";
const skills: Skill[] =
[
{
title: "NodeJS",
description: "React, Vite, Next.js, SASS, TypeScript",
icon: ic.WindowDevToolsRegular,
image: imgs.nodejs
},
{
title: ".NET",
description: "ASP.NET, Razor, WinUI/UWP, WPF, WinForms | Xamarin.Forms, MAUI",
icon: ic.PhoneDesktopRegular,
image: imgs.dotnet
},
{
title: "Architecture & systems",
description: "Docker, Nginx, Linux | Modules, microservices",
icon: ic.DesktopFlowRegular,
image: imgs.architecture
},
{
title: "Databases",
description: "Entity Framework, MongoDB",
icon: ic.DatabaseMultipleRegular,
image: imgs.databases
},
{
title: "Design",
description: "Figma, Photoshop, Illustrator",
icon: ic.DesignIdeasRegular,
// Note, this picture has a special behavior in @/_page_sections/SkillsSection.tsx:24
image: imgs.design
},
{
title: "DevOps",
description: "GitHub, Azure DevOps, AppCenter, Atlassian",
icon: ic.FlashFlowRegular,
image: imgs.devops
},
{
title: "Administration",
description: "Ansible, M365, Azure, InTune",
icon: ic.ConnectedRegular,
image: imgs.admin
}
];
export default skills;
export type Skill =
{
title: string;
description: string;
icon: ic.FluentIcon;
image: ImageExport;
};
+105
View File
@@ -0,0 +1,105 @@
import { ImageExport } from "@/_assets/assets";
import imgs from "@/_assets/illustrations/skills";
import WindowDevTools24Regular from "@fluentui/svg-icons/icons/window_dev_tools_24_regular.svg";
import PhoneDesktop24Regular from "@fluentui/svg-icons/icons/phone_desktop_24_regular.svg";
import DesktopFlow24Regular from "@fluentui/svg-icons/icons/desktop_flow_24_regular.svg";
import DatabaseMultiple32Regular from "@fluentui/svg-icons/icons/database_multiple_32_regular.svg";
import DesignIdeas24Regular from "@fluentui/svg-icons/icons/design_ideas_24_regular.svg";
import FlashFlow24Regular from "@fluentui/svg-icons/icons/flash_flow_24_regular.svg";
import Connected24Regular from "@fluentui/svg-icons/icons/connected_24_regular.svg";
import ShieldKeyhole24Regular from "@fluentui/svg-icons/icons/shield_keyhole_24_regular.svg";
import React from "react";
const skills: Skill[] =
[
{
title: "NodeJS",
caption: "React, Vite, Next.js, SASS, TypeScript",
description: <>
I learned React while being on a 2 week quarantine back in 2020. Since then, it was my go-to framework for frontend in both commercial and personal projects. While .NET is still my main choice for backend, I occasionally use Next.js for smaller projects as well.
</>,
icon: WindowDevTools24Regular,
image: imgs.nodejs
},
{
title: ".NET",
caption: "ASP.NET, WebAPI, Minimal API, MVC | MAUI, WinUI",
description: <>
My bread and butter. The one and only! I learned C# back in 2018 while trying to make a game in Unity. Since then, I have fallen in love with the language and the ecosystem. I have used .NET for everything: web, desktop, mobile, IoT... you name it.
</>,
icon: PhoneDesktop24Regular,
image: imgs.dotnet
},
{
title: "System design",
caption: "Clean architecture, Microservices, Event-driven design",
description: <>
Working for small companies (especially abmitious ones) has its perks. One of them is that you get to do everything, including architecture design. Throughout my career, I have designed a couple of high-load distributed systems, as well as many smaller applications.
</>,
icon: DesktopFlow24Regular,
image: imgs.architecture
},
{
title: "Databases & ORM",
caption: "SQL, Postgres, MongoDB, EF Core",
description: <>
If there is a SQL, then where is prequel?..
</>,
icon: DatabaseMultiple32Regular,
image: imgs.databases
},
{
title: "UI/UX Design",
caption: "Figma, Photoshop, Illustrator",
description: <>
Even though I am not a professional designer, I know a thing or two about good UX, since for the most of the projects, I was usually responsible for it as well.
<br /><br />
For UI though, I prefer sticking to existing design systems (like Fluent UI or Material). But of course, I can draw a couple of buttons if needed.
</>,
icon: DesignIdeas24Regular,
// Note, this picture has a special behavior in @/_page_sections/SkillsSection.tsx
image: imgs.design
},
{
title: "DevOps & Tooling",
caption: "Git, Jira, CI/CD automation, Docker",
description: <>
Back when I was learning programming, whenever I started a new project, I imagined being at a big company with dozens of people working on the same codebase. So, I always tried to make it look like it: version control, documentation, CI/CD, kanban, sprints...<br /><br />
Who would&apos;ve thought that this actually would come in handy!
</>,
icon: FlashFlow24Regular,
image: imgs.devops
},
{
title: "Infrastructure & Administration",
caption: "Azure, AWS, Docker, K8S, Nginx, Linux, Ansible",
description: <>
Thanks to my past experience, I have a solid understanding of how to build and manage infrastructure. I have worked with both cloud and on-premises solutions, as well as different containerization and orchestration tools.
</>,
icon: Connected24Regular,
image: imgs.admin
},
{
title: "Application security",
caption: "JWT, WebAuthn, OAuth2, TOTP",
description: <>
Throughout my work (as a system administrator and as an engineer), I had to learn a lot about best security practices and cybersecurity in general.
<br /><br />
So, I have experience implementing various authentication and authorization mechanisms (some of which I wrote from scratch by following specifications), as well as securing applications against common vulnerabilities.
</>,
icon: ShieldKeyhole24Regular,
// Note, this picture has a special behavior in @/_page_sections/SkillsSection.tsx
image: imgs.security
},
];
export default skills;
export type Skill =
{
title: string;
caption: string;
icon: React.FC;
image: ImageExport;
description: React.ReactElement;
};
+1 -1
View File
@@ -12,7 +12,7 @@ const socials: Socials =
href: "https://www.linkedin.com/in/xfox/", href: "https://www.linkedin.com/in/xfox/",
username: "@xfox" username: "@xfox"
}, },
"BlueSky": "Bluesky":
{ {
href: "https://bsky.app/profile/xfox111.net", href: "https://bsky.app/profile/xfox111.net",
username: "@xfox111.net", username: "@xfox111.net",
+1 -1
View File
@@ -8,7 +8,7 @@
@include centerTwo; @include centerTwo;
> div:first-child .content
{ {
@include flex(column); @include flex(column);
gap: $spacingM; gap: $spacingM;
+5 -7
View File
@@ -1,20 +1,18 @@
import { aboutPicture } from "@/_assets/illustrations"; import { aboutPicture } from "@/_assets/illustrations";
import bio from "@/_data/bio"; import Bio from "@/_data/bio";
import Image from "next/image"; import Image from "next/image";
import React from "react"; import React from "react";
import cls from "./AboutSection.module.scss"; import cls from "./AboutSection.module.scss";
const AboutSection: React.FC = () => ( const AboutSection: React.FC = () => (
<section id="about" className={ cls.section }> <section id="about" className={ cls.section }>
<div> <Image src={ aboutPicture.src } alt={ aboutPicture.alt } />
<div className={ cls.content }>
<h2>About me</h2> <h2>About me</h2>
{ bio.map((i, index) => <Bio />
<p key={ index }>{ i }</p>
) }
</div> </div>
<Image src={ aboutPicture.src } alt={ aboutPicture.alt } />
</section> </section>
); );
+1 -1
View File
@@ -36,7 +36,7 @@ const ContactSection: React.FC = () =>
return ( return (
<section id="contacts" className={ cls.section }> <section id="contacts" className={ cls.section }>
<h2>Let&apos;s get in touch</h2> <h2>Let&apos;s get in touch!</h2>
<div className={ cls.content }> <div className={ cls.content }>
@@ -68,7 +68,7 @@
box-shadow: inset 0 0 0 16px $colorNeutralBackground1; box-shadow: inset 0 0 0 16px $colorNeutralBackground1;
} }
.description .info
{ {
p p
{ {
@@ -113,9 +113,16 @@
.item .item
{ {
grid-template-columns: 64px auto 1fr; grid-template-columns: 64px auto 1fr;
grid-template-rows: auto auto;
padding: $spacingXXXL $spacingNone; padding: $spacingXXXL $spacingNone;
gap: $spacingM; gap: $spacingM;
align-items: center; align-items: center;
.description
{
grid-row: 2/2;
grid-column: 3/4;
}
} }
} }
@@ -126,7 +133,7 @@
.line .line
{ {
bottom: 72px; bottom: 132px;
width: 100%; width: 100%;
height: 8px; height: 8px;
align-content: center; align-content: center;
@@ -147,9 +154,10 @@
.item .item
{ {
grid-template-rows: 128px auto 48px; grid-template-rows: 128px auto 48px 48px;
padding: $spacingNone $spacingM; padding: $spacingNone $spacingM;
row-gap: $spacingM; row-gap: $spacingM;
cursor: pointer;
.year .year
{ {
@@ -171,6 +179,23 @@
} }
.description .description
{
grid-row: 4/4;
transition-property: font-size, line-height, opacity;
transition-duration: $durationNormal;
transition-timing-function: $curveEasyEaseMax;
font-size: 0;
opacity: 0;
p
{
margin-bottom: $spacingSNudge;
}
}
.info
{ {
grid-row: 1/1; grid-row: 1/1;
align-self: self-end; align-self: self-end;
@@ -197,7 +222,7 @@
{ {
// Item that is being hovered or focused // Item that is being hovered or focused
&:is(:hover, :focus-visible, :focus-within) &:is(:focus-visible, :focus-within)
{ {
.year, .year,
@@ -207,16 +232,27 @@
opacity: 1; opacity: 1;
} }
> i .description
{ {
box-shadow: inset 0 0 0 0 $colorNeutralBackground1; @include body2($fontFamilyBaseAlt);
opacity: 1;
} }
.description > p .info > p
{ {
@include subtitle2($fontFamilyBaseAlt); @include subtitle2($fontFamilyBaseAlt);
opacity: 1; opacity: 1;
} }
.year
{
font-size: $fontSizeHero800 !important;
}
}
&:is(:hover, :focus-visible, :focus-within) > i
{
box-shadow: inset 0 0 0 0 $colorNeutralBackground1;
} }
// Other not focused items // Other not focused items
@@ -228,8 +264,11 @@
{ {
@include body1($fontFamilyBaseAlt); @include body1($fontFamilyBaseAlt);
color: $colorNeutralForeground3; color: $colorNeutralForeground3;
}
@media screen and (max-width: 1200px) @media screen and (max-width: 1200px)
{
.title
{ {
opacity: 0; opacity: 0;
font-size: 0; font-size: 0;
@@ -237,6 +276,18 @@
} }
} }
} }
@media screen and (max-width: 1400px)
{
&:has(:focus-visible, :focus-within) .item:not(:focus-visible, :focus-within)
{
.title
{
opacity: 0;
font-size: 0;
}
}
}
} }
} }
} }
+12 -5
View File
@@ -22,16 +22,23 @@ const ExperienceSection: React.FC = () => (
<div className={ cls.item } key={ index } <div className={ cls.item } key={ index }
tabIndex={ 0 } role="listitem" aria-label={ getAriaLabel(i) }> tabIndex={ 0 } role="listitem" aria-label={ getAriaLabel(i) }>
<p aria-hidden className={ cls.year }>{ i.year }</p>
<i />
<div className={ cls.description }> <div className={ cls.description }>
{ i.description }
</div>
<p aria-hidden className={ cls.year } style={ index > 0 && experience[index - 1].year === i.year ? { fontSize: 0 } : undefined }>
{ i.year }
</p>
<i />
<div className={ cls.info }>
<p aria-hidden>{ i.place }</p> <p aria-hidden>{ i.place }</p>
<h3 aria-hidden className={ cls.title }>{ i.title }</h3> <h3 aria-hidden className={ cls.title }>{ i.title }</h3>
<p aria-hidden={ !!i.tech }>{ i.tech ?? <Link href="#contacts">Contact me</Link> }</p> <p aria-hidden={ !!i.summary }>{ i.summary ?? <Link href="#contacts">Contact me</Link> }</p>
</div> </div>
</div> </div>
) } ) }
</div> </div>
{/* <p>Deserunt esse irure duis magna irure. Eiusmod voluptate amet et elit adipisicing ut. Nulla minim elit anim mollit nisi amet est et magna veniam. Qui deserunt eiusmod laboris ex. Ex aute duis duis incididunt quis adipisicing dolor sit aliqua consectetur eu fugiat. Fugiat ipsum dolor elit ad commodo aliquip anim anim nostrud. Lorem adipisicing ex quis veniam aute amet cupidatat reprehenderit do laborum minim laboris sunt.</p> */}
</section> </section>
); );
@@ -47,8 +54,8 @@ function getAriaLabel(item: WorkplaceEntry): string
if (item.place) if (item.place)
str.push(`at ${item.place}`); str.push(`at ${item.place}`);
if (item.tech) if (item.summary)
return str.join(" ") + `. ${item.tech}`; return str.join(" ") + `. ${item.summary}`;
else else
return str.join(" "); return str.join(" ");
+39 -8
View File
@@ -4,9 +4,16 @@
{ {
@include centerTwo; @include centerTwo;
.listItem .content
{ {
background-position: right; overflow-x: hidden;
gap: $spacingM;
@include flex(column);
.listItem
{
background-position-x: right;
}
} }
.descriptions .descriptions
@@ -16,12 +23,6 @@
overflow-x: visible; overflow-x: visible;
min-height: 760px; min-height: 760px;
@media screen and (max-width: 860px)
{
min-height: unset;
padding-top: calc(56px + $spacingXL);
}
img img
{ {
width: 100%; width: 100%;
@@ -35,6 +36,18 @@
@include slideIn; @include slideIn;
} }
.mobileNav
{
margin-top: $spacingL;
display: none;
gap: $spacingMNudge;
.next
{
flex-grow: 1;
}
}
.projectItem .projectItem
{ {
@include flex(column); @include flex(column);
@@ -96,4 +109,22 @@
{ {
align-self: flex-end; align-self: flex-end;
} }
@media screen and (max-width: 860px)
{
.descriptions
{
min-height: unset;
.mobileNav
{
display: flex;
}
}
.list
{
display: none;
}
}
} }
+43 -18
View File
@@ -5,7 +5,9 @@ import Button from "@/_components/Button";
import links from "@/_data/links"; import links from "@/_data/links";
import projects from "@/_data/projects"; import projects from "@/_data/projects";
import shared from "@/_styles/gallery.module.scss"; import shared from "@/_styles/gallery.module.scss";
import { ArrowRight24Regular } from "@fluentui/react-icons"; import ArrowRight24Regular from "@fluentui/svg-icons/icons/arrow_right_24_regular.svg";
import ChevronLeft24Regular from "@fluentui/svg-icons/icons/chevron_left_24_regular.svg";
import ChevronRight24Regular from "@fluentui/svg-icons/icons/chevron_right_24_regular.svg";
import Image from "next/image"; import Image from "next/image";
import React, { useCallback, useState } from "react"; import React, { useCallback, useState } from "react";
import { networkFor } from "react-social-icons"; import { networkFor } from "react-social-icons";
@@ -23,23 +25,25 @@ const ProjectsSection: React.FC = () =>
return ( return (
<section id="projects" className={ cls.section }> <section id="projects" className={ cls.section }>
<div className={ shared.list }> <div className={ cls.content }>
<h2>My pet projects</h2> <h2>My pet projects</h2>
{ projects.map((project, index) => <div className={ `${shared.list} ${cls.list}` }>
<Button key={ index } type="button" { projects.map((project, index) =>
className={ `${shared.listItem} ${cls.listItem}` } <Button key={ index } type="button"
appearance={ selection === index ? "primary" : "secondary" } className={ `${shared.listItem} ${cls.listItem}` }
data-selected={ selection === index } appearance={ selection === index ? "primary" : "secondary" }
onClick={ () => select(selection == index ? undefined : index) } data-selected={ selection === index }
aria-label={ `"${project.title}". ${project.subtitle}` }> onClick={ () => select(selection == index ? undefined : index) }
aria-label={ `"${project.title}". ${project.subtitle}` }>
<div className={ shared.content }> <div className={ shared.content }>
<span className={ shared.title }>{ project.title }</span> <span className={ shared.title }>{ project.title }</span>
<span>{ project.subtitle }</span> <span>{ project.subtitle }</span>
</div> </div>
</Button> </Button>
) } ) }
</div>
<Button className={ cls.cta } appearance="secondary" href={ links.github } target="_blank" <Button className={ cls.cta } appearance="secondary" href={ links.github } target="_blank"
iconAfter={ <ArrowRight24Regular /> }> iconAfter={ <ArrowRight24Regular /> }>
@@ -51,10 +55,14 @@ const ProjectsSection: React.FC = () =>
<div className={ cls.descriptions } aria-live="polite" aria-atomic> <div className={ cls.descriptions } aria-live="polite" aria-atomic>
{ projects.map((project, index) => { projects.map((project, index) =>
<div key={ index } className={ cls.projectItem } hidden={ selection !== index }> <div key={ index } className={ cls.projectItem } hidden={ selection !== index }>
<Image src={ project.image } alt={ project.title } data-theme={ project.imageDark ? "light" : "both" } /> <Image
src={ project.image } alt={ project.title }
data-theme={ project.imageDark ? "light" : "both" }
loading="eager" />
{/* This is a workaround since not all images can be theme-adaptive */ } {/* This is a workaround since not all images can be theme-adaptive */ }
{ project.imageDark && { project.imageDark &&
<Image src={ project.imageDark } alt="" data-theme="dark" /> <Image src={ project.imageDark } alt="" data-theme="dark" loading="eager" />
} }
<h3>{ project.title }</h3> <h3>{ project.title }</h3>
@@ -80,7 +88,24 @@ const ProjectsSection: React.FC = () =>
</div> </div>
) } ) }
<Image className={ cls.defaultImg } hidden={ selection !== undefined } <Image className={ cls.defaultImg } hidden={ selection !== undefined }
src={ projectsImg.src } alt={ projectsImg.alt } /> src={ projectsImg.src } alt={ projectsImg.alt } loading="eager" />
<div className={ cls.mobileNav }>
<Button type="button"
icon={ <ChevronLeft24Regular /> }
aria-label="Previous project"
disabled={ selection === undefined }
onClick={ () => setSelection(selection! < 1 ? undefined : selection! - 1) } />
{ (selection ?? -1) < projects.length - 1 &&
<Button type="button" className={ cls.next }
icon={ <ChevronRight24Regular /> }
onClick={ () => setSelection((selection ?? -1) + 1) } >
Next project: { projects[(selection ?? -1) + 1].title }
</Button>
}
</div>
</div> </div>
</section> </section>
); );
+106 -12
View File
@@ -9,14 +9,48 @@
.illustrations .illustrations
{ {
justify-self: center; justify-self: center;
position: relative; width: 100%;
img .item
{ {
width: 100%; position: relative;
max-height: 600px; @include flex(column);
gap: $spacingXXXL;
@include slideIn; @include slideIn;
img
{
align-self: flex-end;
max-height: 400px;
width: auto;
max-width: 100%;
height: auto;
}
h3
{
@include subtitle1($fontFamilyBaseAlt);
display: none;
}
p
{
@include subtitle1($fontFamilyBaseAlt);
}
}
.mobileNav
{
margin-top: $spacingM;
display: none;
gap: $spacingMNudge;
.next
{
flex-grow: 1;
background-position-x: right;
}
} }
// [SPECIAL] // [SPECIAL]
@@ -25,28 +59,88 @@
position: absolute; position: absolute;
cursor: pointer; cursor: pointer;
bottom: calc(50% - 20px + 13.5%); right: 214px;
left: 40%; top: 81px;
width: 20%; width: 60px;
height: 40px; height: 25px;
@media screen and (max-width: 1400px) @media screen and (max-width: 573px)
{ {
bottom: calc(50% - 20px + 6vw) right: calc(50% - 30px);
top: calc(15vw - 7px);
} }
} }
// [SPECIAL]
.sus
{
position: absolute;
cursor: pointer;
left: 0;
top: 200px;
width: 90px;
height: 100px;
@media screen and (max-width: 1472px)
{
top: calc(15vw - 20px);
width: calc(8vw - 24px);
height: calc(8vw - 17px);
@media screen and (max-width: 860px)
{
top: calc(35vw - 65px);
width: 12vw;
height: 14vw;
}
}
}
} }
.list .content
{ {
@include flex(column);
gap: $spacingM;
.cta .cta
{ {
align-self: flex-end; align-self: flex-end;
} }
}
@media screen and (max-width: 860px) @media screen and (max-width: 860px)
{
.content
{ {
grid-row: 1; grid-row: 1;
.list
{
display: none;
}
}
.illustrations
{
.mobileNav
{
display: flex;
}
.item
{
h3
{
display: block;
}
p
{
@include subtitle2($fontFamilyBaseAlt);
}
}
} }
} }
} }
+67 -30
View File
@@ -1,13 +1,15 @@
"use client"; "use client";
import Button from "@/_components/Button"; import Button from "@/_components/Button";
import links from "@/_data/links";
import skills from "@/_data/skills"; import skills from "@/_data/skills";
import shared from "@/_styles/gallery.module.scss"; import shared from "@/_styles/gallery.module.scss";
import { ArrowDownload24Regular } from "@fluentui/react-icons"; import ArrowDownload24Regular from "@fluentui/svg-icons/icons/arrow_download_24_regular.svg";
import ChevronLeft24Regular from "@fluentui/svg-icons/icons/chevron_left_24_regular.svg";
import ChevronRight24Regular from "@fluentui/svg-icons/icons/chevron_right_24_regular.svg";
import Image from "next/image"; import Image from "next/image";
import React, { useCallback, useId, useState } from "react"; import React, { useCallback, useId, useState } from "react";
import cls from "./SkillsSection.module.scss"; import cls from "./SkillsSection.module.scss";
import links from "@/_data/links";
const SkillsSection: React.FC = () => const SkillsSection: React.FC = () =>
{ {
@@ -24,39 +26,74 @@ const SkillsSection: React.FC = () =>
<section id="skills" className={ cls.section }> <section id="skills" className={ cls.section }>
<div id={ illustrations } className={ cls.illustrations } aria-live="polite" aria-atomic> <div id={ illustrations } className={ cls.illustrations } aria-live="polite" aria-atomic>
{ skills.map((i, index) => { skills.map((i, index) =>
<Image key={ index } <div key={ index } className={ cls.item } hidden={ selection !== index }>
src={ i.image.src } alt={ i.image.alt } <Image src={ i.image.src } alt={ i.image.alt } loading="eager" />
hidden={ selection !== index } />
<h3>{ i.title }</h3>
<p>{ i.description }</p>
{ selection === 4 &&
// [SPECIAL] It's a surprize tool that will help us later
<div role="button" aria-label="Click me"
className={ cls.whatsThis }
onClick={ () =>
{
window.clarity?.("event", "ngguu");
window.open("https://www.youtube.com/watch?v=dQw4w9WgXcQ");
} } />
}
{ selection === 7 &&
// [SPECIAL] sus
<div role="button" aria-label="Click me"
className={ cls.sus }
onClick={ () =>
{
window.clarity?.("event", "sus");
const track = new Audio("sus.mp3");
track.volume = 0.1;
track.play();
} } />
}
</div>
) } ) }
{ selection === 4 && <div className={ cls.mobileNav }>
// [SPECIAL] It's a surprize tool that will help us later <Button type="button"
<div role="button" aria-label="Click me" icon={ <ChevronLeft24Regular /> }
className={ cls.whatsThis } aria-label="Previous skill"
onClick={ () => disabled={ selection < 1 }
{ onClick={ () => setSelection(selection - 1) } />
window.clarity?.("event", "ngguu");
window.open("https://www.youtube.com/watch?v=dQw4w9WgXcQ"); { selection < skills.length - 1 &&
} } /> <Button type="button" className={ cls.next }
} icon={ <ChevronRight24Regular /> }
onClick={ () => setSelection(selection + 1) } >
Next skill: { skills[selection + 1].title }
</Button>
}
</div>
</div> </div>
<div className={ `${shared.list} ${cls.list}` }> <div className={ cls.content }>
<h2>My skillset</h2> <h2>My skills &amp; tools</h2>
{ skills.map((skill, index) => <div className={ `${shared.list} ${cls.list}` }>
<Button key={ index } type="button" aria-current={ selection === index } aria-controls={ illustrations } { skills.map((skill, index) =>
className={ shared.listItem } appearance={ selection === index ? "primary" : "secondary" } <Button key={ index } type="button" aria-current={ selection === index } aria-controls={ illustrations }
data-selected={ selection === index } className={ shared.listItem } appearance={ selection === index ? "primary" : "secondary" }
onClick={ () => select(index) } data-selected={ selection === index }
aria-label={ `${skill.title} skills. Associated stack: ${skill.description}` } onClick={ () => select(index) }
icon={ <skill.icon /> } > aria-label={ `${skill.title} skills. Associated stack: ${skill.caption}` }
icon={ <skill.icon /> } >
<div className={ shared.content }> <div className={ shared.content }>
<span className={ shared.title }>{ skill.title }</span> <span className={ shared.title }>{ skill.title }</span>
<span>{ skill.description }</span> <span>{ skill.caption }</span>
</div> </div>
</Button> </Button>
) } ) }
</div>
<Button appearance="secondary" className={ cls.cta } <Button appearance="secondary" className={ cls.cta }
as="next" href={ links.resume } as="next" href={ links.resume }
+19 -1
View File
@@ -88,8 +88,26 @@ textarea
@include formBase; @include formBase;
} }
.hl
{
color: $colorNeutralForegroundInverted;
background-color: $colorNeutralBackgroundInverted;
padding: $spacingXXS $spacingXXS;
&::selection
{
color: $colorNeutralForegroundInverted;
background-color: $colorBrandForeground1;
}
}
svg
{
fill: currentColor;
}
// [SPECIAL] case for 404 page // [SPECIAL] case for 404 page
main.not-found + footer > .illustration body:has(.not-found) footer .illustration
{ {
display: none; display: none;
} }
+2 -8
View File
@@ -12,18 +12,12 @@ export const rejectCookies = (): void =>
window.clarity?.("consent", false); window.clarity?.("consent", false);
}; };
export const dismissCookies = (): void => export const getCookieChoice = (): "accepted" | "rejected" | "none" =>
{
setCookie("CC", "", 1209600); // 14 days
};
export const getCookieChoice = (): "accepted" | "rejected" | "acknowledged" | "none" =>
{ {
switch (getCookie("CC")) switch (getCookie("CC"))
{ {
case "1": return "accepted"; case "1": return "accepted";
case "0": return "rejected"; case "0": return "rejected";
case "": return "acknowledged";
default: return "none"; default: return "none";
} }
}; };
@@ -41,7 +35,7 @@ function getCookie(name: string): string | undefined
for (const cookie of cookies) for (const cookie of cookies)
if (cookie.trim().startsWith(cookieName)) if (cookie.trim().startsWith(cookieName))
return cookie.substring(cookieName.length); return cookie.trim().substring(cookieName.length);
return undefined; return undefined;
} }
-10
View File
@@ -9,13 +9,3 @@ export const analyticsEnabled = (): boolean =>
unstable_noStore(); unstable_noStore();
return !!process.env.CLARITY_ID; return !!process.env.CLARITY_ID;
}; };
/**
* Check if Clarity requires explicit consent
* @returns true if Clarity requires explicit consent
*/
export const requireExplicitConsent = (): boolean =>
{
unstable_noStore();
return process.env.CLARITY_CONSENT === "1";
};
+2 -2
View File
@@ -29,9 +29,9 @@ export async function verifyTurnstile(token: string): Promise<[false, TurnstileE
const result: TurnstileValidationResponse = await response.json(); const result: TurnstileValidationResponse = await response.json();
if (result.success) if (result.success)
return [result.success]; return [true];
else else
return [result.success, result["error-codes"][0]]; return [false, result["error-codes"][0]];
} }
export type TurnstileValidationResponse = export type TurnstileValidationResponse =
+12 -13
View File
@@ -3,8 +3,9 @@ import Button from "@/_components/Button";
import RevokeConsentButton from "@/_components/RevokeConsentButton"; import RevokeConsentButton from "@/_components/RevokeConsentButton";
import { canonicalName, getTitle } from "@/_data/metadata"; import { canonicalName, getTitle } from "@/_data/metadata";
import ThirdPartyAttribution from "@/_data/ThirdPartyAttributiont"; import ThirdPartyAttribution from "@/_data/ThirdPartyAttributiont";
import { analyticsEnabled, requireExplicitConsent } from "@/_utils/analytics/server"; import { analyticsEnabled } from "@/_utils/analytics/server";
import { ArrowLeft24Regular, ArrowRight24Regular } from "@fluentui/react-icons"; import ArrowLeft24Regular from "@fluentui/svg-icons/icons/arrow_left_24_regular.svg";
import ArrowRight24Regular from "@fluentui/svg-icons/icons/arrow_right_24_regular.svg";
import { Metadata } from "next"; import { Metadata } from "next";
import { unstable_noStore } from "next/cache"; import { unstable_noStore } from "next/cache";
import React from "react"; import React from "react";
@@ -45,17 +46,15 @@ const AttributionPage: React.FC = () => (
If the &quot;Do Not Track&quot; option is enabled in your browser, If the &quot;Do Not Track&quot; option is enabled in your browser,
the website will not execute any tracking code. the website will not execute any tracking code.
</p> </p>
{ requireExplicitConsent() && <p>
<p> If you previously gave your consent to use cookies,
If you previously gave your consent to use cookies, you can revoke it by clicking &quot;Revoke my consent&quot; button on this page below
you can revoke it by clicking &quot;Revoke my consent&quot; button on this page below (the button is available only if the consent was given).
(the button is available only if the consent was given). Recorded data will be deleted after 30-day retention period.
Recorded data will be deleted after 30-day retention period. </p>
</p>
}
<div className={ cls.buttonRow }> <div className={ cls.buttonRow }>
{ requireExplicitConsent() && <RevokeConsentButton /> } <RevokeConsentButton />
<Button appearance="secondary" <Button appearance="secondary"
href="https://learn.microsoft.com/clarity/faq#privacy" target="_blank" href="https://learn.microsoft.com/clarity/faq#privacy" target="_blank"
iconAfter={ <ArrowRight24Regular /> }> iconAfter={ <ArrowRight24Regular /> }>
@@ -72,10 +71,10 @@ const AttributionPage: React.FC = () => (
Copyright &copy; { new Date().getFullYear() } { Package.author.name }. Some rights reserved. Copyright &copy; { new Date().getFullYear() } { Package.author.name }. Some rights reserved.
</p> </p>
<p> <p>
Text and graphical material of this website is a subject to general copyright law. You must obtain written permission from the author to use any copyrighted material. Text and graphical materials of this website are a subject to general copyright law. You must obtain a written permission from the author to use any copyrighted materials.
</p> </p>
<p> <p>
You may use copyrighted material without excplicit permission in following cases: You may use copyrighted materials without excplicit permission in following cases:
</p> </p>
<ul> <ul>
<li>Educational purposes.</li> <li>Educational purposes.</li>
+2 -2
View File
@@ -5,7 +5,7 @@ import { PropsWithChildren } from "react";
import CookieBanner from "./_components/CookieBanner"; import CookieBanner from "./_components/CookieBanner";
import Footer from "./_components/Footer"; import Footer from "./_components/Footer";
import Header from "./_components/Header"; import Header from "./_components/Header";
import { analyticsEnabled, requireExplicitConsent } from "./_utils/analytics/server"; import { analyticsEnabled } from "./_utils/analytics/server";
import fonts from "./fonts"; import fonts from "./fonts";
import "./_styles/globals.scss"; import "./_styles/globals.scss";
@@ -28,7 +28,7 @@ export default function RootLayout(props: PropsWithChildren)
} }
<body> <body>
{ analyticsEnabled() && { analyticsEnabled() &&
<CookieBanner askForConsent={ requireExplicitConsent() } /> <CookieBanner />
} }
<Header /> <Header />
+3 -3
View File
@@ -4,9 +4,9 @@ import { spinnerDark, spinnerLight } from "./_assets/illustrations";
import cls from "./loading.module.scss"; import cls from "./loading.module.scss";
const LoadingPage: React.FC = () => ( const LoadingPage: React.FC = () => (
<div className={ cls.root } role="alert" aria-label="Loading page"> <div className={ `not-found ${cls.root}` } role="alert" aria-label="Loading page">
<Image className={ cls.dark } src={ spinnerDark.src } alt={ spinnerDark.alt } priority unoptimized /> <Image className={ cls.dark } src={ spinnerDark.src } alt={ spinnerDark.alt } loading="eager" unoptimized />
<Image className={ cls.light } src={ spinnerLight.src } alt={ spinnerLight.alt } priority unoptimized /> <Image className={ cls.light } src={ spinnerLight.src } alt={ spinnerLight.alt } loading="eager" unoptimized />
</div> </div>
); );
+2 -2
View File
@@ -1,5 +1,5 @@
import { textCorrection } from "@/_assets/decorations"; import { textCorrection } from "@/_assets/decorations";
import { Home24Regular } from "@fluentui/react-icons"; import Home24Regular from "@fluentui/svg-icons/icons/home_24_regular.svg";
import { Metadata } from "next"; import { Metadata } from "next";
import { unstable_noStore } from "next/cache"; import { unstable_noStore } from "next/cache";
import Image from "next/image"; import Image from "next/image";
@@ -24,7 +24,7 @@ const NotFoundPage: React.FC = () => (
<main className={ `${cls.page} not-found` }> <main className={ `${cls.page} not-found` }>
<div className={ cls.illustration }> <div className={ cls.illustration }>
<h1>404...</h1> <h1>404...</h1>
<Image src={ notFoundImage.src } alt={ notFoundImage.alt } priority /> <Image src={ notFoundImage.src } alt={ notFoundImage.alt } loading="eager" />
</div> </div>
<div className={ cls.content }> <div className={ cls.content }>
<div className={ cls.caption }> <div className={ cls.caption }>
+3 -3
View File
@@ -16,10 +16,10 @@ const HomePage: React.FC = () => (
<article> <article>
<FrontSection /> <FrontSection />
<SkillsSection />
<ProjectsSection />
<ExperienceSection />
<AboutSection /> <AboutSection />
<SkillsSection />
<ExperienceSection />
<ProjectsSection />
<ContactSection /> <ContactSection />
</article> </article>
</main> </main>
+8 -4
View File
@@ -5,18 +5,22 @@ import { PDFDocument, PDFPage } from "pdf-lib";
export async function GET(req: NextRequest): Promise<Response> export async function GET(req: NextRequest): Promise<Response>
{ {
const type: string | null = req.nextUrl.searchParams.get("type"); const type: string | null = req.nextUrl.searchParams.get("type");
const isAts: boolean = req.nextUrl.searchParams.get("ats") === "true";
const resume: Resume | undefined = findResume(type); const resume: Resume | undefined = findResume(type);
const url: string | undefined = isAts ? process.env.ATS_RESUME_URL : process.env.RESUME_URL;
if (!resume) if (!resume)
return error(400, "'type' parameter is invalid"); return error(400, "'type' parameter is invalid");
if (!process.env.RESUME_URL) const fileName: string = (isAts ? "(ATS) " + resume.fileName : resume.fileName).replaceAll("\"", "'");
if (!url)
return error(500, "Cannot find file location."); return error(500, "Cannot find file location.");
try try
{ {
// Fetch the PDF file from the remote URL using the fetch API // Fetch the PDF file from the remote URL using the fetch API
const response: Response = await fetch(process.env.RESUME_URL as string); const response: Response = await fetch(url);
if (!response.ok) if (!response.ok)
return error(500, "Failed to fetch PDF file"); return error(500, "Failed to fetch PDF file");
@@ -30,7 +34,7 @@ export async function GET(req: NextRequest): Promise<Response>
const [page, refs]: PDFPage[] = await newDoc.copyPages(srcDoc, [resume.pageIndex, srcDoc.getPageCount() - 1]); const [page, refs]: PDFPage[] = await newDoc.copyPages(srcDoc, [resume.pageIndex, srcDoc.getPageCount() - 1]);
newDoc.addPage(page); newDoc.addPage(page);
if (process.env.RESUME_HAS_REFS === "true") if (process.env.RESUME_HAS_REFS === "true" && isAts)
newDoc.addPage(refs); newDoc.addPage(refs);
// Serialize the new PDF document // Serialize the new PDF document
@@ -43,7 +47,7 @@ export async function GET(req: NextRequest): Promise<Response>
// Set response headers for PDF file // Set response headers for PDF file
headers: { headers: {
"Content-Type": "application/pdf", "Content-Type": "application/pdf",
"Content-Disposition": `inline; filename="${resume.fileName.replaceAll("\"", "'")}.pdf"` "Content-Disposition": `inline; filename="${fileName}.pdf"`
} }
} }
); );
+10
View File
@@ -20,6 +20,16 @@
grid-auto-columns: 1fr; grid-auto-columns: 1fr;
gap: $spacingXL; gap: $spacingXL;
.buttonContainer
{
@include flex(column);
}
.atsLink
{
@include body1();
}
.button .button
{ {
flex-flow: column; flex-flow: column;
+15 -8
View File
@@ -21,15 +21,22 @@ const ResumePage: React.FC = () => (
<h1>Who are you looking for?</h1> <h1>Who are you looking for?</h1>
<div className={ cls.resumeButtons }> <div className={ cls.resumeButtons }>
{ resumeList.map(i => { resumeList.map(i =>
<Button key={ i.key } className={ cls.button } <div key={ i.key } className={ cls.buttonContainer }>
href={ `/resume/download?type=${i.key}` } download <Button className={ cls.button }
icon={ href={ `/resume/download?type=${i.key}` } download
<Image className={ cls.image } src={ i.image.src } priority draggable={ false } icon={
aria-hidden alt={ i.image.alt } /> <Image className={ cls.image } src={ i.image.src } loading="eager" draggable={ false }
}> aria-hidden alt={ i.image.alt } />
}>
{ i.label } { i.label }
</Button> </Button>
{ process.env.ATS_RESUME_URL &&
<a className={ cls.atsLink } href={ `/resume/download?type=${i.key}&ats=true` } download>
ATS-compatible version
</a>
}
</div>
) } ) }
</div> </div>
+35 -34
View File
@@ -1,36 +1,37 @@
import { FlatCompat } from "@eslint/eslintrc"; import { defineConfig, globalIgnores } from "eslint/config";
import js from "@eslint/js"; import nextVitals from "eslint-config-next/core-web-vitals";
import nextTs from "eslint-config-next/typescript";
const compat = new FlatCompat({
baseDirectory: import.meta.dirname,
recommendedConfig: js.configs.recommended
});
const eslintConfig =
[
...compat.config({
extends: ["eslint:recommended", "next/core-web-vitals", "next/typescript"],
rules:
{
"@typescript-eslint/no-explicit-any": ["off"],
"@typescript-eslint/no-unused-vars": ["warn"],
"indent": [
"warn",
"tab",
{
"SwitchCase": 1
}
],
"quotes": [
"error",
"double"
],
"semi": [
"error",
"always"
],
}
})
];
const eslintConfig = defineConfig([
...nextVitals,
...nextTs,
globalIgnores([
".next/**",
"out/**",
"build/**",
"next-env.d.ts"
]),
{
rules:
{
"@typescript-eslint/no-explicit-any": ["off"],
"@typescript-eslint/no-unused-vars": ["warn"],
"indent": [
"warn",
"tab",
{
"SwitchCase": 1
}
],
"quotes": [
"error",
"double"
],
"semi": [
"error",
"always"
],
}
}
]);
export default eslintConfig; export default eslintConfig;
+45 -1
View File
@@ -28,6 +28,50 @@ const nextConfig = {
] ]
} }
]; ];
},
turbopack:
{
rules:
{
"*.svg":
{
condition:
{
// apply only for @fluentui/svg-icons package
path: /node_modules[\\/]@fluentui[\\/]svg-icons[\\/]/
},
as: "*.js",
loaders:
[
{
loader: "@svgr/webpack",
options:
{
icon: true,
expandProps: true,
svgoConfig:
{
plugins:
[
{
name: "preset-default",
params:
{
overrides:
{
cleanupIds: true,
removeViewBox: false
}
}
}
]
}
}
}
]
}
}
} }
}; };
@@ -51,7 +95,7 @@ function generateCspPolicy(isDev)
"manifest-src": "'self'", "manifest-src": "'self'",
"media-src": "'self'", "media-src": "'self'",
"object-src": "'none'", "object-src": "'none'",
"script-src": "'self' https://*.clarity.ms https://c.bing.com https://*.cloudflare.com 'unsafe-inline'", "script-src": "'self' https://*.clarity.ms https://c.bing.com https://*.cloudflare.com https://*.cloudflareinsights.com 'unsafe-inline'",
"style-src": "'self' 'unsafe-inline'", "style-src": "'self' 'unsafe-inline'",
"worker-src": "'self'" "worker-src": "'self'"
}; };
+13050
View File
File diff suppressed because it is too large Load Diff
+30 -23
View File
@@ -1,6 +1,6 @@
{ {
"name": "my-website", "name": "my-website",
"version": "1.0.0", "version": "0.0.0",
"private": true, "private": true,
"homepage": "https://xfox111.net", "homepage": "https://xfox111.net",
"license": "(MIT with exception)", "license": "(MIT with exception)",
@@ -18,33 +18,40 @@
"dev": "next dev", "dev": "next dev",
"build": "next build", "build": "next build",
"start": "next start", "start": "next start",
"lint": "next lint" "lint": "eslint ."
}, },
"dependencies": { "dependencies": {
"@fluentui/react-icons": "^2.0.298", "@fluentui/svg-icons": "^1.1.328",
"next": "^15.3.1", "next": "^16.2.7",
"nodemailer": "^7.0.0", "nodemailer": "^8.0.10",
"pdf-lib": "^1.17.1", "pdf-lib": "^1.17.1",
"react": "^19.1.0", "react": "^19.2.7",
"react-dom": "^19.1.0", "react-dom": "^19.2.7",
"react-social-icons": "^6.24.0", "react-social-icons": "^6.26.0",
"react-turnstile": "^1.1.4", "react-turnstile": "^1.1.5",
"sharp": "^0.34.1", "sharp": "^0.34.5",
"zod": "^3.24.3" "zod": "^4.4.3"
}, },
"devDependencies": { "devDependencies": {
"@next/eslint-plugin-next": "^15.3.1", "@next/eslint-plugin-next": "^16.2.7",
"@types/node": "^22.15.3", "@svgr/webpack": "^8.1.0",
"@types/nodemailer": "^6.4.17", "@types/node": "^25.9.1",
"@types/react": "^19.1.2", "@types/nodemailer": "^8.0.0",
"@types/react-dom": "^19.1.3", "@types/react": "^19.2.16",
"eslint": "^9.19.0", "@types/react-dom": "^19.2.3",
"eslint-config-next": "^15.3.1", "eslint": "^9.39.1",
"sass": "^1.87.0", "eslint-config-next": "^16.2.7",
"typescript": "^5.8.3", "sass": "^1.100.0",
"typescript-eslint": "^8.31.1" "typescript": "^6.0.3",
"typescript-eslint": "^8.60.1"
}, },
"resolutions": { "overrides": {
"react": "^19.0.0" "next": {
"postcss": "^8.5.10"
}
},
"allowScripts": {
"sharp": true,
"@parcel/watcher": true
} }
} }
+6 -3
View File
@@ -34,10 +34,13 @@
if (!id || navigator.doNotTrack === "1") if (!id || navigator.doNotTrack === "1")
return; return;
window["clarity"] ??= function () // @ts-expect-error -- Clarity adds itself to the window object
window.clarity ??= function ()
{ {
window["clarity"].q ??= []; // @ts-expect-error -- Clarity adds itself to the window object
window["clarity"].q.push(arguments); window.clarity.q ??= [];
// @ts-expect-error -- Clarity adds itself to the window object
window.clarity.q.push(arguments);
}; };
/** @type {HTMLScriptElement} */ /** @type {HTMLScriptElement} */
BIN
View File
Binary file not shown.
+3 -2
View File
@@ -15,7 +15,7 @@
"moduleResolution": "bundler", "moduleResolution": "bundler",
"resolveJsonModule": true, "resolveJsonModule": true,
"isolatedModules": true, "isolatedModules": true,
"jsx": "preserve", "jsx": "react-jsx",
"incremental": true, "incremental": true,
"plugins": [ "plugins": [
{ {
@@ -32,7 +32,8 @@
"next-env.d.ts", "next-env.d.ts",
"**/*.ts", "**/*.ts",
"**/*.tsx", "**/*.tsx",
".next/types/**/*.ts" ".next/types/**/*.ts",
".next/dev/types/**/*.ts"
], ],
"exclude": [ "exclude": [
"node_modules" "node_modules"
-3554
View File
File diff suppressed because it is too large Load Diff