Compare commits
37 Commits
master
...
PROD-v1.0.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b83c7a7d6d | ||
|
|
609940cafe | ||
|
|
49e1bcac81 | ||
|
|
1fdf7516a5 | ||
|
|
d5c4a99281 | ||
|
|
e785ea0ea6 | ||
|
|
cd89d07f70 | ||
|
|
3ade4d1bd1 | ||
|
|
120fc26d01 | ||
|
|
a55a295164 | ||
|
|
e616a400ed | ||
|
|
8acf22a953 | ||
|
|
295c15f03b | ||
|
|
ee5daffdba | ||
|
|
3849e2d0dc | ||
|
|
46e5797d85 | ||
|
|
43ddc32e17 | ||
|
|
40793eceab | ||
|
|
4d2b176816 | ||
|
|
85ab22d566 | ||
|
|
97520d404a | ||
|
|
225c0654cc | ||
|
|
00f4158d57 | ||
|
|
f2c2b55cb1 | ||
|
|
24c382d520 | ||
|
|
128d87636a | ||
|
|
54083e4233 | ||
|
|
fe14d9f790 | ||
|
|
6f76ba2f6e | ||
|
|
0643d4fb08 | ||
|
|
7e0cd37851 | ||
|
|
e378e7fa11 | ||
|
|
1a862b1efc | ||
|
|
9d25fbc935 | ||
|
|
c03360713f | ||
|
|
ae2b3b106a | ||
|
|
70f799ea73 |
23
.claude/commands/openspec/apply.md
Normal file
23
.claude/commands/openspec/apply.md
Normal file
@ -0,0 +1,23 @@
|
||||
---
|
||||
name: OpenSpec: Apply
|
||||
description: Implement an approved OpenSpec change and keep tasks in sync.
|
||||
category: OpenSpec
|
||||
tags: [openspec, apply]
|
||||
---
|
||||
<!-- OPENSPEC:START -->
|
||||
**Guardrails**
|
||||
- Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
|
||||
- Keep changes tightly scoped to the requested outcome.
|
||||
- Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
|
||||
|
||||
**Steps**
|
||||
Track these steps as TODOs and complete them one by one.
|
||||
1. Read `changes/<id>/proposal.md`, `design.md` (if present), and `tasks.md` to confirm scope and acceptance criteria.
|
||||
2. Work through tasks sequentially, keeping edits minimal and focused on the requested change.
|
||||
3. Confirm completion before updating statuses—make sure every item in `tasks.md` is finished.
|
||||
4. Update the checklist after all work is done so each task is marked `- [x]` and reflects reality.
|
||||
5. Reference `openspec list` or `openspec show <item>` when additional context is required.
|
||||
|
||||
**Reference**
|
||||
- Use `openspec show <id> --json --deltas-only` if you need additional context from the proposal while implementing.
|
||||
<!-- OPENSPEC:END -->
|
||||
21
.claude/commands/openspec/archive.md
Normal file
21
.claude/commands/openspec/archive.md
Normal file
@ -0,0 +1,21 @@
|
||||
---
|
||||
name: OpenSpec: Archive
|
||||
description: Archive a deployed OpenSpec change and update specs.
|
||||
category: OpenSpec
|
||||
tags: [openspec, archive]
|
||||
---
|
||||
<!-- OPENSPEC:START -->
|
||||
**Guardrails**
|
||||
- Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
|
||||
- Keep changes tightly scoped to the requested outcome.
|
||||
- Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
|
||||
|
||||
**Steps**
|
||||
1. Identify the requested change ID (via the prompt or `openspec list`).
|
||||
2. Run `openspec archive <id> --yes` to let the CLI move the change and apply spec updates without prompts (use `--skip-specs` only for tooling-only work).
|
||||
3. Review the command output to confirm the target specs were updated and the change landed in `changes/archive/`.
|
||||
4. Validate with `openspec validate --strict` and inspect with `openspec show <id>` if anything looks off.
|
||||
|
||||
**Reference**
|
||||
- Inspect refreshed specs with `openspec list --specs` and address any validation issues before handing off.
|
||||
<!-- OPENSPEC:END -->
|
||||
27
.claude/commands/openspec/proposal.md
Normal file
27
.claude/commands/openspec/proposal.md
Normal file
@ -0,0 +1,27 @@
|
||||
---
|
||||
name: OpenSpec: Proposal
|
||||
description: Scaffold a new OpenSpec change and validate strictly.
|
||||
category: OpenSpec
|
||||
tags: [openspec, change]
|
||||
---
|
||||
<!-- OPENSPEC:START -->
|
||||
**Guardrails**
|
||||
- Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
|
||||
- Keep changes tightly scoped to the requested outcome.
|
||||
- Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
|
||||
- Identify any vague or ambiguous details and ask the necessary follow-up questions before editing files.
|
||||
|
||||
**Steps**
|
||||
1. Review `openspec/project.md`, run `openspec list` and `openspec list --specs`, and inspect related code or docs (e.g., via `rg`/`ls`) to ground the proposal in current behaviour; note any gaps that require clarification.
|
||||
2. Choose a unique verb-led `change-id` and scaffold `proposal.md`, `tasks.md`, and `design.md` (when needed) under `openspec/changes/<id>/`.
|
||||
3. Map the change into concrete capabilities or requirements, breaking multi-scope efforts into distinct spec deltas with clear relationships and sequencing.
|
||||
4. Capture architectural reasoning in `design.md` when the solution spans multiple systems, introduces new patterns, or demands trade-off discussion before committing to specs.
|
||||
5. Draft spec deltas in `changes/<id>/specs/<capability>/spec.md` (one folder per capability) using `## ADDED|MODIFIED|REMOVED Requirements` with at least one `#### Scenario:` per requirement and cross-reference related capabilities when relevant.
|
||||
6. Draft `tasks.md` as an ordered list of small, verifiable work items that deliver user-visible progress, include validation (tests, tooling), and highlight dependencies or parallelizable work.
|
||||
7. Validate with `openspec validate <id> --strict` and resolve every issue before sharing the proposal.
|
||||
|
||||
**Reference**
|
||||
- Use `openspec show <id> --json --deltas-only` or `openspec show <spec> --type spec` to inspect details when validation fails.
|
||||
- Search existing requirements with `rg -n "Requirement:|Scenario:" openspec/specs` before writing new ones.
|
||||
- Explore the codebase with `rg <keyword>`, `ls`, or direct file reads so proposals align with current implementation realities.
|
||||
<!-- OPENSPEC:END -->
|
||||
1
.env.local
Normal file
1
.env.local
Normal file
@ -0,0 +1 @@
|
||||
NEXT_PUBLIC_API_URL=http://localhost:8000/api
|
||||
1
.env.production
Normal file
1
.env.production
Normal file
@ -0,0 +1 @@
|
||||
NEXT_PUBLIC_API_URL=https://portfolio-host.com/api
|
||||
70
.gitea/workflows/deploy-alpha.yml
Normal file
70
.gitea/workflows/deploy-alpha.yml
Normal file
@ -0,0 +1,70 @@
|
||||
name: Build and Deploy to k3s
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'PRE_ALPHA*'
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
env:
|
||||
KUBECONFIG: ~/.kube/config
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '22'
|
||||
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build Angular app
|
||||
run: npm run build --prod
|
||||
|
||||
- name: Build Docker image
|
||||
run: |
|
||||
docker build -t ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend:${{ github.sha }} .
|
||||
docker tag ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend:${{ github.sha }} ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend:latest
|
||||
|
||||
- name: Login to Container Registry
|
||||
run: echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ secrets.REGISTRY_URL }} -u "${{ secrets.REGISTRY_USER }}" --password-stdin
|
||||
|
||||
- name: Push Docker image
|
||||
run: |
|
||||
docker push ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend:${{ github.sha }}
|
||||
docker push ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend:latest
|
||||
|
||||
- name: Setup kubectl
|
||||
uses: azure/setup-kubectl@v3
|
||||
with:
|
||||
version: 'latest'
|
||||
|
||||
- name: Configure kubectl
|
||||
run: |
|
||||
mkdir -p ~/.kube
|
||||
echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > ~/.kube/config
|
||||
chmod 600 ~/.kube/config
|
||||
|
||||
- name: Check Config
|
||||
run: |
|
||||
cat ~/.kube/config
|
||||
|
||||
- name: Validate kubeconfig
|
||||
run: |
|
||||
if ! kubectl version --client && kubectl cluster-info --kubeconfig ~/.kube/config; then
|
||||
echo "❌ Failed to connect to cluster"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
- name: Deploy to k3s
|
||||
run: |
|
||||
kubectl apply -k deploy/k3s/alpha --kubeconfig ~/.kube/config
|
||||
kubectl set image deployment/hosting-frontend \
|
||||
hosting-frontend=${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend:${{ github.sha }} \
|
||||
-n hosting-alpha --kubeconfig ~/.kube/config
|
||||
kubectl rollout status deployment/hosting-frontend -n hosting-alpha --kubeconfig ~/.kube/config
|
||||
67
.gitea/workflows/deploy-prod.yml
Normal file
67
.gitea/workflows/deploy-prod.yml
Normal file
@ -0,0 +1,67 @@
|
||||
name: Build and Deploy to k3s
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'PROD*'
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
env:
|
||||
KUBECONFIG: ~/.kube/config
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '22'
|
||||
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build Angular app
|
||||
run: npm run build --prod
|
||||
|
||||
- name: Build Docker image
|
||||
run: |
|
||||
docker build -t ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend-prod:${{ github.sha }} .
|
||||
docker tag ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend-prod:${{ github.sha }} ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend-prod:latest
|
||||
|
||||
- name: Login to Container Registry
|
||||
run: echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ secrets.REGISTRY_URL }} -u "${{ secrets.REGISTRY_USER }}" --password-stdin
|
||||
|
||||
- name: Push Docker image
|
||||
run: |
|
||||
docker push ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend-prod:${{ github.sha }}
|
||||
docker push ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend-prod:latest
|
||||
|
||||
- name: Setup kubectl
|
||||
uses: azure/setup-kubectl@v3
|
||||
with:
|
||||
version: 'latest'
|
||||
|
||||
- name: Configure kubectl
|
||||
run: |
|
||||
mkdir -p ~/.kube
|
||||
echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > ~/.kube/config
|
||||
chmod 600 ~/.kube/config
|
||||
|
||||
|
||||
- name: Validate kubeconfig
|
||||
run: |
|
||||
if ! kubectl version --client && kubectl cluster-info --kubeconfig ~/.kube/config; then
|
||||
echo "❌ Failed to connect to cluster"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
- name: Deploy to k3s
|
||||
run: |
|
||||
kubectl apply -k deploy/k3s/prod --kubeconfig ~/.kube/config
|
||||
kubectl set image deployment/hosting-frontend \
|
||||
hosting-frontend=${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend-prod:${{ github.sha }} \
|
||||
-n hosting --kubeconfig ~/.kube/config
|
||||
kubectl rollout status deployment/hosting-frontend -n hosting --kubeconfig ~/.kube/config
|
||||
15
.next/app-build-manifest.json
Normal file
15
.next/app-build-manifest.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"pages": {
|
||||
"/layout": [
|
||||
"static/chunks/webpack.js",
|
||||
"static/chunks/main-app.js",
|
||||
"static/css/app/layout.css",
|
||||
"static/chunks/app/layout.js"
|
||||
],
|
||||
"/page": [
|
||||
"static/chunks/webpack.js",
|
||||
"static/chunks/main-app.js",
|
||||
"static/chunks/app/page.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
20
.next/build-manifest.json
Normal file
20
.next/build-manifest.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"polyfillFiles": [
|
||||
"static/chunks/polyfills.js"
|
||||
],
|
||||
"devFiles": [],
|
||||
"ampDevFiles": [],
|
||||
"lowPriorityFiles": [
|
||||
"static/development/_buildManifest.js",
|
||||
"static/development/_ssgManifest.js"
|
||||
],
|
||||
"rootMainFiles": [
|
||||
"static/chunks/webpack.js",
|
||||
"static/chunks/main-app.js"
|
||||
],
|
||||
"rootMainFilesTree": {},
|
||||
"pages": {
|
||||
"/_app": []
|
||||
},
|
||||
"ampFirstPages": []
|
||||
}
|
||||
1
.next/cache/.previewinfo
vendored
Normal file
1
.next/cache/.previewinfo
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"previewModeId":"dc559f34b2cfb8e471f5cf7c4303e624","previewModeSigningKey":"cbfcb5c64d2055dbda1bfdbc6833ad47f57d6fb250a5de05c1dc43c23f26d6b1","previewModeEncryptionKey":"0ac99f44e54b21dc78776676abda88910973e01c15da70460817db51a4491fdd","expireAt":1761863112139}
|
||||
1
.next/cache/.rscinfo
vendored
Normal file
1
.next/cache/.rscinfo
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"encryption.key":"UJCuqkc43Q1Tu8qgslshb0xL4QAUycNhcPIjjC8lUyo=","encryption.expire_at":1761863112040}
|
||||
1
.next/cache/.tsbuildinfo
vendored
Normal file
1
.next/cache/.tsbuildinfo
vendored
Normal file
File diff suppressed because one or more lines are too long
1
.next/cache/next-devtools-config.json
vendored
Normal file
1
.next/cache/next-devtools-config.json
vendored
Normal file
@ -0,0 +1 @@
|
||||
{}
|
||||
BIN
.next/cache/webpack/client-development/0.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development/0.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development/1.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development/1.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development/index.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development/index.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development/index.pack.gz.old
vendored
Normal file
BIN
.next/cache/webpack/client-development/index.pack.gz.old
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-production/0.pack
vendored
Normal file
BIN
.next/cache/webpack/client-production/0.pack
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-production/1.pack
vendored
Normal file
BIN
.next/cache/webpack/client-production/1.pack
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-production/2.pack
vendored
Normal file
BIN
.next/cache/webpack/client-production/2.pack
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-production/3.pack
vendored
Normal file
BIN
.next/cache/webpack/client-production/3.pack
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-production/4.pack
vendored
Normal file
BIN
.next/cache/webpack/client-production/4.pack
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-production/5.pack
vendored
Normal file
BIN
.next/cache/webpack/client-production/5.pack
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-production/6.pack
vendored
Normal file
BIN
.next/cache/webpack/client-production/6.pack
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-production/index.pack
vendored
Normal file
BIN
.next/cache/webpack/client-production/index.pack
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-production/index.pack.old
vendored
Normal file
BIN
.next/cache/webpack/client-production/index.pack.old
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/edge-server-production/0.pack
vendored
Normal file
BIN
.next/cache/webpack/edge-server-production/0.pack
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/edge-server-production/1.pack
vendored
Normal file
BIN
.next/cache/webpack/edge-server-production/1.pack
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/edge-server-production/index.pack
vendored
Normal file
BIN
.next/cache/webpack/edge-server-production/index.pack
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/edge-server-production/index.pack.old
vendored
Normal file
BIN
.next/cache/webpack/edge-server-production/index.pack.old
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/0.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/0.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/index.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/index.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-production/0.pack
vendored
Normal file
BIN
.next/cache/webpack/server-production/0.pack
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-production/1.pack
vendored
Normal file
BIN
.next/cache/webpack/server-production/1.pack
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-production/2.pack
vendored
Normal file
BIN
.next/cache/webpack/server-production/2.pack
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-production/3.pack
vendored
Normal file
BIN
.next/cache/webpack/server-production/3.pack
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-production/4.pack
vendored
Normal file
BIN
.next/cache/webpack/server-production/4.pack
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-production/5.pack
vendored
Normal file
BIN
.next/cache/webpack/server-production/5.pack
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-production/index.pack
vendored
Normal file
BIN
.next/cache/webpack/server-production/index.pack
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-production/index.pack.old
vendored
Normal file
BIN
.next/cache/webpack/server-production/index.pack.old
vendored
Normal file
Binary file not shown.
1
.next/package.json
Normal file
1
.next/package.json
Normal file
@ -0,0 +1 @@
|
||||
{"type": "commonjs"}
|
||||
11
.next/prerender-manifest.json
Normal file
11
.next/prerender-manifest.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": 4,
|
||||
"routes": {},
|
||||
"dynamicRoutes": {},
|
||||
"notFoundRoutes": [],
|
||||
"preview": {
|
||||
"previewModeId": "b519e1f670f54aba65a44541ac258fa1",
|
||||
"previewModeSigningKey": "357de2109d161118a84c195d2910555373bfa1683d172ae54a76574b720b4802",
|
||||
"previewModeEncryptionKey": "85cbb6533f9cf3ef2e23ca4286fc7869149638eadc425c8a643447926c624384"
|
||||
}
|
||||
}
|
||||
1
.next/react-loadable-manifest.json
Normal file
1
.next/react-loadable-manifest.json
Normal file
@ -0,0 +1 @@
|
||||
{}
|
||||
1
.next/routes-manifest.json
Normal file
1
.next/routes-manifest.json
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"caseSensitive":false,"basePath":"","rewrites":{"beforeFiles":[],"afterFiles":[],"fallback":[]},"redirects":[{"source":"/:path+/","destination":"/:path+","permanent":true,"internal":true,"regex":"^(?:\\/((?:[^\\/]+?)(?:\\/(?:[^\\/]+?))*))\\/$"}],"headers":[]}
|
||||
3
.next/server/app-paths-manifest.json
Normal file
3
.next/server/app-paths-manifest.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"/page": "app/page.js"
|
||||
}
|
||||
316
.next/server/app/page.js
Normal file
316
.next/server/app/page.js
Normal file
File diff suppressed because one or more lines are too long
1
.next/server/app/page_client-reference-manifest.js
Normal file
1
.next/server/app/page_client-reference-manifest.js
Normal file
File diff suppressed because one or more lines are too long
1
.next/server/interception-route-rewrite-manifest.js
Normal file
1
.next/server/interception-route-rewrite-manifest.js
Normal file
@ -0,0 +1 @@
|
||||
self.__INTERCEPTION_ROUTE_REWRITE_MANIFEST="[]"
|
||||
22
.next/server/middleware-build-manifest.js
Normal file
22
.next/server/middleware-build-manifest.js
Normal file
@ -0,0 +1,22 @@
|
||||
globalThis.__BUILD_MANIFEST = {
|
||||
"polyfillFiles": [
|
||||
"static/chunks/polyfills.js"
|
||||
],
|
||||
"devFiles": [],
|
||||
"ampDevFiles": [],
|
||||
"lowPriorityFiles": [],
|
||||
"rootMainFiles": [
|
||||
"static/chunks/webpack.js",
|
||||
"static/chunks/main-app.js"
|
||||
],
|
||||
"rootMainFilesTree": {},
|
||||
"pages": {
|
||||
"/_app": []
|
||||
},
|
||||
"ampFirstPages": []
|
||||
};
|
||||
globalThis.__BUILD_MANIFEST.lowPriorityFiles = [
|
||||
"/static/" + process.env.__NEXT_BUILD_ID + "/_buildManifest.js",
|
||||
,"/static/" + process.env.__NEXT_BUILD_ID + "/_ssgManifest.js",
|
||||
|
||||
];
|
||||
6
.next/server/middleware-manifest.json
Normal file
6
.next/server/middleware-manifest.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": 3,
|
||||
"middleware": {},
|
||||
"functions": {},
|
||||
"sortedMiddleware": []
|
||||
}
|
||||
1
.next/server/middleware-react-loadable-manifest.js
Normal file
1
.next/server/middleware-react-loadable-manifest.js
Normal file
@ -0,0 +1 @@
|
||||
self.__REACT_LOADABLE_MANIFEST="{}"
|
||||
1
.next/server/next-font-manifest.js
Normal file
1
.next/server/next-font-manifest.js
Normal file
@ -0,0 +1 @@
|
||||
self.__NEXT_FONT_MANIFEST="{\"pages\":{},\"app\":{\"/home/sorti/projects/hosting-frontend/app/layout\":[\"static/media/e4af272ccee01ff0-s.p.woff2\"]},\"appUsingSizeAdjust\":true,\"pagesUsingSizeAdjust\":false}"
|
||||
1
.next/server/next-font-manifest.json
Normal file
1
.next/server/next-font-manifest.json
Normal file
@ -0,0 +1 @@
|
||||
{"pages":{},"app":{"/home/sorti/projects/hosting-frontend/app/layout":["static/media/e4af272ccee01ff0-s.p.woff2"]},"appUsingSizeAdjust":true,"pagesUsingSizeAdjust":false}
|
||||
1
.next/server/pages-manifest.json
Normal file
1
.next/server/pages-manifest.json
Normal file
@ -0,0 +1 @@
|
||||
{}
|
||||
1
.next/server/server-reference-manifest.js
Normal file
1
.next/server/server-reference-manifest.js
Normal file
@ -0,0 +1 @@
|
||||
self.__RSC_SERVER_MANIFEST="{\n \"node\": {},\n \"edge\": {},\n \"encryptionKey\": \"process.env.NEXT_SERVER_ACTIONS_ENCRYPTION_KEY\"\n}"
|
||||
5
.next/server/server-reference-manifest.json
Normal file
5
.next/server/server-reference-manifest.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"node": {},
|
||||
"edge": {},
|
||||
"encryptionKey": "UJCuqkc43Q1Tu8qgslshb0xL4QAUycNhcPIjjC8lUyo="
|
||||
}
|
||||
55
.next/server/vendor-chunks/@swc.js
Normal file
55
.next/server/vendor-chunks/@swc.js
Normal file
@ -0,0 +1,55 @@
|
||||
"use strict";
|
||||
/*
|
||||
* ATTENTION: An "eval-source-map" devtool has been used.
|
||||
* This devtool is neither made for production nor for readable output files.
|
||||
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
|
||||
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
||||
* or disable the default devtool with "devtool: false".
|
||||
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
||||
*/
|
||||
exports.id = "vendor-chunks/@swc";
|
||||
exports.ids = ["vendor-chunks/@swc"];
|
||||
exports.modules = {
|
||||
|
||||
/***/ "(ssr)/./node_modules/@swc/helpers/esm/_class_private_field_loose_base.js":
|
||||
/*!**************************************************************************!*\
|
||||
!*** ./node_modules/@swc/helpers/esm/_class_private_field_loose_base.js ***!
|
||||
\**************************************************************************/
|
||||
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ _: () => (/* binding */ _class_private_field_loose_base)\n/* harmony export */ });\nfunction _class_private_field_loose_base(receiver, privateKey) {\n if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {\n throw new TypeError(\"attempted to use private field on non-instance\");\n }\n\n return receiver;\n}\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHNzcikvLi9ub2RlX21vZHVsZXMvQHN3Yy9oZWxwZXJzL2VzbS9fY2xhc3NfcHJpdmF0ZV9maWVsZF9sb29zZV9iYXNlLmpzIiwibWFwcGluZ3MiOiI7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ2dEIiwic291cmNlcyI6WyIvaG9tZS9zb3J0aS9wcm9qZWN0cy9ob3N0aW5nLWZyb250ZW5kL25vZGVfbW9kdWxlcy9Ac3djL2hlbHBlcnMvZXNtL19jbGFzc19wcml2YXRlX2ZpZWxkX2xvb3NlX2Jhc2UuanMiXSwic291cmNlc0NvbnRlbnQiOlsiZnVuY3Rpb24gX2NsYXNzX3ByaXZhdGVfZmllbGRfbG9vc2VfYmFzZShyZWNlaXZlciwgcHJpdmF0ZUtleSkge1xuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlY2VpdmVyLCBwcml2YXRlS2V5KSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYXR0ZW1wdGVkIHRvIHVzZSBwcml2YXRlIGZpZWxkIG9uIG5vbi1pbnN0YW5jZVwiKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVjZWl2ZXI7XG59XG5leHBvcnQgeyBfY2xhc3NfcHJpdmF0ZV9maWVsZF9sb29zZV9iYXNlIGFzIF8gfTtcbiJdLCJuYW1lcyI6W10sImlnbm9yZUxpc3QiOlswXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///(ssr)/./node_modules/@swc/helpers/esm/_class_private_field_loose_base.js\n");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "(ssr)/./node_modules/@swc/helpers/esm/_class_private_field_loose_key.js":
|
||||
/*!*************************************************************************!*\
|
||||
!*** ./node_modules/@swc/helpers/esm/_class_private_field_loose_key.js ***!
|
||||
\*************************************************************************/
|
||||
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ _: () => (/* binding */ _class_private_field_loose_key)\n/* harmony export */ });\nvar id = 0;\n\nfunction _class_private_field_loose_key(name) {\n return \"__private_\" + id++ + \"_\" + name;\n}\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHNzcikvLi9ub2RlX21vZHVsZXMvQHN3Yy9oZWxwZXJzL2VzbS9fY2xhc3NfcHJpdmF0ZV9maWVsZF9sb29zZV9rZXkuanMiLCJtYXBwaW5ncyI6Ijs7OztBQUFBOztBQUVBO0FBQ0E7QUFDQTtBQUMrQyIsInNvdXJjZXMiOlsiL2hvbWUvc29ydGkvcHJvamVjdHMvaG9zdGluZy1mcm9udGVuZC9ub2RlX21vZHVsZXMvQHN3Yy9oZWxwZXJzL2VzbS9fY2xhc3NfcHJpdmF0ZV9maWVsZF9sb29zZV9rZXkuanMiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGlkID0gMDtcblxuZnVuY3Rpb24gX2NsYXNzX3ByaXZhdGVfZmllbGRfbG9vc2Vfa2V5KG5hbWUpIHtcbiAgICByZXR1cm4gXCJfX3ByaXZhdGVfXCIgKyBpZCsrICsgXCJfXCIgKyBuYW1lO1xufVxuZXhwb3J0IHsgX2NsYXNzX3ByaXZhdGVfZmllbGRfbG9vc2Vfa2V5IGFzIF8gfTtcbiJdLCJuYW1lcyI6W10sImlnbm9yZUxpc3QiOlswXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///(ssr)/./node_modules/@swc/helpers/esm/_class_private_field_loose_key.js\n");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "(ssr)/./node_modules/@swc/helpers/esm/_interop_require_default.js":
|
||||
/*!*******************************************************************!*\
|
||||
!*** ./node_modules/@swc/helpers/esm/_interop_require_default.js ***!
|
||||
\*******************************************************************/
|
||||
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ _: () => (/* binding */ _interop_require_default)\n/* harmony export */ });\nfunction _interop_require_default(obj) {\n return obj && obj.__esModule ? obj : { default: obj };\n}\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHNzcikvLi9ub2RlX21vZHVsZXMvQHN3Yy9oZWxwZXJzL2VzbS9faW50ZXJvcF9yZXF1aXJlX2RlZmF1bHQuanMiLCJtYXBwaW5ncyI6Ijs7OztBQUFBO0FBQ0EsMkNBQTJDO0FBQzNDO0FBQ3lDIiwic291cmNlcyI6WyIvaG9tZS9zb3J0aS9wcm9qZWN0cy9ob3N0aW5nLWZyb250ZW5kL25vZGVfbW9kdWxlcy9Ac3djL2hlbHBlcnMvZXNtL19pbnRlcm9wX3JlcXVpcmVfZGVmYXVsdC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJmdW5jdGlvbiBfaW50ZXJvcF9yZXF1aXJlX2RlZmF1bHQob2JqKSB7XG4gICAgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07XG59XG5leHBvcnQgeyBfaW50ZXJvcF9yZXF1aXJlX2RlZmF1bHQgYXMgXyB9O1xuIl0sIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6WzBdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///(ssr)/./node_modules/@swc/helpers/esm/_interop_require_default.js\n");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "(ssr)/./node_modules/@swc/helpers/esm/_interop_require_wildcard.js":
|
||||
/*!********************************************************************!*\
|
||||
!*** ./node_modules/@swc/helpers/esm/_interop_require_wildcard.js ***!
|
||||
\********************************************************************/
|
||||
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ _: () => (/* binding */ _interop_require_wildcard)\n/* harmony export */ });\nfunction _getRequireWildcardCache(nodeInterop) {\n if (typeof WeakMap !== \"function\") return null;\n\n var cacheBabelInterop = new WeakMap();\n var cacheNodeInterop = new WeakMap();\n\n return (_getRequireWildcardCache = function(nodeInterop) {\n return nodeInterop ? cacheNodeInterop : cacheBabelInterop;\n })(nodeInterop);\n}\nfunction _interop_require_wildcard(obj, nodeInterop) {\n if (!nodeInterop && obj && obj.__esModule) return obj;\n if (obj === null || typeof obj !== \"object\" && typeof obj !== \"function\") return { default: obj };\n\n var cache = _getRequireWildcardCache(nodeInterop);\n\n if (cache && cache.has(obj)) return cache.get(obj);\n\n var newObj = { __proto__: null };\n var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;\n\n for (var key in obj) {\n if (key !== \"default\" && Object.prototype.hasOwnProperty.call(obj, key)) {\n var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;\n if (desc && (desc.get || desc.set)) Object.defineProperty(newObj, key, desc);\n else newObj[key] = obj[key];\n }\n }\n\n newObj.default = obj;\n\n if (cache) cache.set(obj, newObj);\n\n return newObj;\n}\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHNzcikvLi9ub2RlX21vZHVsZXMvQHN3Yy9oZWxwZXJzL2VzbS9faW50ZXJvcF9yZXF1aXJlX3dpbGRjYXJkLmpzIiwibWFwcGluZ3MiOiI7Ozs7QUFBQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSx1RkFBdUY7O0FBRXZGOztBQUVBOztBQUVBLG1CQUFtQjtBQUNuQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQzBDIiwic291cmNlcyI6WyIvaG9tZS9zb3J0aS9wcm9qZWN0cy9ob3N0aW5nLWZyb250ZW5kL25vZGVfbW9kdWxlcy9Ac3djL2hlbHBlcnMvZXNtL19pbnRlcm9wX3JlcXVpcmVfd2lsZGNhcmQuanMiXSwic291cmNlc0NvbnRlbnQiOlsiZnVuY3Rpb24gX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlKG5vZGVJbnRlcm9wKSB7XG4gICAgaWYgKHR5cGVvZiBXZWFrTWFwICE9PSBcImZ1bmN0aW9uXCIpIHJldHVybiBudWxsO1xuXG4gICAgdmFyIGNhY2hlQmFiZWxJbnRlcm9wID0gbmV3IFdlYWtNYXAoKTtcbiAgICB2YXIgY2FjaGVOb2RlSW50ZXJvcCA9IG5ldyBXZWFrTWFwKCk7XG5cbiAgICByZXR1cm4gKF9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSA9IGZ1bmN0aW9uKG5vZGVJbnRlcm9wKSB7XG4gICAgICAgIHJldHVybiBub2RlSW50ZXJvcCA/IGNhY2hlTm9kZUludGVyb3AgOiBjYWNoZUJhYmVsSW50ZXJvcDtcbiAgICB9KShub2RlSW50ZXJvcCk7XG59XG5mdW5jdGlvbiBfaW50ZXJvcF9yZXF1aXJlX3dpbGRjYXJkKG9iaiwgbm9kZUludGVyb3ApIHtcbiAgICBpZiAoIW5vZGVJbnRlcm9wICYmIG9iaiAmJiBvYmouX19lc01vZHVsZSkgcmV0dXJuIG9iajtcbiAgICBpZiAob2JqID09PSBudWxsIHx8IHR5cGVvZiBvYmogIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG9iaiAhPT0gXCJmdW5jdGlvblwiKSByZXR1cm4geyBkZWZhdWx0OiBvYmogfTtcblxuICAgIHZhciBjYWNoZSA9IF9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZShub2RlSW50ZXJvcCk7XG5cbiAgICBpZiAoY2FjaGUgJiYgY2FjaGUuaGFzKG9iaikpIHJldHVybiBjYWNoZS5nZXQob2JqKTtcblxuICAgIHZhciBuZXdPYmogPSB7IF9fcHJvdG9fXzogbnVsbCB9O1xuICAgIHZhciBoYXNQcm9wZXJ0eURlc2NyaXB0b3IgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkgJiYgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcblxuICAgIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgICAgaWYgKGtleSAhPT0gXCJkZWZhdWx0XCIgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkge1xuICAgICAgICAgICAgdmFyIGRlc2MgPSBoYXNQcm9wZXJ0eURlc2NyaXB0b3IgPyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwga2V5KSA6IG51bGw7XG4gICAgICAgICAgICBpZiAoZGVzYyAmJiAoZGVzYy5nZXQgfHwgZGVzYy5zZXQpKSBPYmplY3QuZGVmaW5lUHJvcGVydHkobmV3T2JqLCBrZXksIGRlc2MpO1xuICAgICAgICAgICAgZWxzZSBuZXdPYmpba2V5XSA9IG9ialtrZXldO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbmV3T2JqLmRlZmF1bHQgPSBvYmo7XG5cbiAgICBpZiAoY2FjaGUpIGNhY2hlLnNldChvYmosIG5ld09iaik7XG5cbiAgICByZXR1cm4gbmV3T2JqO1xufVxuZXhwb3J0IHsgX2ludGVyb3BfcmVxdWlyZV93aWxkY2FyZCBhcyBfIH07XG4iXSwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbMF0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///(ssr)/./node_modules/@swc/helpers/esm/_interop_require_wildcard.js\n");
|
||||
|
||||
/***/ })
|
||||
|
||||
};
|
||||
;
|
||||
25
.next/server/vendor-chunks/class-variance-authority.js
Normal file
25
.next/server/vendor-chunks/class-variance-authority.js
Normal file
File diff suppressed because one or more lines are too long
25
.next/server/vendor-chunks/clsx.js
Normal file
25
.next/server/vendor-chunks/clsx.js
Normal file
@ -0,0 +1,25 @@
|
||||
"use strict";
|
||||
/*
|
||||
* ATTENTION: An "eval-source-map" devtool has been used.
|
||||
* This devtool is neither made for production nor for readable output files.
|
||||
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
|
||||
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
||||
* or disable the default devtool with "devtool: false".
|
||||
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
||||
*/
|
||||
exports.id = "vendor-chunks/clsx";
|
||||
exports.ids = ["vendor-chunks/clsx"];
|
||||
exports.modules = {
|
||||
|
||||
/***/ "(rsc)/./node_modules/clsx/dist/clsx.mjs":
|
||||
/*!*****************************************!*\
|
||||
!*** ./node_modules/clsx/dist/clsx.mjs ***!
|
||||
\*****************************************/
|
||||
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ clsx: () => (/* binding */ clsx),\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nfunction r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (clsx);//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHJzYykvLi9ub2RlX21vZHVsZXMvY2xzeC9kaXN0L2Nsc3gubWpzIiwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsY0FBYyxhQUFhLCtDQUErQyxnREFBZ0QsZUFBZSxRQUFRLElBQUksMENBQTBDLHlDQUF5QyxTQUFnQixnQkFBZ0Isd0NBQXdDLElBQUksbURBQW1ELFNBQVMsaUVBQWUsSUFBSSIsInNvdXJjZXMiOlsiL2hvbWUvc29ydGkvcHJvamVjdHMvaG9zdGluZy1mcm9udGVuZC9ub2RlX21vZHVsZXMvY2xzeC9kaXN0L2Nsc3gubWpzIl0sInNvdXJjZXNDb250ZW50IjpbImZ1bmN0aW9uIHIoZSl7dmFyIHQsZixuPVwiXCI7aWYoXCJzdHJpbmdcIj09dHlwZW9mIGV8fFwibnVtYmVyXCI9PXR5cGVvZiBlKW4rPWU7ZWxzZSBpZihcIm9iamVjdFwiPT10eXBlb2YgZSlpZihBcnJheS5pc0FycmF5KGUpKXt2YXIgbz1lLmxlbmd0aDtmb3IodD0wO3Q8bzt0KyspZVt0XSYmKGY9cihlW3RdKSkmJihuJiYobis9XCIgXCIpLG4rPWYpfWVsc2UgZm9yKGYgaW4gZSllW2ZdJiYobiYmKG4rPVwiIFwiKSxuKz1mKTtyZXR1cm4gbn1leHBvcnQgZnVuY3Rpb24gY2xzeCgpe2Zvcih2YXIgZSx0LGY9MCxuPVwiXCIsbz1hcmd1bWVudHMubGVuZ3RoO2Y8bztmKyspKGU9YXJndW1lbnRzW2ZdKSYmKHQ9cihlKSkmJihuJiYobis9XCIgXCIpLG4rPXQpO3JldHVybiBufWV4cG9ydCBkZWZhdWx0IGNsc3g7Il0sIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6WzBdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///(rsc)/./node_modules/clsx/dist/clsx.mjs\n");
|
||||
|
||||
/***/ })
|
||||
|
||||
};
|
||||
;
|
||||
3591
.next/server/vendor-chunks/next.js
Normal file
3591
.next/server/vendor-chunks/next.js
Normal file
File diff suppressed because one or more lines are too long
25
.next/server/vendor-chunks/tailwind-merge.js
Normal file
25
.next/server/vendor-chunks/tailwind-merge.js
Normal file
File diff suppressed because one or more lines are too long
209
.next/server/webpack-runtime.js
Normal file
209
.next/server/webpack-runtime.js
Normal file
File diff suppressed because one or more lines are too long
182
.next/static/chunks/app-pages-internals.js
Normal file
182
.next/static/chunks/app-pages-internals.js
Normal file
File diff suppressed because one or more lines are too long
114
.next/static/chunks/app/layout.js
Normal file
114
.next/static/chunks/app/layout.js
Normal file
File diff suppressed because one or more lines are too long
105
.next/static/chunks/app/page.js
Normal file
105
.next/static/chunks/app/page.js
Normal file
File diff suppressed because one or more lines are too long
1893
.next/static/chunks/main-app.js
Normal file
1893
.next/static/chunks/main-app.js
Normal file
File diff suppressed because one or more lines are too long
1
.next/static/chunks/polyfills.js
Normal file
1
.next/static/chunks/polyfills.js
Normal file
File diff suppressed because one or more lines are too long
1405
.next/static/chunks/webpack.js
Normal file
1405
.next/static/chunks/webpack.js
Normal file
File diff suppressed because one or more lines are too long
1505
.next/static/css/app/layout.css
Normal file
1505
.next/static/css/app/layout.css
Normal file
File diff suppressed because it is too large
Load Diff
1
.next/static/development/_buildManifest.js
Normal file
1
.next/static/development/_buildManifest.js
Normal file
@ -0,0 +1 @@
|
||||
self.__BUILD_MANIFEST = (function(a){return {__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},__routerFilterStatic:a,__routerFilterDynamic:a,sortedPages:["\u002F_app"]}}(void 0));self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB()
|
||||
1
.next/static/development/_ssgManifest.js
Normal file
1
.next/static/development/_ssgManifest.js
Normal file
@ -0,0 +1 @@
|
||||
self.__SSG_MANIFEST=new Set;self.__SSG_MANIFEST_CB&&self.__SSG_MANIFEST_CB()
|
||||
BIN
.next/static/media/19cfc7226ec3afaa-s.woff2
Normal file
BIN
.next/static/media/19cfc7226ec3afaa-s.woff2
Normal file
Binary file not shown.
BIN
.next/static/media/21350d82a1f187e9-s.woff2
Normal file
BIN
.next/static/media/21350d82a1f187e9-s.woff2
Normal file
Binary file not shown.
BIN
.next/static/media/8e9860b6e62d6359-s.woff2
Normal file
BIN
.next/static/media/8e9860b6e62d6359-s.woff2
Normal file
Binary file not shown.
BIN
.next/static/media/ba9851c3c22cd980-s.woff2
Normal file
BIN
.next/static/media/ba9851c3c22cd980-s.woff2
Normal file
Binary file not shown.
BIN
.next/static/media/c5fe6dc8356a8c31-s.woff2
Normal file
BIN
.next/static/media/c5fe6dc8356a8c31-s.woff2
Normal file
Binary file not shown.
BIN
.next/static/media/df0a9ae256c0569c-s.woff2
Normal file
BIN
.next/static/media/df0a9ae256c0569c-s.woff2
Normal file
Binary file not shown.
BIN
.next/static/media/e4af272ccee01ff0-s.p.woff2
Normal file
BIN
.next/static/media/e4af272ccee01ff0-s.p.woff2
Normal file
Binary file not shown.
@ -0,0 +1 @@
|
||||
{"c":["app/layout","webpack"],"r":[],"m":[]}
|
||||
1
.next/static/webpack/633457081244afec._.hot-update.json
Normal file
1
.next/static/webpack/633457081244afec._.hot-update.json
Normal file
@ -0,0 +1 @@
|
||||
{"c":[],"r":[],"m":[]}
|
||||
@ -0,0 +1,22 @@
|
||||
"use strict";
|
||||
/*
|
||||
* ATTENTION: An "eval-source-map" devtool has been used.
|
||||
* This devtool is neither made for production nor for readable output files.
|
||||
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
|
||||
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
||||
* or disable the default devtool with "devtool: false".
|
||||
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
||||
*/
|
||||
self["webpackHotUpdate_N_E"]("app/layout",{
|
||||
|
||||
/***/ "(app-pages-browser)/./app/globals.css":
|
||||
/*!*************************!*\
|
||||
!*** ./app/globals.css ***!
|
||||
\*************************/
|
||||
/***/ ((module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (\"f7e2466089dd\");\nif (true) { module.hot.accept() }\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKGFwcC1wYWdlcy1icm93c2VyKS8uL2FwcC9nbG9iYWxzLmNzcyIsIm1hcHBpbmdzIjoiOzs7O0FBQUEsaUVBQWUsY0FBYztBQUM3QixJQUFJLElBQVUsSUFBSSxpQkFBaUIiLCJzb3VyY2VzIjpbIi9ob21lL3NvcnRpL3Byb2plY3RzL2hvc3RpbmctZnJvbnRlbmQvYXBwL2dsb2JhbHMuY3NzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IFwiZjdlMjQ2NjA4OWRkXCJcbmlmIChtb2R1bGUuaG90KSB7IG1vZHVsZS5ob3QuYWNjZXB0KCkgfVxuIl0sIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///(app-pages-browser)/./app/globals.css\n"));
|
||||
|
||||
/***/ })
|
||||
|
||||
});
|
||||
12
.next/static/webpack/webpack.18886a9ebe220a08.hot-update.js
Normal file
12
.next/static/webpack/webpack.18886a9ebe220a08.hot-update.js
Normal file
@ -0,0 +1,12 @@
|
||||
"use strict";
|
||||
self["webpackHotUpdate_N_E"]("webpack",{},
|
||||
/******/ function(__webpack_require__) { // webpackRuntimeModules
|
||||
/******/ /* webpack/runtime/getFullHash */
|
||||
/******/ (() => {
|
||||
/******/ __webpack_require__.h = () => ("8e3f0ede0ae7b4ef")
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ }
|
||||
)
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJpZ25vcmVMaXN0IjpbMF0sIm1hcHBpbmdzIjoiQUFBQSIsInNvdXJjZXMiOlsid2VicGFjay1pbnRlcm5hbDovL25leHRqcy93ZWJwYWNrLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFRoaXMgc291cmNlIHdhcyBnZW5lcmF0ZWQgYnkgTmV4dC5qcyBiYXNlZCBvZmYgb2YgdGhlIGdlbmVyYXRlZCBXZWJwYWNrIHJ1bnRpbWUuXG4vLyBUaGUgbWFwcGluZ3MgYXJlIGluY29ycmVjdC5cbi8vIFRvIGdldCB0aGUgY29ycmVjdCBsaW5lL2NvbHVtbiBtYXBwaW5ncywgdHVybiBvZmYgc291cmNlbWFwcyBpbiB5b3VyIGRlYnVnZ2VyLlxuXG5zZWxmW1wid2VicGFja0hvdFVwZGF0ZV9OX0VcIl0oXCJ3ZWJwYWNrXCIse30sXG4vKioqKioqLyBmdW5jdGlvbihfX3dlYnBhY2tfcmVxdWlyZV9fKSB7IC8vIHdlYnBhY2tSdW50aW1lTW9kdWxlc1xuLyoqKioqKi8gLyogd2VicGFjay9ydW50aW1lL2dldEZ1bGxIYXNoICovXG4vKioqKioqLyAoKCkgPT4ge1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmggPSAoKSA9PiAoXCI4ZTNmMGVkZTBhZTdiNGVmXCIpXG4vKioqKioqLyB9KSgpO1xuLyoqKioqKi8gXG4vKioqKioqLyB9XG4pIl19
|
||||
;
|
||||
10
.next/trace
Normal file
10
.next/trace
Normal file
File diff suppressed because one or more lines are too long
84
.next/types/app/layout.ts
Normal file
84
.next/types/app/layout.ts
Normal file
@ -0,0 +1,84 @@
|
||||
// File: /home/sorti/projects/hosting-frontend/app/layout.tsx
|
||||
import * as entry from '../../../app/layout.js'
|
||||
import type { ResolvingMetadata, ResolvingViewport } from 'next/dist/lib/metadata/types/metadata-interface.js'
|
||||
|
||||
type TEntry = typeof import('../../../app/layout.js')
|
||||
|
||||
type SegmentParams<T extends Object = any> = T extends Record<string, any>
|
||||
? { [K in keyof T]: T[K] extends string ? string | string[] | undefined : never }
|
||||
: T
|
||||
|
||||
// Check that the entry is a valid entry
|
||||
checkFields<Diff<{
|
||||
default: Function
|
||||
config?: {}
|
||||
generateStaticParams?: Function
|
||||
revalidate?: RevalidateRange<TEntry> | false
|
||||
dynamic?: 'auto' | 'force-dynamic' | 'error' | 'force-static'
|
||||
dynamicParams?: boolean
|
||||
fetchCache?: 'auto' | 'force-no-store' | 'only-no-store' | 'default-no-store' | 'default-cache' | 'only-cache' | 'force-cache'
|
||||
preferredRegion?: 'auto' | 'global' | 'home' | string | string[]
|
||||
runtime?: 'nodejs' | 'experimental-edge' | 'edge'
|
||||
maxDuration?: number
|
||||
|
||||
metadata?: any
|
||||
generateMetadata?: Function
|
||||
viewport?: any
|
||||
generateViewport?: Function
|
||||
experimental_ppr?: boolean
|
||||
|
||||
}, TEntry, ''>>()
|
||||
|
||||
|
||||
// Check the prop type of the entry function
|
||||
checkFields<Diff<LayoutProps, FirstArg<TEntry['default']>, 'default'>>()
|
||||
|
||||
// Check the arguments and return type of the generateMetadata function
|
||||
if ('generateMetadata' in entry) {
|
||||
checkFields<Diff<LayoutProps, FirstArg<MaybeField<TEntry, 'generateMetadata'>>, 'generateMetadata'>>()
|
||||
checkFields<Diff<ResolvingMetadata, SecondArg<MaybeField<TEntry, 'generateMetadata'>>, 'generateMetadata'>>()
|
||||
}
|
||||
|
||||
// Check the arguments and return type of the generateViewport function
|
||||
if ('generateViewport' in entry) {
|
||||
checkFields<Diff<LayoutProps, FirstArg<MaybeField<TEntry, 'generateViewport'>>, 'generateViewport'>>()
|
||||
checkFields<Diff<ResolvingViewport, SecondArg<MaybeField<TEntry, 'generateViewport'>>, 'generateViewport'>>()
|
||||
}
|
||||
|
||||
// Check the arguments and return type of the generateStaticParams function
|
||||
if ('generateStaticParams' in entry) {
|
||||
checkFields<Diff<{ params: SegmentParams }, FirstArg<MaybeField<TEntry, 'generateStaticParams'>>, 'generateStaticParams'>>()
|
||||
checkFields<Diff<{ __tag__: 'generateStaticParams', __return_type__: any[] | Promise<any[]> }, { __tag__: 'generateStaticParams', __return_type__: ReturnType<MaybeField<TEntry, 'generateStaticParams'>> }>>()
|
||||
}
|
||||
|
||||
export interface PageProps {
|
||||
params?: Promise<SegmentParams>
|
||||
searchParams?: Promise<any>
|
||||
}
|
||||
export interface LayoutProps {
|
||||
children?: React.ReactNode
|
||||
|
||||
params?: Promise<SegmentParams>
|
||||
}
|
||||
|
||||
// =============
|
||||
// Utility types
|
||||
type RevalidateRange<T> = T extends { revalidate: any } ? NonNegative<T['revalidate']> : never
|
||||
|
||||
// If T is unknown or any, it will be an empty {} type. Otherwise, it will be the same as Omit<T, keyof Base>.
|
||||
type OmitWithTag<T, K extends keyof any, _M> = Omit<T, K>
|
||||
type Diff<Base, T extends Base, Message extends string = ''> = 0 extends (1 & T) ? {} : OmitWithTag<T, keyof Base, Message>
|
||||
|
||||
type FirstArg<T extends Function> = T extends (...args: [infer T, any]) => any ? unknown extends T ? any : T : never
|
||||
type SecondArg<T extends Function> = T extends (...args: [any, infer T]) => any ? unknown extends T ? any : T : never
|
||||
type MaybeField<T, K extends string> = T extends { [k in K]: infer G } ? G extends Function ? G : never : never
|
||||
|
||||
|
||||
|
||||
function checkFields<_ extends { [k in keyof any]: never }>() {}
|
||||
|
||||
// https://github.com/sindresorhus/type-fest
|
||||
type Numeric = number | bigint
|
||||
type Zero = 0 | 0n
|
||||
type Negative<T extends Numeric> = T extends Zero ? never : `${T}` extends `-${string}` ? T : never
|
||||
type NonNegative<T extends Numeric> = T extends Zero ? T : Negative<T> extends never ? T : '__invalid_negative_number__'
|
||||
84
.next/types/app/page.ts
Normal file
84
.next/types/app/page.ts
Normal file
@ -0,0 +1,84 @@
|
||||
// File: /home/sorti/projects/hosting-frontend/app/page.tsx
|
||||
import * as entry from '../../../app/page.js'
|
||||
import type { ResolvingMetadata, ResolvingViewport } from 'next/dist/lib/metadata/types/metadata-interface.js'
|
||||
|
||||
type TEntry = typeof import('../../../app/page.js')
|
||||
|
||||
type SegmentParams<T extends Object = any> = T extends Record<string, any>
|
||||
? { [K in keyof T]: T[K] extends string ? string | string[] | undefined : never }
|
||||
: T
|
||||
|
||||
// Check that the entry is a valid entry
|
||||
checkFields<Diff<{
|
||||
default: Function
|
||||
config?: {}
|
||||
generateStaticParams?: Function
|
||||
revalidate?: RevalidateRange<TEntry> | false
|
||||
dynamic?: 'auto' | 'force-dynamic' | 'error' | 'force-static'
|
||||
dynamicParams?: boolean
|
||||
fetchCache?: 'auto' | 'force-no-store' | 'only-no-store' | 'default-no-store' | 'default-cache' | 'only-cache' | 'force-cache'
|
||||
preferredRegion?: 'auto' | 'global' | 'home' | string | string[]
|
||||
runtime?: 'nodejs' | 'experimental-edge' | 'edge'
|
||||
maxDuration?: number
|
||||
|
||||
metadata?: any
|
||||
generateMetadata?: Function
|
||||
viewport?: any
|
||||
generateViewport?: Function
|
||||
experimental_ppr?: boolean
|
||||
|
||||
}, TEntry, ''>>()
|
||||
|
||||
|
||||
// Check the prop type of the entry function
|
||||
checkFields<Diff<PageProps, FirstArg<TEntry['default']>, 'default'>>()
|
||||
|
||||
// Check the arguments and return type of the generateMetadata function
|
||||
if ('generateMetadata' in entry) {
|
||||
checkFields<Diff<PageProps, FirstArg<MaybeField<TEntry, 'generateMetadata'>>, 'generateMetadata'>>()
|
||||
checkFields<Diff<ResolvingMetadata, SecondArg<MaybeField<TEntry, 'generateMetadata'>>, 'generateMetadata'>>()
|
||||
}
|
||||
|
||||
// Check the arguments and return type of the generateViewport function
|
||||
if ('generateViewport' in entry) {
|
||||
checkFields<Diff<PageProps, FirstArg<MaybeField<TEntry, 'generateViewport'>>, 'generateViewport'>>()
|
||||
checkFields<Diff<ResolvingViewport, SecondArg<MaybeField<TEntry, 'generateViewport'>>, 'generateViewport'>>()
|
||||
}
|
||||
|
||||
// Check the arguments and return type of the generateStaticParams function
|
||||
if ('generateStaticParams' in entry) {
|
||||
checkFields<Diff<{ params: SegmentParams }, FirstArg<MaybeField<TEntry, 'generateStaticParams'>>, 'generateStaticParams'>>()
|
||||
checkFields<Diff<{ __tag__: 'generateStaticParams', __return_type__: any[] | Promise<any[]> }, { __tag__: 'generateStaticParams', __return_type__: ReturnType<MaybeField<TEntry, 'generateStaticParams'>> }>>()
|
||||
}
|
||||
|
||||
export interface PageProps {
|
||||
params?: Promise<SegmentParams>
|
||||
searchParams?: Promise<any>
|
||||
}
|
||||
export interface LayoutProps {
|
||||
children?: React.ReactNode
|
||||
|
||||
params?: Promise<SegmentParams>
|
||||
}
|
||||
|
||||
// =============
|
||||
// Utility types
|
||||
type RevalidateRange<T> = T extends { revalidate: any } ? NonNegative<T['revalidate']> : never
|
||||
|
||||
// If T is unknown or any, it will be an empty {} type. Otherwise, it will be the same as Omit<T, keyof Base>.
|
||||
type OmitWithTag<T, K extends keyof any, _M> = Omit<T, K>
|
||||
type Diff<Base, T extends Base, Message extends string = ''> = 0 extends (1 & T) ? {} : OmitWithTag<T, keyof Base, Message>
|
||||
|
||||
type FirstArg<T extends Function> = T extends (...args: [infer T, any]) => any ? unknown extends T ? any : T : never
|
||||
type SecondArg<T extends Function> = T extends (...args: [any, infer T]) => any ? unknown extends T ? any : T : never
|
||||
type MaybeField<T, K extends string> = T extends { [k in K]: infer G } ? G extends Function ? G : never : never
|
||||
|
||||
|
||||
|
||||
function checkFields<_ extends { [k in keyof any]: never }>() {}
|
||||
|
||||
// https://github.com/sindresorhus/type-fest
|
||||
type Numeric = number | bigint
|
||||
type Zero = 0 | 0n
|
||||
type Negative<T extends Numeric> = T extends Zero ? never : `${T}` extends `-${string}` ? T : never
|
||||
type NonNegative<T extends Numeric> = T extends Zero ? T : Negative<T> extends never ? T : '__invalid_negative_number__'
|
||||
141
.next/types/cache-life.d.ts
vendored
Normal file
141
.next/types/cache-life.d.ts
vendored
Normal file
@ -0,0 +1,141 @@
|
||||
// Type definitions for Next.js cacheLife configs
|
||||
|
||||
declare module 'next/cache' {
|
||||
export { unstable_cache } from 'next/dist/server/web/spec-extension/unstable-cache'
|
||||
export {
|
||||
revalidateTag,
|
||||
revalidatePath,
|
||||
unstable_expireTag,
|
||||
unstable_expirePath,
|
||||
} from 'next/dist/server/web/spec-extension/revalidate'
|
||||
export { unstable_noStore } from 'next/dist/server/web/spec-extension/unstable-no-store'
|
||||
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` for a timespan defined by the `"default"` profile.
|
||||
* ```
|
||||
* stale: 300 seconds (5 minutes)
|
||||
* revalidate: 900 seconds (15 minutes)
|
||||
* expire: never
|
||||
* ```
|
||||
*
|
||||
* This cache may be stale on clients for 5 minutes before checking with the server.
|
||||
* If the server receives a new request after 15 minutes, start revalidating new values in the background.
|
||||
* It lives for the maximum age of the server cache. If this entry has no traffic for a while, it may serve an old value the next request.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: "default"): void
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` for a timespan defined by the `"seconds"` profile.
|
||||
* ```
|
||||
* stale: 30 seconds
|
||||
* revalidate: 1 seconds
|
||||
* expire: 60 seconds (1 minute)
|
||||
* ```
|
||||
*
|
||||
* This cache may be stale on clients for 30 seconds before checking with the server.
|
||||
* If the server receives a new request after 1 seconds, start revalidating new values in the background.
|
||||
* If this entry has no traffic for 1 minute it will expire. The next request will recompute it.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: "seconds"): void
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` for a timespan defined by the `"minutes"` profile.
|
||||
* ```
|
||||
* stale: 300 seconds (5 minutes)
|
||||
* revalidate: 60 seconds (1 minute)
|
||||
* expire: 3600 seconds (1 hour)
|
||||
* ```
|
||||
*
|
||||
* This cache may be stale on clients for 5 minutes before checking with the server.
|
||||
* If the server receives a new request after 1 minute, start revalidating new values in the background.
|
||||
* If this entry has no traffic for 1 hour it will expire. The next request will recompute it.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: "minutes"): void
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` for a timespan defined by the `"hours"` profile.
|
||||
* ```
|
||||
* stale: 300 seconds (5 minutes)
|
||||
* revalidate: 3600 seconds (1 hour)
|
||||
* expire: 86400 seconds (1 day)
|
||||
* ```
|
||||
*
|
||||
* This cache may be stale on clients for 5 minutes before checking with the server.
|
||||
* If the server receives a new request after 1 hour, start revalidating new values in the background.
|
||||
* If this entry has no traffic for 1 day it will expire. The next request will recompute it.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: "hours"): void
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` for a timespan defined by the `"days"` profile.
|
||||
* ```
|
||||
* stale: 300 seconds (5 minutes)
|
||||
* revalidate: 86400 seconds (1 day)
|
||||
* expire: 604800 seconds (1 week)
|
||||
* ```
|
||||
*
|
||||
* This cache may be stale on clients for 5 minutes before checking with the server.
|
||||
* If the server receives a new request after 1 day, start revalidating new values in the background.
|
||||
* If this entry has no traffic for 1 week it will expire. The next request will recompute it.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: "days"): void
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` for a timespan defined by the `"weeks"` profile.
|
||||
* ```
|
||||
* stale: 300 seconds (5 minutes)
|
||||
* revalidate: 604800 seconds (1 week)
|
||||
* expire: 2592000 seconds (30 days)
|
||||
* ```
|
||||
*
|
||||
* This cache may be stale on clients for 5 minutes before checking with the server.
|
||||
* If the server receives a new request after 1 week, start revalidating new values in the background.
|
||||
* If this entry has no traffic for 30 days it will expire. The next request will recompute it.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: "weeks"): void
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` for a timespan defined by the `"max"` profile.
|
||||
* ```
|
||||
* stale: 300 seconds (5 minutes)
|
||||
* revalidate: 2592000 seconds (30 days)
|
||||
* expire: never
|
||||
* ```
|
||||
*
|
||||
* This cache may be stale on clients for 5 minutes before checking with the server.
|
||||
* If the server receives a new request after 30 days, start revalidating new values in the background.
|
||||
* It lives for the maximum age of the server cache. If this entry has no traffic for a while, it may serve an old value the next request.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: "max"): void
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` using a custom timespan.
|
||||
* ```
|
||||
* stale: ... // seconds
|
||||
* revalidate: ... // seconds
|
||||
* expire: ... // seconds
|
||||
* ```
|
||||
*
|
||||
* This is similar to Cache-Control: max-age=`stale`,s-max-age=`revalidate`,stale-while-revalidate=`expire-revalidate`
|
||||
*
|
||||
* If a value is left out, the lowest of other cacheLife() calls or the default, is used instead.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: {
|
||||
/**
|
||||
* This cache may be stale on clients for ... seconds before checking with the server.
|
||||
*/
|
||||
stale?: number,
|
||||
/**
|
||||
* If the server receives a new request after ... seconds, start revalidating new values in the background.
|
||||
*/
|
||||
revalidate?: number,
|
||||
/**
|
||||
* If this entry has no traffic for ... seconds it will expire. The next request will recompute it.
|
||||
*/
|
||||
expire?: number
|
||||
}): void
|
||||
|
||||
|
||||
export { cacheTag as unstable_cacheTag } from 'next/dist/server/use-cache/cache-tag'
|
||||
}
|
||||
1
.next/types/package.json
Normal file
1
.next/types/package.json
Normal file
@ -0,0 +1 @@
|
||||
{"type": "module"}
|
||||
60
.next/types/routes.d.ts
vendored
Normal file
60
.next/types/routes.d.ts
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
// This file is generated automatically by Next.js
|
||||
// Do not edit this file manually
|
||||
|
||||
type AppRoutes = "/" | "/dashboard" | "/login" | "/register"
|
||||
type PageRoutes = never
|
||||
type LayoutRoutes = "/"
|
||||
type RedirectRoutes = never
|
||||
type RewriteRoutes = never
|
||||
type Routes = AppRoutes | PageRoutes | LayoutRoutes | RedirectRoutes | RewriteRoutes
|
||||
|
||||
|
||||
interface ParamMap {
|
||||
"/": {}
|
||||
"/dashboard": {}
|
||||
"/login": {}
|
||||
"/register": {}
|
||||
}
|
||||
|
||||
|
||||
export type ParamsOf<Route extends Routes> = ParamMap[Route]
|
||||
|
||||
interface LayoutSlotMap {
|
||||
"/": never
|
||||
}
|
||||
|
||||
|
||||
export type { AppRoutes, PageRoutes, LayoutRoutes, RedirectRoutes, RewriteRoutes, ParamMap }
|
||||
|
||||
declare global {
|
||||
/**
|
||||
* Props for Next.js App Router page components
|
||||
* @example
|
||||
* ```tsx
|
||||
* export default function Page(props: PageProps<'/blog/[slug]'>) {
|
||||
* const { slug } = await props.params
|
||||
* return <div>Blog post: {slug}</div>
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
interface PageProps<AppRoute extends AppRoutes> {
|
||||
params: Promise<ParamMap[AppRoute]>
|
||||
searchParams: Promise<Record<string, string | string[] | undefined>>
|
||||
}
|
||||
|
||||
/**
|
||||
* Props for Next.js App Router layout components
|
||||
* @example
|
||||
* ```tsx
|
||||
* export default function Layout(props: LayoutProps<'/dashboard'>) {
|
||||
* return <div>{props.children}</div>
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
type LayoutProps<LayoutRoute extends LayoutRoutes> = {
|
||||
params: Promise<ParamMap[LayoutRoute]>
|
||||
children: React.ReactNode
|
||||
} & {
|
||||
[K in LayoutSlotMap[LayoutRoute]]: React.ReactNode
|
||||
}
|
||||
}
|
||||
88
.next/types/validator.ts
Normal file
88
.next/types/validator.ts
Normal file
@ -0,0 +1,88 @@
|
||||
// This file is generated automatically by Next.js
|
||||
// Do not edit this file manually
|
||||
// This file validates that all pages and layouts export the correct types
|
||||
|
||||
import type { AppRoutes, LayoutRoutes, ParamMap } from "./routes.js"
|
||||
import type { ResolvingMetadata, ResolvingViewport } from "next/types.js"
|
||||
|
||||
type AppPageConfig<Route extends AppRoutes = AppRoutes> = {
|
||||
default: React.ComponentType<{ params: Promise<ParamMap[Route]> } & any> | ((props: { params: Promise<ParamMap[Route]> } & any) => React.ReactNode | Promise<React.ReactNode> | never | void | Promise<void>)
|
||||
generateStaticParams?: (props: { params: ParamMap[Route] }) => Promise<any[]> | any[]
|
||||
generateMetadata?: (
|
||||
props: { params: Promise<ParamMap[Route]> } & any,
|
||||
parent: ResolvingMetadata
|
||||
) => Promise<any> | any
|
||||
generateViewport?: (
|
||||
props: { params: Promise<ParamMap[Route]> } & any,
|
||||
parent: ResolvingViewport
|
||||
) => Promise<any> | any
|
||||
metadata?: any
|
||||
viewport?: any
|
||||
}
|
||||
|
||||
type LayoutConfig<Route extends LayoutRoutes = LayoutRoutes> = {
|
||||
default: React.ComponentType<LayoutProps<Route>> | ((props: LayoutProps<Route>) => React.ReactNode | Promise<React.ReactNode> | never | void | Promise<void>)
|
||||
generateStaticParams?: (props: { params: ParamMap[Route] }) => Promise<any[]> | any[]
|
||||
generateMetadata?: (
|
||||
props: { params: Promise<ParamMap[Route]> } & any,
|
||||
parent: ResolvingMetadata
|
||||
) => Promise<any> | any
|
||||
generateViewport?: (
|
||||
props: { params: Promise<ParamMap[Route]> } & any,
|
||||
parent: ResolvingViewport
|
||||
) => Promise<any> | any
|
||||
metadata?: any
|
||||
viewport?: any
|
||||
}
|
||||
|
||||
|
||||
// Validate ../../app/dashboard/page.tsx
|
||||
{
|
||||
type __IsExpected<Specific extends AppPageConfig<"/dashboard">> = Specific
|
||||
const handler = {} as typeof import("../../app/dashboard/page.js")
|
||||
type __Check = __IsExpected<typeof handler>
|
||||
// @ts-ignore
|
||||
type __Unused = __Check
|
||||
}
|
||||
|
||||
// Validate ../../app/login/page.tsx
|
||||
{
|
||||
type __IsExpected<Specific extends AppPageConfig<"/login">> = Specific
|
||||
const handler = {} as typeof import("../../app/login/page.js")
|
||||
type __Check = __IsExpected<typeof handler>
|
||||
// @ts-ignore
|
||||
type __Unused = __Check
|
||||
}
|
||||
|
||||
// Validate ../../app/page.tsx
|
||||
{
|
||||
type __IsExpected<Specific extends AppPageConfig<"/">> = Specific
|
||||
const handler = {} as typeof import("../../app/page.js")
|
||||
type __Check = __IsExpected<typeof handler>
|
||||
// @ts-ignore
|
||||
type __Unused = __Check
|
||||
}
|
||||
|
||||
// Validate ../../app/register/page.tsx
|
||||
{
|
||||
type __IsExpected<Specific extends AppPageConfig<"/register">> = Specific
|
||||
const handler = {} as typeof import("../../app/register/page.js")
|
||||
type __Check = __IsExpected<typeof handler>
|
||||
// @ts-ignore
|
||||
type __Unused = __Check
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Validate ../../app/layout.tsx
|
||||
{
|
||||
type __IsExpected<Specific extends LayoutConfig<"/">> = Specific
|
||||
const handler = {} as typeof import("../../app/layout.js")
|
||||
type __Check = __IsExpected<typeof handler>
|
||||
// @ts-ignore
|
||||
type __Unused = __Check
|
||||
}
|
||||
18
AGENTS.md
Normal file
18
AGENTS.md
Normal file
@ -0,0 +1,18 @@
|
||||
<!-- OPENSPEC:START -->
|
||||
# OpenSpec Instructions
|
||||
|
||||
These instructions are for AI assistants working in this project.
|
||||
|
||||
Always open `@/openspec/AGENTS.md` when the request:
|
||||
- Mentions planning or proposals (words like proposal, spec, change, plan)
|
||||
- Introduces new capabilities, breaking changes, architecture shifts, or big performance/security work
|
||||
- Sounds ambiguous and you need the authoritative spec before coding
|
||||
|
||||
Use `@/openspec/AGENTS.md` to learn:
|
||||
- How to create and apply change proposals
|
||||
- Spec format and conventions
|
||||
- Project structure and guidelines
|
||||
|
||||
Keep this managed block so 'openspec update' can refresh the instructions.
|
||||
|
||||
<!-- OPENSPEC:END -->
|
||||
18
CLAUDE.md
Normal file
18
CLAUDE.md
Normal file
@ -0,0 +1,18 @@
|
||||
<!-- OPENSPEC:START -->
|
||||
# OpenSpec Instructions
|
||||
|
||||
These instructions are for AI assistants working in this project.
|
||||
|
||||
Always open `@/openspec/AGENTS.md` when the request:
|
||||
- Mentions planning or proposals (words like proposal, spec, change, plan)
|
||||
- Introduces new capabilities, breaking changes, architecture shifts, or big performance/security work
|
||||
- Sounds ambiguous and you need the authoritative spec before coding
|
||||
|
||||
Use `@/openspec/AGENTS.md` to learn:
|
||||
- How to create and apply change proposals
|
||||
- Spec format and conventions
|
||||
- Project structure and guidelines
|
||||
|
||||
Keep this managed block so 'openspec update' can refresh the instructions.
|
||||
|
||||
<!-- OPENSPEC:END -->
|
||||
5
Dockerfile
Normal file
5
Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
FROM nginx:alpine AS prod
|
||||
COPY ./dist/hosting-frontend/browser /usr/share/nginx/html
|
||||
COPY ./deploy/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
EXPOSE 80
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
255
README.md
255
README.md
@ -1,59 +1,260 @@
|
||||
# HostingFrontend
|
||||
# Portfolio Hosting Platform - Frontend
|
||||
|
||||
This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.0.0.
|
||||
A modern Next.js application for managing and deploying portfolio websites with custom domains.
|
||||
|
||||
## Development server
|
||||
## Tech Stack
|
||||
|
||||
To start a local development server, run:
|
||||
- **Framework**: Next.js 15 with App Router
|
||||
- **Language**: TypeScript 5.8
|
||||
- **Styling**: Tailwind CSS 4.1 with shadcn/ui components
|
||||
- **State Management**: React Context API + hooks
|
||||
- **Forms**: React Hook Form
|
||||
- **Icons**: Lucide React
|
||||
- **Authentication**: JWT Bearer tokens
|
||||
|
||||
```bash
|
||||
ng serve
|
||||
## Features
|
||||
|
||||
- **User Authentication**: Login and registration with JWT tokens
|
||||
- **Portfolio Management**: Create, upload, and deploy portfolio websites
|
||||
- **File Upload**: ZIP file upload with progress tracking
|
||||
- **Dashboard**: Comprehensive portfolio management interface
|
||||
- **Responsive Design**: Mobile-first, fully responsive UI
|
||||
- **Protected Routes**: Middleware-based authentication
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
/
|
||||
├── app/ # Next.js App Router pages
|
||||
│ ├── layout.tsx # Root layout with AuthProvider
|
||||
│ ├── page.tsx # Landing page
|
||||
│ ├── login/ # Login page
|
||||
│ ├── register/ # Registration page
|
||||
│ └── dashboard/ # Dashboard (protected)
|
||||
├── components/ # React components
|
||||
│ ├── ui/ # shadcn/ui primitives
|
||||
│ └── auth/ # Authentication components
|
||||
├── lib/ # Utilities and API client
|
||||
│ ├── api-client.ts # Fetch wrapper with auth
|
||||
│ ├── types.ts # TypeScript interfaces
|
||||
│ └── utils.ts # Utility functions
|
||||
├── hooks/ # Custom React hooks
|
||||
│ ├── use-auth.ts # Authentication hook
|
||||
│ └── use-portfolios.ts # Portfolio data hook
|
||||
└── middleware.ts # Route protection
|
||||
```
|
||||
|
||||
Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files.
|
||||
## Getting Started
|
||||
|
||||
## Code scaffolding
|
||||
### Prerequisites
|
||||
|
||||
Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
|
||||
- Node.js 18+ and npm
|
||||
- Backend API running (see API section)
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
ng generate component component-name
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Set up environment variables
|
||||
cp .env.local.example .env.local
|
||||
# Edit .env.local with your API URL
|
||||
```
|
||||
|
||||
For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
|
||||
### Environment Variables
|
||||
|
||||
Create a `.env.local` file:
|
||||
|
||||
```env
|
||||
NEXT_PUBLIC_API_URL=http://localhost:8000/api
|
||||
```
|
||||
|
||||
For production, create `.env.production`:
|
||||
|
||||
```env
|
||||
NEXT_PUBLIC_API_URL=https://api.portfolio-host.com/api
|
||||
```
|
||||
|
||||
### Development
|
||||
|
||||
```bash
|
||||
ng generate --help
|
||||
# Start development server
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Building
|
||||
Visit [http://localhost:3000](http://localhost:3000)
|
||||
|
||||
To build the project run:
|
||||
### Build
|
||||
|
||||
```bash
|
||||
ng build
|
||||
# Build for production
|
||||
npm run build
|
||||
|
||||
# Start production server
|
||||
npm start
|
||||
```
|
||||
|
||||
This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
|
||||
### Docker Deployment
|
||||
|
||||
```bash
|
||||
ng test
|
||||
# Build Docker image
|
||||
docker build -t hosting-frontend .
|
||||
|
||||
# Run container
|
||||
docker run -p 3000:3000 hosting-frontend
|
||||
```
|
||||
|
||||
## Running end-to-end tests
|
||||
## API Integration
|
||||
|
||||
For end-to-end (e2e) testing, run:
|
||||
The application integrates with a backend API for:
|
||||
|
||||
### Authentication Endpoints
|
||||
- `POST /auth/register` - User registration
|
||||
- `POST /auth/login` - User login
|
||||
- `POST /auth/logout` - Logout
|
||||
- `GET /auth/user` - Get current user
|
||||
- `POST /auth/refresh` - Refresh token
|
||||
|
||||
### Portfolio Endpoints
|
||||
- `GET /portfolios` - List user's portfolios
|
||||
- `POST /portfolios` - Create new portfolio
|
||||
- `POST /portfolios/{id}/upload` - Upload ZIP file
|
||||
- `POST /portfolios/{id}/deploy` - Deploy portfolio
|
||||
- `GET /portfolio/random` - Get random portfolio
|
||||
|
||||
### API Response Format
|
||||
|
||||
All API responses follow this structure:
|
||||
|
||||
```typescript
|
||||
{
|
||||
success: boolean;
|
||||
data?: T;
|
||||
message?: string;
|
||||
errors?: any;
|
||||
}
|
||||
```
|
||||
|
||||
## Key Components
|
||||
|
||||
### Authentication Flow
|
||||
|
||||
1. User logs in via `/login`
|
||||
2. API returns JWT token
|
||||
3. Token stored in localStorage
|
||||
4. AuthContext provides auth state globally
|
||||
5. Middleware protects `/dashboard/*` routes
|
||||
6. API client automatically injects Bearer token
|
||||
|
||||
### Portfolio Management Flow
|
||||
|
||||
1. User creates portfolio (name + domain)
|
||||
2. Upload ZIP file containing portfolio files
|
||||
3. Deploy portfolio to make it live
|
||||
4. Status indicators show portfolio state:
|
||||
- **Pending Payment**: Not yet active
|
||||
- **Pending Upload**: Active but no files
|
||||
- **Uploaded**: Ready to deploy
|
||||
|
||||
## Code Style & Conventions
|
||||
|
||||
### File Naming
|
||||
- Components: `PascalCase.tsx`
|
||||
- Utilities: `kebab-case.ts`
|
||||
- Pages: Next.js conventions (`page.tsx`, `layout.tsx`)
|
||||
|
||||
### Component Patterns
|
||||
- Use `'use client'` directive for client components
|
||||
- Server components by default
|
||||
- Colocate styles with components
|
||||
|
||||
### State Management
|
||||
- Global auth state: `AuthContext`
|
||||
- Component state: `useState`
|
||||
- Form state: React Hook Form
|
||||
|
||||
### API Calls
|
||||
- Use `apiClient` from `lib/api-client.ts`
|
||||
- Wrap in try/catch
|
||||
- Handle loading and error states
|
||||
|
||||
## Migration from Angular
|
||||
|
||||
This project was migrated from Angular 20 to Next.js 15. Key changes:
|
||||
|
||||
- **Framework**: Angular → Next.js + React
|
||||
- **Routing**: Angular Router → Next.js App Router
|
||||
- **State**: RxJS → React Context API
|
||||
- **Forms**: Angular Reactive Forms → React Hook Form
|
||||
- **HTTP**: Angular HttpClient → Fetch API
|
||||
|
||||
The Angular code has been backed up to `/angular-backup` for reference.
|
||||
|
||||
## Deployment
|
||||
|
||||
### Production Build
|
||||
|
||||
The production build uses Next.js standalone output for optimal performance:
|
||||
|
||||
```bash
|
||||
ng e2e
|
||||
npm run build
|
||||
```
|
||||
|
||||
Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
|
||||
Output is in `.next/standalone/`
|
||||
|
||||
## Additional Resources
|
||||
### Environment Configuration
|
||||
|
||||
For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
|
||||
- Development: `.env.local`
|
||||
- Production: `.env.production`
|
||||
- Staging: `.env.staging`
|
||||
|
||||
### Docker
|
||||
|
||||
The included `Dockerfile` creates an optimized production image:
|
||||
|
||||
```dockerfile
|
||||
# Build and run
|
||||
docker build -t portfolio-frontend .
|
||||
docker run -p 3000:3000 -e NEXT_PUBLIC_API_URL=https://api.example.com portfolio-frontend
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Build Errors
|
||||
|
||||
**Issue**: Tailwind CSS errors
|
||||
```bash
|
||||
# Ensure @tailwindcss/postcss is installed
|
||||
npm install @tailwindcss/postcss
|
||||
```
|
||||
|
||||
**Issue**: TypeScript errors
|
||||
```bash
|
||||
# Regenerate types
|
||||
rm -rf .next
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Runtime Errors
|
||||
|
||||
**Issue**: API connection failed
|
||||
- Check `NEXT_PUBLIC_API_URL` in `.env.local`
|
||||
- Verify backend API is running
|
||||
- Check CORS configuration on backend
|
||||
|
||||
**Issue**: Authentication not working
|
||||
- Check localStorage for `auth_token`
|
||||
- Verify JWT token format
|
||||
- Check middleware configuration
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Create feature branch from `main`
|
||||
2. Make changes following code style
|
||||
3. Test locally with `npm run build`
|
||||
4. Submit pull request
|
||||
|
||||
## License
|
||||
|
||||
Copyright © 2025 Portfolio Host. All rights reserved.
|
||||
|
||||
92
angular-backup/angular.json
Normal file
92
angular-backup/angular.json
Normal file
@ -0,0 +1,92 @@
|
||||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"hosting-frontend": {
|
||||
"projectType": "application",
|
||||
"schematics": {},
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"prefix": "app",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular/build:application",
|
||||
"options": {
|
||||
"browser": "src/main.ts",
|
||||
"polyfills": [
|
||||
"zone.js"
|
||||
],
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"assets": [
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "public"
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.css"
|
||||
]
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "500kB",
|
||||
"maximumError": "1MB"
|
||||
},
|
||||
{
|
||||
"type": "anyComponentStyle",
|
||||
"maximumWarning": "16kB",
|
||||
"maximumError": "32kB"
|
||||
}
|
||||
],
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
"optimization": false,
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular/build:dev-server",
|
||||
"configurations": {
|
||||
"production": {
|
||||
"buildTarget": "hosting-frontend:build:production"
|
||||
},
|
||||
"development": {
|
||||
"buildTarget": "hosting-frontend:build:development"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular/build:extract-i18n"
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular/build:karma",
|
||||
"options": {
|
||||
"polyfills": [
|
||||
"zone.js",
|
||||
"zone.js/testing"
|
||||
],
|
||||
"tsConfig": "tsconfig.spec.json",
|
||||
"assets": [
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "public"
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.css"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
angular-backup/src/app/app.config.ts
Normal file
12
angular-backup/src/app/app.config.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { ApplicationConfig, provideBrowserGlobalErrorListeners, provideZoneChangeDetection } from '@angular/core';
|
||||
import { provideRouter } from '@angular/router';
|
||||
|
||||
import { routes } from './app.routes';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
provideBrowserGlobalErrorListeners(),
|
||||
provideZoneChangeDetection({ eventCoalescing: true }),
|
||||
provideRouter(routes)
|
||||
]
|
||||
};
|
||||
1
angular-backup/src/app/app.css
Normal file
1
angular-backup/src/app/app.css
Normal file
@ -0,0 +1 @@
|
||||
@import "tailwindcss";
|
||||
1
angular-backup/src/app/app.html
Normal file
1
angular-backup/src/app/app.html
Normal file
@ -0,0 +1 @@
|
||||
<router-outlet />
|
||||
23
angular-backup/src/app/app.routes.ts
Normal file
23
angular-backup/src/app/app.routes.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import {Routes} from '@angular/router';
|
||||
import {LoginComponent} from './components/login/login.component';
|
||||
import {RegisterComponent} from './components/register/register.component';
|
||||
import {LandingComponent} from './components/landing/landing.component';
|
||||
import {DashboardComponent} from './components/dashboard/dashboard.component';
|
||||
|
||||
export const routes: Routes = [
|
||||
|
||||
{
|
||||
path: 'login', component: LoginComponent, title: 'Login - Your App Name'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'register', component: RegisterComponent, title: 'Register - Your App Name'
|
||||
},
|
||||
|
||||
{
|
||||
path: '', component: LandingComponent, title: 'Home'
|
||||
},
|
||||
|
||||
{path: 'dashboard', component: DashboardComponent}
|
||||
|
||||
];
|
||||
23
angular-backup/src/app/app.spec.ts
Normal file
23
angular-backup/src/app/app.spec.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { App } from './app';
|
||||
|
||||
describe('App', () => {
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [App],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
it('should create the app', () => {
|
||||
const fixture = TestBed.createComponent(App);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should render title', () => {
|
||||
const fixture = TestBed.createComponent(App);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.nativeElement as HTMLElement;
|
||||
expect(compiled.querySelector('h1')?.textContent).toContain('Hello, hosting-frontend');
|
||||
});
|
||||
});
|
||||
12
angular-backup/src/app/app.ts
Normal file
12
angular-backup/src/app/app.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { RouterOutlet } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
imports: [RouterOutlet],
|
||||
templateUrl: './app.html',
|
||||
styleUrl: './app.css'
|
||||
})
|
||||
export class App {
|
||||
protected title = 'hosting-frontend';
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user