Skip to content

Commit 8dc73cc

Browse files
authored
Initial commit
0 parents  commit 8dc73cc

File tree

163 files changed

+32609
-0
lines changed

Some content is hidden

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

163 files changed

+32609
-0
lines changed

.eslintrc.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "next/core-web-vitals"
3+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
name: Accessibility CI
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches: [main]
7+
8+
jobs:
9+
accessibility:
10+
runs-on: ubuntu-latest
11+
env:
12+
BASE_URL: http://localhost:3000
13+
NEXT_PUBLIC_DMS: https://api.cloud.portaljs.com/@datopian
14+
15+
steps:
16+
- name: 🧩 Checkout repository
17+
uses: actions/checkout@v4
18+
19+
- name: ⚙️ Setup Node.js
20+
uses: actions/setup-node@v4
21+
with:
22+
node-version: '22'
23+
cache: 'npm'
24+
25+
- name: 📦 Install dependencies
26+
run: npm ci
27+
28+
- name: 🧱 Build Next.js app
29+
run: npm run build
30+
31+
- name: 🗺️ Generate routes manifest
32+
run: npm run generate:routes
33+
34+
- name: 🎭 Install Playwright browsers
35+
run: npx playwright install --with-deps
36+
37+
- name: 🚀 Run accessibility tests (Playwright + Pa11y + Lighthouse)
38+
run: |
39+
npm i -D start-server-and-test
40+
npx start-server-and-test 'npm run start' $BASE_URL \
41+
'npx playwright test && npm run test:pa11y && npm run test:lhci'
42+
43+
- name: 📤 Upload Playwright report
44+
if: always()
45+
uses: actions/upload-artifact@v4
46+
with:
47+
name: playwright-report
48+
path: playwright-report
49+
if-no-files-found: ignore
50+
51+
- name: 📤 Upload Pa11y report
52+
if: always()
53+
uses: actions/upload-artifact@v4
54+
with:
55+
name: pa11y-report
56+
path: pa11y-report.ndjson
57+
if-no-files-found: ignore
58+
59+
- name: 📤 Upload Lighthouse report
60+
if: always()
61+
uses: actions/upload-artifact@v4
62+
with:
63+
name: lhci-report
64+
path: lhci-report
65+
if-no-files-found: ignore

.gitignore

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
10+
11+
# next.js
12+
/.next/
13+
/out/
14+
15+
# production
16+
/build
17+
18+
# misc
19+
.DS_Store
20+
*.pem
21+
22+
# debug
23+
npm-debug.log*
24+
yarn-debug.log*
25+
yarn-error.log*
26+
27+
# local env files
28+
.env*.local
29+
.env
30+
31+
# vercel
32+
.vercel
33+
34+
# typescript
35+
*.tsbuildinfo
36+
next-env.d.ts

.lighthouserc.base.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"ci": {
3+
"assert": {
4+
"assertions": {
5+
"categories:accessibility": ["error", { "minScore": 0.95 }]
6+
}
7+
},
8+
"upload": {
9+
"target": "filesystem",
10+
"outputDir": "./lhci-report"
11+
}
12+
}
13+
}

.pa11yci.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"defaults": {
3+
"standard": "WCAG2AA",
4+
"timeout": 60000,
5+
"wait": 1000,
6+
"level": "error",
7+
"chromeLaunchConfig": {
8+
"args": ["--no-sandbox", "--disable-setuid-sandbox"]
9+
}
10+
},
11+
"urls": []
12+
}

README.md

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
# PortalJS Frontend Starter
2+
3+
<div align="center">
4+
5+
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/datopian/portaljs-frontend-starter)
6+
7+
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Next.js 13+](https://img.shields.io/badge/Next.js-13%2B-black?logo=next.js&logoColor=white)](https://nextjs.org/) [![GitHub Stars](https://img.shields.io/github/stars/datopian/portaljs?style=social)](https://github.com/datopian/portaljs/stargazers)
8+
9+
**A modern, customizable frontend template for building high-performance CKAN-based data portals**
10+
11+
Powered by **[Next.js](https://nextjs.org)**, **[React](https://react.dev/)**, and **[Tailwind CSS](https://tailwindcss.com/)**
12+
13+
**[🚀 Live Demo](https://demo.portaljs.com/)[📖 Documentation](https://portaljs.com/docs)[☁️ PortalJS Cloud](https://cloud.portaljs.com/)[🌐 Website](https://portaljs.com/)**
14+
15+
</div>
16+
17+
---
18+
19+
## Overview
20+
21+
This is the official frontend template used by [PortalJS Cloud](https://cloud.portaljs.com) — a fully managed data portal service built on top of CKAN and Next.js.
22+
23+
Use it to:
24+
25+
- Build decoupled CKAN frontends with modern tools (Next.js, React, TailwindCSS)
26+
- Customize dataset views, branding, and layouts
27+
- Deploy on Vercel, Netlify, Cloudflare Pages or your own infra
28+
29+
## ✨ Features
30+
31+
- **Modern UI** - Clean, responsive design with Tailwind CSS
32+
- **High Performance** - Built on Next.js 13+ with SSR/SSG
33+
- **CKAN Integration** - Seamless data fetching via @portaljs/ckan
34+
- **TypeScript** - Full type safety and better DX
35+
- **Easy Customizatio**n - Simple theme system and component styling
36+
- **Mobile-First** - Responsive design for all devices
37+
- **Deploy Ready** - One-click deployment to Vercel
38+
39+
## Getting started
40+
41+
### Option 1: PortalJS Cloud
42+
43+
PortalJS Cloud uses this template for creating new portals. If you want to quickly get started for free, follow the steps:
44+
45+
1. **Sign up** at <https://cloud.portaljs.com>
46+
2. **Create portal** → PortalJS Cloud will auto-generate a GitHub repository for your portal (based on this template) and deploy it automatically
47+
3. Find the repo link in your PortalJS Cloud dashboard
48+
4. **Customize** your portal via pull requests — or let us take care of it by reaching out at portaljs@datopian.com
49+
50+
### Option 2: Self-Hosted / Standalone
51+
52+
> [!note]
53+
> In standalone mode, you are going to need your own dedicated CKAN instance.
54+
55+
In order to use this repository in standalone mode (i.e. without PortalJS Cloud), click on the "Use this template" button on the top right corner to replicate this code to a new repo.
56+
57+
Then, you can start customizing it locally by following the development instructions bellow, and/or deploy it somewhere such as on Vercel.
58+
59+
### Development
60+
61+
1) Clone this repository
62+
63+
2) Install the dependencies with `npm i`
64+
65+
3) Create a new `.env` file with:
66+
67+
```bash
68+
# This is the URL of the CKAN instance. Use the example value if you are using PortalJS Cloud.
69+
NEXT_PUBLIC_DMS=https://api.cloud.portaljs.com/@my-portal-main-org-name
70+
```
71+
72+
4) Run `npm run dev` to start the development server
73+
74+
5) Access `http://localhost:3000` in your browser
75+
76+
## Customization
77+
78+
This template was developed with Next.js/React and TailwindCSS.
79+
80+
In order to learn more about how it can be customized, check the following documentations:
81+
82+
- https://react.dev/
83+
- https://nextjs.org/docs
84+
- https://v3.tailwindcss.com/docs/installation
85+
86+
### Quick Customizations
87+
88+
#### Logo Customization
89+
90+
```tsx
91+
// components/_shared/PortalDefaultLogo.tsx
92+
export default function PortalDefaultLogo() {
93+
return (
94+
<Link href="/">
95+
<img src="/your-logo.png" alt="Your Portal" height={55} />
96+
</Link>
97+
);
98+
}
99+
```
100+
101+
#### Footer Links
102+
103+
```tsx
104+
// components/_shared/Footer.tsx - Update navigation object
105+
const navigation = {
106+
about: [
107+
{ name: "About Us", href: "/about" },
108+
{ name: "Contact", href: "/contact" },
109+
],
110+
useful: [
111+
{ name: "Datasets", href: "/search" },
112+
{ name: "Organizations", href: "/organizations" },
113+
],
114+
social: [
115+
{ name: "twitter", href: "https://twitter.com/yourhandle" },
116+
{ name: "email", href: "mailto:contact@yoursite.com" },
117+
],
118+
};
119+
```
120+
121+
#### Homepage Content
122+
123+
```tsx
124+
// pages/index.tsx - Update title and description
125+
<Head>
126+
<title>Your Portal Name</title>
127+
<meta name="description" content="Your portal description" />
128+
</Head>
129+
```
130+
131+
##### Dataset Search
132+
133+
```tsx
134+
// lib/queries/dataset.ts - Add custom facet fields
135+
const facetFields = [
136+
"groups",
137+
"organization",
138+
"res_format",
139+
"tags", // Enable tags
140+
"license_id", // Add license filtering
141+
]
142+
```
143+
144+
#### Theme Components
145+
146+
```tsx
147+
// themes/default/index.tsx - Replace with custom components
148+
const DefaultTheme = {
149+
header: CustomHeader,
150+
footer: CustomFooter,
151+
layout: DefaultThemeLayout,
152+
};
153+
```
154+
155+
---
156+
157+
## Tech Stack
158+
159+
- **Framework:** [Next.js 13+](https://nextjs.org/) with TypeScript
160+
- **Styling:** [Tailwind CSS](https://tailwindcss.com/)
161+
- **Data:** [CKAN API](https://docs.ckan.org/en/2.10/api/) via [@portaljs/ckan](https://www.npmjs.com/package/@portaljs/ckan)
162+
- **Deployment:** [Vercel](https://vercel.com/)
163+
164+
## Deployment
165+
166+
### Vercel (Recommended)
167+
168+
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fdatopian%2Fportaljs-frontend-starter&env=NEXT_PUBLIC_DMS&envDescription=DMS%20endpoint%2C%20e.g.%2C%20a%20CKAN%20instance%20URL.%20For%20testing%20purposes%2C%20you%20can%20use%20https%3A%2F%2Fapi.cloud.portaljs.com%2F&project-name=my-portaljs-app&repository-name=my-portaljs-app)
169+
170+
1. Push your repo to GitHub
171+
2. Connect it on [vercel.com](https://vercel.com/)
172+
3. Add environment variables
173+
4. Deploy! 🎉
174+
175+
#### Other Platforms
176+
177+
This template works on:
178+
- **Netlify** - Connect your GitHub repo
179+
- **Cloudflare Pages** - Import from Git
180+
- **Your server** - `npm run build && npm start`
181+
182+
## Contributing
183+
184+
We welcome contributions! Here's how to get started:
185+
186+
1. **Fork** this repository
187+
2. **Create** a feature branch (`git checkout -b feature/amazing-feature`)
188+
3. **Commit** your changes (`git commit -m 'Add amazing feature'`)
189+
4. **Push** to the branch (`git push origin feature/amazing-feature`)
190+
5. **Open** a Pull Request
191+
192+
## 📄 License
193+
194+
This project is licensed under the [MIT License](https://opensource.org/licenses/MIT).
195+
196+
## Need help or advanced features?
197+
198+
This template covers basic portal functionality. For complex customizations, integrations, or enterprise features, [contact our team](mailto:portaljs@datopian.com) for professional services.
199+
200+
- **Custom Design** - Tailored branding and UI/UX
201+
- **Advanced Features** - Custom integrations and functionality
202+
- **Enterprise Support** - Dedicated support and SLA
203+
- **Migration** - Help moving from existing portals
204+
205+
---
206+
207+
<div align="center">
208+
209+
**Built with ❤️ by [Datopian](https://datopian.com/)**
210+
211+
Let’s build better data portals together 🚀
212+
213+
**⭐️ [Star PortalJS](https://github.com/datopian/portaljs)[🐦 Follow us](https://www.linkedin.com/company/10340373)[💬 Contact](mailto:portaljs@datopian.com)**
214+
215+
**[📚 Docs](https://portaljs.com/docs)[ 🐛 Report a bug or suggest an idea](https://github.com/datopian/portaljs/issues)**
216+
217+
</div>

0 commit comments

Comments
 (0)