Skip to content

Commit 63a919a

Browse files
authored
Merge branch 'rinafcode:main' into men
2 parents c870ed1 + a209574 commit 63a919a

72 files changed

Lines changed: 5764 additions & 8254 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.husky/pre-push

100644100755
Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,35 @@
11
#!/bin/sh
2-
command -v git-lfs >/dev/null 2>&1 || { printf >&2 "\n%s\n\n" "This repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting the 'pre-push' file in the hooks directory (set by 'core.hookspath'; usually '.git/hooks')."; exit 2; }
3-
git lfs pre-push "$@"
2+
. "$(dirname "$0")/_/husky.sh"
3+
4+
# Git hooks run with a minimal PATH; ensure pnpm is available.
5+
if ! command -v pnpm >/dev/null 2>&1; then
6+
if [ -n "$PNPM_HOME" ]; then
7+
PATH="$PNPM_HOME:$PATH"
8+
fi
9+
PATH="$HOME/.local/share/pnpm:/opt/homebrew/bin:/usr/local/bin:$PATH"
10+
export PATH
11+
fi
12+
13+
if ! command -v pnpm >/dev/null 2>&1; then
14+
printf >&2 "\n❌ Pre-push blocked: pnpm not found on PATH.\nInstall pnpm or add it to PATH, then try pushing again.\n\n"
15+
exit 1
16+
fi
17+
18+
command -v git-lfs >/dev/null 2>&1 || {
19+
printf >&2 "\n%s\n\n" "This repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting the 'pre-push' file in the hooks directory (set by 'core.hookspath'; usually '.git/hooks')."
20+
exit 2
21+
}
22+
23+
git lfs pre-push "$@" || exit $?
24+
25+
echo "Running type-check before push..."
26+
pnpm run type-check || {
27+
printf >&2 "\n❌ Pre-push blocked: TypeScript type-check failed.\nFix the errors above, then try pushing again.\n\n"
28+
exit 1
29+
}
30+
31+
echo "Running tests before push..."
32+
pnpm run test || {
33+
printf >&2 "\n❌ Pre-push blocked: Tests failed.\nFix the failing tests above, then try pushing again.\n\n"
34+
exit 1
35+
}

CONTRIBUTING.md

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,26 @@ Your PR will be blocked from merging unless it meets the following:
4040

4141
## Local checks (run before pushing)
4242

43-
- `npm run type-check`
44-
- `npm run lint`
45-
- `npm run test`
46-
- `npm run build`
43+
- `pnpm run type-check`
44+
- `pnpm run lint`
45+
- `pnpm run test`
46+
- `pnpm run build`
47+
48+
## Git hooks
49+
50+
### Pre-push (`.husky/pre-push`)
51+
52+
Before a push is sent to the remote, the pre-push hook runs automatically:
53+
54+
1. **Git LFS** — validates LFS-tracked files (`git lfs pre-push`)
55+
2. **Type-check**`pnpm run type-check` (`tsc --noEmit`)
56+
3. **Tests**`pnpm run test` (`vitest run`)
57+
58+
If type-check or tests fail, the push is **blocked** and the hook prints which check failed. Fix the reported errors and push again.
59+
60+
The hook ensures `pnpm` is on `PATH` (common install locations and `$PNPM_HOME`). If `pnpm` still cannot be found, the push is blocked with a clear message.
61+
62+
`lint` and `build` are not run by this hook; run them locally or rely on CI before opening a PR.
4763

4864
## PR description format
4965

DOCKER_DEPLOYMENT.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,23 @@ docker image prune
266266
docker system prune -a --volumes
267267
```
268268

269+
## SEO: Sitemap Submission
270+
271+
The build pipeline automatically generates `public/sitemap.xml` via the `postbuild` script. After deploying to production:
272+
273+
1. **Verify the sitemap** is accessible at `https://your-domain.com/sitemap.xml`
274+
2. **Submit to Google Search Console:**
275+
- Navigate to [Google Search Console](https://search.google.com/search-console)
276+
- Select your property
277+
- Go to **Sitemaps** under **Indexing**
278+
- Enter `sitemap.xml` and click Submit
279+
3. **Monitor** for crawl errors and indexing status in Search Console
280+
269281
## Reference
270282

271283
- [Next.js Docker Documentation](https://nextjs.org/docs/deployment/docker)
272284
- [Docker Best Practices](https://docs.docker.com/develop/dev-best-practices/)
273285
- [Docker Compose Reference](https://docs.docker.com/compose/compose-file/)
274286
- [Alpine Linux Benefits](https://www.alpinelinux.org/)
287+
- [Google Search Console](https://search.google.com/search-console)
288+
- [Sitemaps.org Protocol](https://www.sitemaps.org/)

STRUCTURED_DATA_IMPLEMENTATION.md

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# Structured Data Implementation for Filter Controls
2+
3+
## Overview
4+
5+
This document describes the implementation of Structured Data (JSON-LD) for Filter Controls in the TeachLink application. This implementation improves SEO and accessibility by providing machine-readable metadata about filter options.
6+
7+
## Implementation Details
8+
9+
### Files Created
10+
11+
1. **`src/utils/structuredDataUtils.ts`**
12+
13+
- Utility functions for generating JSON-LD structured data
14+
- Functions:
15+
- `generateFilterStructuredData()`: Generates complete filter control structured data
16+
- `generateBreadcrumbStructuredData()`: Generates breadcrumb navigation structured data
17+
- `generateFilterGroupStructuredData()`: Generates individual filter group structured data
18+
- `validateStructuredData()`: Validates JSON-LD structure and schema.org compliance
19+
20+
2. **`src/components/seo/StructuredDataScript.tsx`**
21+
22+
- React component to render JSON-LD script tags
23+
- Validates JSON before rendering
24+
- Uses `type="application/ld+json"` for proper schema.org recognition
25+
26+
3. **`src/utils/__tests__/structuredDataUtils.test.ts`**
27+
- Comprehensive unit tests for structured data utilities
28+
- Tests for generation, validation, and edge cases
29+
30+
### Files Modified
31+
32+
1. **`src/components/search/FilterSidebar.tsx`**
33+
34+
- Added structured data generation for search filters
35+
- Includes: difficulty, duration, price, topics, instructor, node affinity
36+
- Integrated `StructuredDataScript` component
37+
38+
2. **`src/components/dashboard/DashboardFilters.tsx`**
39+
40+
- Added structured data for dashboard analytics filters
41+
- Includes: time range, aggregation, metric, categories
42+
- Integrated `StructuredDataScript` component
43+
44+
3. **`src/components/search/FacetedFilterSystem.tsx`**
45+
- Added structured data for faceted search filters
46+
- Includes: content type, topics, difficulty, price, rating
47+
- Integrated `StructuredDataScript` component
48+
49+
## Schema.org Compliance
50+
51+
The implementation follows schema.org specifications:
52+
53+
- Uses `@context: https://schema.org`
54+
- Implements `FilterControls` type for main filter groups
55+
- Uses `ItemList` for filter options
56+
- Uses `PropertyValueSpecification` for individual filter groups
57+
- Uses `BreadcrumbList` for navigation breadcrumbs
58+
59+
## Accessibility Considerations
60+
61+
### ARIA Labels
62+
63+
- All existing ARIA labels are preserved
64+
- Structured data provides additional semantic information
65+
- Screen readers can access filter metadata through JSON-LD
66+
67+
### Keyboard Navigation
68+
69+
- No changes to keyboard navigation
70+
- Existing keyboard shortcuts and focus management remain intact
71+
72+
### Screen Reader Support
73+
74+
- JSON-LD provides machine-readable descriptions
75+
- Filter options include descriptive text in structured data
76+
- Helps assistive technologies understand filter semantics
77+
78+
## Security Considerations
79+
80+
### XSS Prevention
81+
82+
- `StructuredDataScript` component uses `dangerouslySetInnerHTML` only after validation
83+
- JSON parsing validates structure before rendering
84+
- No user input is directly injected without sanitization
85+
86+
### Data Validation
87+
88+
- `validateStructuredData()` function ensures:
89+
- Valid JSON format
90+
- Required fields present (@context, @type)
91+
- Schema.org context compliance
92+
- Invalid structured data is not rendered to prevent console errors
93+
94+
### Performance Impact
95+
96+
- Structured data generation uses `useMemo` to avoid unnecessary recalculations
97+
- Minimal performance overhead (JSON serialization)
98+
- Only renders when filter values change
99+
100+
## Testing
101+
102+
### Unit Tests
103+
104+
- Comprehensive test coverage for all utility functions
105+
- Tests for:
106+
- JSON-LD generation
107+
- Schema.org compliance
108+
- Validation logic
109+
- Edge cases (invalid JSON, missing fields)
110+
111+
### Integration Testing
112+
113+
- Structured data is integrated into all three filter components
114+
- Each component generates appropriate metadata for its filters
115+
- No regression in existing functionality
116+
117+
## Browser Compatibility
118+
119+
- JSON-LD is supported by all modern browsers
120+
- Graceful degradation for older browsers (script tag simply not rendered)
121+
- No impact on core functionality if structured data fails to load
122+
123+
## SEO Benefits
124+
125+
- Search engines can understand filter structure
126+
- Rich snippets potential for filter pages
127+
- Improved indexing of filterable content
128+
- Better semantic understanding of UI controls
129+
130+
## Future Enhancements
131+
132+
Potential improvements:
133+
134+
1. Dynamic structured data based on actual filter results
135+
2. Integration with Google Rich Results testing
136+
3. Add more schema.org types as needed
137+
4. Server-side rendering for initial structured data
138+
5. Internationalization support for structured data descriptions
139+
140+
## Maintenance Notes
141+
142+
- When adding new filters, update the corresponding structured data generation
143+
- Keep structured data in sync with UI changes
144+
- Run tests after modifying filter components
145+
- Validate JSON-LD using Google's Structured Data Testing Tool

package.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,15 @@
3434
"check-i18n": "node scripts/check-i18n.cjs",
3535
"check-locales": "node scripts/check-locales.mjs",
3636
"prebuild": "pnpm run check-locales && pnpm run check-i18n",
37-
"generate:sitemap": "npx tsx scripts/generate-sitemap.ts"
37+
"postbuild": "pnpm run generate:sitemap",
38+
"generate:sitemap": "npx tsx scripts/generate-sitemap.ts",
39+
"migrate": "npx tsx src/lib/db/migrate.ts"
3840
},
3941
"dependencies": {
4042
"@apollo/client": "^3.8.0",
4143
"@dnd-kit/core": "^6.3.1",
4244
"@dnd-kit/sortable": "^8.0.0",
4345
"@dnd-kit/utilities": "^3.2.2",
44-
"@hello-pangea/dnd": "^18.0.1",
4546
"@hookform/resolvers": "^3.10.0",
4647
"@monaco-editor/react": "^4.7.0",
4748
"@testing-library/dom": "^10.4.1",
@@ -73,8 +74,6 @@
7374
"react": "^18.3.1",
7475
"react-big-calendar": "1.19.4",
7576
"react-countdown": "^2.3.6",
76-
"react-dnd": "^16.0.1",
77-
"react-dnd-html5-backend": "^16.0.1",
7877
"react-dom": "^18.3.1",
7978
"react-hook-form": "^7.60.0",
8079
"react-hot-toast": "^2.6.0",

0 commit comments

Comments
 (0)