Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

9 interview card data #24

Merged
merged 5 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8,138 changes: 4,698 additions & 3,440 deletions .pnp.cjs

Large diffs are not rendered by default.

1,249 changes: 878 additions & 371 deletions .pnp.loader.mjs

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
{
"recommendations": ["arcanis.vscode-zipfs", "dbaeumer.vscode-eslint"]
"recommendations": [
"arcanis.vscode-zipfs",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
]
}
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
},
"eslint.nodePath": ".yarn/sdks",
"typescript.tsdk": ".yarn/sdks/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
"typescript.enablePromptUseWorkspaceTsdk": true,
"prettier.prettierPath": ".yarn/sdks/prettier/index.cjs"
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed .yarn/cache/has-npm-1.0.3-b7f00631c1-a449f3185b.zip
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed .yarn/cache/open-npm-9.1.0-d104a17ec5-b45bcc7a67.zip
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion .yarnrc.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
yarnPath: ".yarn/releases/yarn-3.6.1.cjs"
yarnPath: '.yarn/releases/yarn-3.6.1.cjs'
6 changes: 0 additions & 6 deletions formSources.config.js

This file was deleted.

4 changes: 2 additions & 2 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ const isProd = process.env.NODE_ENV === 'production';

const nextConfig = {
output: 'export',
basePath: isProd ? '/courtformsonline.org' : '',
assetPrefix: isProd ? '/courtformsonline.org' : '',
// basePath: isProd ? '/courtformsonline.org' : '',
// assetPrefix: isProd ? '/courtformsonline.org' : '',
images: {
unoptimized: true,
},
Expand Down
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"dev": "next",
"build": "next build",
"start": "next start",
"start": "serve out",
"lint": "next lint",
"format": "prettier --write .",
"test:format": "prettier --check 'src/**/*.js'"
Expand All @@ -28,7 +28,9 @@
"react-bootstrap": "^2.7.4",
"react-dom": "18.2.0",
"react-icons": "^5.0.1",
"reactstrap": "^9.1.9"
"reactstrap": "^9.1.9",
"serve": "^14.2.3",
"swr": "^2.2.5"
},
"devDependencies": {
"@types/bootstrap": "^5.2.6",
Expand Down
2 changes: 1 addition & 1 deletion src/app/[topic]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { GetStaticPathsResult } from 'next';
import { legalTopics, Topic } from '../../../topics.config';
import { legalTopics, Topic } from '../../config/topics.config';

interface PageProps {
params: {
Expand Down
57 changes: 57 additions & 0 deletions src/app/components/TopicCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import Link from 'next/link';

interface TopicCardProps {
topic: {
name: string;
long_name: string;
icon: string;
};
interviews: any[];
}

interface IconProps {
iconName: string;
className?: string;
style?: React.CSSProperties;
}

const FontAwesomeIcon = ({ iconName, className = '' }: IconProps) => {
return <i className={`fas fa-${iconName} ${className}`}></i>;
};

const TopicCard = ({ topic, interviews }: TopicCardProps) => {
// Display the first 3 interviews, and show a final tag with how many remaining interviews are not shown
const displayInterviews = interviews.slice(0, 3);
const extraCount = interviews.length > 3 ? interviews.length - 3 : 0;

return (
<div className="col-lg-4">
<Link
href={`/${topic.name.toLowerCase()}`}
className="text-decoration-none text-dark"
>
<div className="card m-1 topic-card h-100">
<div className="card-header d-flex align-items-center">
<div
style={{ minWidth: '40px', minHeight: '40px' }}
className="icon-container d-inline-flex justify-content-center align-items-center rounded"
>
<FontAwesomeIcon iconName={topic.icon} className="fa-icon" />
</div>
<h5 className="card-title ms-3">{topic.long_name}</h5>
</div>
<div className="card-body">
{displayInterviews.map((interview, index) => (
<span key={index} className="form-tag">
{interview.metadata.title}
</span>
))}
{extraCount > 0 && <span className="form-tag">+{extraCount}</span>}
</div>
</div>
</Link>
</div>
);
};

export default TopicCard;
25 changes: 13 additions & 12 deletions src/app/forms/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Form } from '../interfaces/Form';
import InteractiveForm from '../components/InteractiveForm';
import serverList from '../../../formSources.config.js';
import { formSources } from '../../config/formSources.config';

interface LegalFormsPageProps {
forms: Form[];
Expand All @@ -9,33 +9,34 @@ interface LegalFormsPageProps {
async function getData() {
let allData: Form[] = [];

for (const [serverName, serverUrl] of Object.entries(
serverList['docassemble servers']
)) {
const url = new URL(serverUrl);
// Iterating over an array of server objects
for (const server of formSources.docassembleServers) {
const url = new URL(server.url); // Access the URL directly from the server object
url.pathname = '/list';
url.search = 'json=1';

const res = await fetch(url);
const res = await fetch(url.toString());

// Recommendation: handle errors
// Handle errors
if (!res.ok) {
console.error(`Failed to fetch data from ${serverUrl}`);
console.error(`Failed to fetch data from ${server.url}`);
continue; // Skip this server and continue with the next one
}

const data = await res.json();

if (!data.hasOwnProperty('interviews')) {
console.error(`Data from ${serverUrl} does not contain "interviews" key`);
console.error(
`Data from ${server.url} does not contain "interviews" key`
);
continue; // Skip this server and continue with the next one
}

// If you want to include the server name and server URL in the data:
// Include the server name and server URL in the data
const interviews = data['interviews'].map((interview: Form) => ({
...interview,
serverName,
serverUrl,
serverName: server.name,
serverUrl: server.url,
}));

allData = allData.concat(interviews);
Expand Down
104 changes: 19 additions & 85 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,75 +1,14 @@
import Link from 'next/link';
import React from 'react';
import HeroSection from './components/HeroSection';
import HowItWorksSection from './components/HowItWorksSection';
import { Topic } from '../../topics.config';
import { fetchInterviews } from '../data/fetchInterviewData';
import TopicCard from './components/TopicCard';
import { legalTopics } from '../config/topics.config';

const { legalTopics, findParentTopic } = require('../../topics.config.ts');
export default async function TopicsPage() {
const interviewsResult = await fetchInterviews();
const { interviewsByTopic } = interviewsResult;

interface IconProps {
iconName: string;
className: string;
}

const FontAwesomeIcon: React.FC<IconProps> = ({ iconName, className = '' }) => {
return <i className={`fas fa-${iconName} ${className}`}></i>;
};

const fakeFormNames = [
'Fee waiver',
'209A Domestic Violence Restraining Order',
'Enlarge Time to File (Appeals Court)',
'Appeal or Stay Your Eviction',
'Eviction Moratorium',
'Civil Docketing Statement',
'Massachusetts Defense for Eviction (MADE)',
'Dismiss your CRA case',
'Interpreter Notice',
'Petition to Change Name of Adult',
];

const getRandomItems = (arr: Array<string>, min: number, max: number) => {
const newArr = [...arr]; // Copy array to avoid mutating the original one.
let count = Math.floor(min + Math.random() * (max - min + 1));
let result: Array<string> = [];
while (count--) {
result.push(newArr.splice(Math.floor(Math.random() * newArr.length), 1)[0]);
}
return result;
};

// const formPill

const TopicCard = ({ topic }: { topic: Topic }) => (
<div className="col-lg-4">
<Link
href={`/${topic.name.toLowerCase()}`}
className="text-decoration-none text-dark"
>
<div className="card m-1 topic-card h-100">
<div className="card-header d-flex align-items-center">
<div
style={{ minWidth: '40px', minHeight: '40px' }}
className="icon-container d-inline-flex justify-content-center align-items-center rounded"
>
<FontAwesomeIcon iconName={topic.icon} className="fa-icon" />
</div>
<h5 className="card-title ms-3">{topic.long_name}</h5>
</div>
<div className="card-body">
{getRandomItems(fakeFormNames, 2, 5).map((form: string) => (
<span key={form} className="form-tag">
{form}
</span>
))}
<span className="form-tag">+2</span>
</div>
</div>
</Link>
</div>
);

export default function TopicsPage() {
return (
<div>
<HeroSection />
Expand All @@ -79,29 +18,24 @@ export default function TopicsPage() {
<h2>Browse court forms by category</h2>
<div className="row row-cols-1 row-cols-md-3 g-5">
{legalTopics
.sort((a: Topic, b: Topic) => (a.priority < b.priority ? 1 : -1))
.filter((topic: Topic) => topic.always_visible)
.map((topic: Topic) => (
<TopicCard key={topic.codes[0]} topic={topic} />
.sort((a, b) => b.priority - a.priority)
.filter(
(topic) =>
topic.always_visible ||
(interviewsByTopic[topic.name] &&
interviewsByTopic[topic.name].length > 0)
)
Comment on lines +22 to +27
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LIST is a hierarchical code. 209A, which is FA-07-00-00-00, should go into the "Family" topic but it's getting sorted into Other

image

image

.map((topic) => (
<TopicCard
key={topic.codes[0]}
topic={topic}
interviews={interviewsByTopic[topic.name] || []}
/>
))}
</div>
<Link href="#">Show all categories</Link>
</div>
</section>
<div className="container">
<div className="row mt-4">
<div className="col">
<h2>About</h2>
<p>
Court Forms Online is operated by Suffolk University Law School's
Legal Innovation and Technology Lab. It began as a volunteer
project in cooperation with the Massachusetts Access to Justice
Commission's COVID-19 task force and volunteers from around the
world. <Link href="/about">Learn more...</Link>
</p>
</div>
</div>
</div>
</div>
);
}
14 changes: 14 additions & 0 deletions src/config/formSources.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export const formSources = {
docassembleServers: [
{
key: 'suffolkListLab',
url: 'https://apps.suffolklitlab.org',
name: 'Suffolk LIT Lab',
},
{
key: 'greaterBostonLegalService',
url: 'https://interviews.gbls.org',
name: 'Greater Boston Legal Services',
},
],
};
Loading