@rssa-project/study-template 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -0
- package/README.md +49 -0
- package/dist/App.d.ts +2 -0
- package/dist/components/CodeInput.d.ts +7 -0
- package/dist/components/ContinueFormModal.d.ts +9 -0
- package/dist/components/ErrorBoundary.d.ts +15 -0
- package/dist/components/LoadingText.d.ts +6 -0
- package/dist/components/PaginatedDataViewer.d.ts +9 -0
- package/dist/components/Select.d.ts +7 -0
- package/dist/components/TestFeedbackModal.d.ts +10 -0
- package/dist/components/TestModeConfirmation.d.ts +7 -0
- package/dist/components/TestModeIndicator.d.ts +6 -0
- package/dist/components/TestModeToast.d.ts +10 -0
- package/dist/components/loadingscreen/LoadingScreen.d.ts +7 -0
- package/dist/components/moviegallery/MovieCard.d.ts +7 -0
- package/dist/components/moviegallery/StarRating.d.ts +6 -0
- package/dist/components/warningDialog.d.ts +12 -0
- package/dist/constants.d.ts +11 -0
- package/dist/contexts/NextButtonContext.d.ts +12 -0
- package/dist/contexts/NextButtonControlProvider.d.ts +3 -0
- package/dist/contexts/StudyUrlParamsContext.d.ts +12 -0
- package/dist/contexts/pageCompletionContext.d.ts +4 -0
- package/dist/contexts/stepCompletionContext.d.ts +4 -0
- package/dist/hooks/useDebounce.d.ts +1 -0
- package/dist/hooks/useNextButtonControl.d.ts +1 -0
- package/dist/hooks/usePageCompletion.d.ts +7 -0
- package/dist/hooks/useStepCompletion.d.ts +7 -0
- package/dist/index.d.ts +26 -0
- package/dist/layouts/StudyFooter.d.ts +2 -0
- package/dist/layouts/StudyHeader.d.ts +5 -0
- package/dist/layouts/StudyLayout.d.ts +6 -0
- package/dist/layouts/WelcomeFooter.d.ts +8 -0
- package/dist/layouts/templates/ContentBlock.d.ts +7 -0
- package/dist/layouts/templates/ItemBlock.d.ts +11 -0
- package/dist/layouts/templates/SurveyTemplate.d.ts +6 -0
- package/dist/main.d.ts +0 -0
- package/dist/pages/ConsentPage.d.ts +21 -0
- package/dist/pages/DemographicsPage.d.ts +2 -0
- package/dist/pages/FeedbackPage.d.ts +16 -0
- package/dist/pages/FinalPage.d.ts +3 -0
- package/dist/pages/MovieRatingPage.d.ts +7 -0
- package/dist/pages/StudyExitPage.d.ts +3 -0
- package/dist/pages/SurveyPage.d.ts +2 -0
- package/dist/pages/WelcomePage.d.ts +18 -0
- package/dist/res/country_state.json.d.ts +970 -0
- package/dist/routes/RouteWrapper.d.ts +13 -0
- package/dist/rssa-study-template.es.js +8989 -0
- package/dist/types/rssa.types.d.ts +142 -0
- package/dist/types/study.types.d.ts +5 -0
- package/dist/utils/constants.d.ts +11 -0
- package/dist/vite.svg +1 -0
- package/package.json +83 -0
package/LICENSE
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
MIT License
|
package/README.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# RSSA Study Template (@rssa-project/study-template)
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@rssa-project/study-template)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
A React component library providing standard layouts, pages, and hooks for building research studies on the RSSA Platform. It creates a consistent UI and logic flow (consent -> survey -> stimuli -> feedback) across different RSSA studies.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @rssa-project/study-template
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
Wrap your main router with the `RouteWrapper`, ensuring you pass a component map mapping step types to your page components.
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
import { RouteWrapper, WelcomePage, SurveyPage, FinalPage } from '@rssa-project/study-template';
|
|
20
|
+
import UserCustomPage from './UserCustomPage';
|
|
21
|
+
|
|
22
|
+
// Map 'step_type' from your study config to React components
|
|
23
|
+
const componentMap = {
|
|
24
|
+
welcome: WelcomePage,
|
|
25
|
+
survey: SurveyPage,
|
|
26
|
+
custom_task: UserCustomPage,
|
|
27
|
+
completion: FinalPage,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
function App() {
|
|
31
|
+
return (
|
|
32
|
+
<Router>
|
|
33
|
+
{/* RouteWrapper handles navigation logic based on study state */}
|
|
34
|
+
<RouteWrapper componentMap={componentMap} WelcomePage={WelcomePage} />
|
|
35
|
+
</Router>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Core Features
|
|
41
|
+
|
|
42
|
+
- **Standard Pages**: `ConsentPage`, `SurveyPage`, `MovieRatingPage`, `DemographicsPage`.
|
|
43
|
+
- **Hooks**: `useNextButtonControl`, `useStepCompletion`.
|
|
44
|
+
- **Contexts**: Handles participant state and navigation flow automatically.
|
|
45
|
+
|
|
46
|
+
## Requirements
|
|
47
|
+
|
|
48
|
+
- React 18+
|
|
49
|
+
- `@rssa-project/api` (Peer Dependency)
|
package/dist/App.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Component, ErrorInfo, ReactNode } from 'react';
|
|
2
|
+
interface Props {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
}
|
|
5
|
+
interface State {
|
|
6
|
+
hasError: boolean;
|
|
7
|
+
errorMessage: string;
|
|
8
|
+
}
|
|
9
|
+
declare class ErrorBoundary extends Component<Props, State> {
|
|
10
|
+
state: State;
|
|
11
|
+
static getDerivedStateFromError(error: Error): State;
|
|
12
|
+
componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
|
|
13
|
+
render(): string | number | bigint | boolean | import("react/jsx-runtime").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import('react').ReactPortal | import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null | undefined;
|
|
14
|
+
}
|
|
15
|
+
export default ErrorBoundary;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface PaginatedResourceViewerProps<T> {
|
|
2
|
+
apiResourceTag: string;
|
|
3
|
+
limit?: number;
|
|
4
|
+
children: (data: T[], selectedItem: T | null, handleItemClick: (item: T) => void) => React.ReactNode;
|
|
5
|
+
}
|
|
6
|
+
declare const PaginatedResourceViewer: <T extends {
|
|
7
|
+
id: string;
|
|
8
|
+
}>({ apiResourceTag, limit, children, }: PaginatedResourceViewerProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export default PaginatedResourceViewer;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
declare const Select: ({ onChange, children, placeholder, className, }: {
|
|
2
|
+
onChange: (value: string | boolean | number | null) => void;
|
|
3
|
+
children: React.ReactNode[];
|
|
4
|
+
placeholder?: string;
|
|
5
|
+
className?: string;
|
|
6
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default Select;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { StudyStep } from '../types/rssa.types';
|
|
2
|
+
import { ToastType } from './TestModeToast';
|
|
3
|
+
interface TestFeedbackModalProps {
|
|
4
|
+
isOpen: boolean;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
studyStep?: StudyStep;
|
|
7
|
+
onShowToast: (message: string, type: ToastType) => void;
|
|
8
|
+
}
|
|
9
|
+
declare const TestFeedbackModal: React.FC<TestFeedbackModalProps>;
|
|
10
|
+
export default TestFeedbackModal;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type ToastType = "success" | "error";
|
|
2
|
+
interface TestModeToastProps {
|
|
3
|
+
show: boolean;
|
|
4
|
+
message: string;
|
|
5
|
+
type: ToastType;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
duration?: number;
|
|
8
|
+
}
|
|
9
|
+
declare const TestModeToast: React.FC<TestModeToastProps>;
|
|
10
|
+
export default TestModeToast;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { MovieDetails, RatedItem } from '../../types/rssa.types';
|
|
2
|
+
declare const MovieCard: ({ movie, userRating, onClick, }: {
|
|
3
|
+
movie: MovieDetails;
|
|
4
|
+
userRating: RatedItem | undefined;
|
|
5
|
+
onClick: () => void;
|
|
6
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default MovieCard;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface WarningDialogProps {
|
|
2
|
+
show: boolean;
|
|
3
|
+
title: string;
|
|
4
|
+
message: string;
|
|
5
|
+
onClose: (show: boolean) => void;
|
|
6
|
+
confirmCallback?: () => void;
|
|
7
|
+
confirmText?: string;
|
|
8
|
+
cancelCallback?: () => void;
|
|
9
|
+
disableHide?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare const WarningDialog: React.FC<WarningDialogProps>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Dispatch, SetStateAction } from 'react';
|
|
2
|
+
export interface NextButtonControl {
|
|
3
|
+
label: string;
|
|
4
|
+
action: () => void;
|
|
5
|
+
isDisabled: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare const defaultControl: NextButtonControl;
|
|
8
|
+
export interface NextButtonContextType {
|
|
9
|
+
setButtonControl: Dispatch<SetStateAction<NextButtonControl>>;
|
|
10
|
+
buttonControl: NextButtonControl;
|
|
11
|
+
}
|
|
12
|
+
export declare const NextButtonContext: import('react').Context<NextButtonContextType | null>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { default as React, ReactNode } from 'react';
|
|
2
|
+
interface StudyUrlParams {
|
|
3
|
+
participantTypeKey: string;
|
|
4
|
+
externalId: string;
|
|
5
|
+
isTestMode: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare const useStudyUrlParams: () => StudyUrlParams;
|
|
8
|
+
export declare const StudyUrlParamsProvider: React.FC<{
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
params: StudyUrlParams;
|
|
11
|
+
}>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function useDebounce<T>(value: T, delay: number): T;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useNextButtonControl: () => import('..').NextButtonContextType;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
interface PageCompletionContextType {
|
|
2
|
+
isPageComplete: boolean;
|
|
3
|
+
setIsPageComplete: (isComplete: boolean) => void;
|
|
4
|
+
}
|
|
5
|
+
export declare const PageCompletionContext: import('react').Context<PageCompletionContextType | undefined>;
|
|
6
|
+
export declare const usePageCompletion: () => PageCompletionContextType;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
interface StepCompletionContextType {
|
|
2
|
+
isStepComplete: boolean;
|
|
3
|
+
setIsStepComplete: (isComplete: boolean) => void;
|
|
4
|
+
}
|
|
5
|
+
export declare const StepCompletionContext: import('react').Context<StepCompletionContextType | undefined>;
|
|
6
|
+
export declare const useStepCompletion: () => StepCompletionContextType;
|
|
7
|
+
export {};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export { default as RouteWrapper } from './routes/RouteWrapper';
|
|
2
|
+
export { default as StudyLayout } from './layouts/StudyLayout';
|
|
3
|
+
export { default as LoadingScreen } from './components/loadingscreen/LoadingScreen';
|
|
4
|
+
export { default as ErrorBoundary } from './components/ErrorBoundary';
|
|
5
|
+
export * from './types/rssa.types.ts';
|
|
6
|
+
export * from './types/study.types.ts';
|
|
7
|
+
export * from './hooks/useStepCompletion';
|
|
8
|
+
export * from './hooks/useNextButtonControl';
|
|
9
|
+
export * from './hooks/usePageCompletion';
|
|
10
|
+
export * from './contexts/stepCompletionContext';
|
|
11
|
+
export * from './contexts/NextButtonControlProvider';
|
|
12
|
+
export * from './contexts/NextButtonContext';
|
|
13
|
+
export * from './contexts/pageCompletionContext';
|
|
14
|
+
export { default as SurveyPage } from './pages/SurveyPage';
|
|
15
|
+
export { default as SurveyTemplate } from './layouts/templates/SurveyTemplate';
|
|
16
|
+
export { default as WelcomePage } from './pages/WelcomePage';
|
|
17
|
+
export { default as ConsentPage } from './pages/ConsentPage';
|
|
18
|
+
export { default as MovieRatingPage } from './pages/MovieRatingPage';
|
|
19
|
+
export { default as MovieCard } from './components/moviegallery/MovieCard';
|
|
20
|
+
export { default as StarRating } from './components/moviegallery/StarRating';
|
|
21
|
+
export { default as DemographicsPage } from './pages/DemographicsPage';
|
|
22
|
+
export { default as FeedbackPage } from './pages/FeedbackPage';
|
|
23
|
+
export { default as LoadingText } from './components/LoadingText';
|
|
24
|
+
export { default as FinalPage } from './pages/FinalPage';
|
|
25
|
+
export { WarningDialog } from './components/warningDialog';
|
|
26
|
+
export * from './hooks/useDebounce';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ScaleLevel, SurveyConstructItem, SurveyItemResponse } from '../../types/rssa.types';
|
|
2
|
+
interface ItemBlockProps {
|
|
3
|
+
contextTag: string;
|
|
4
|
+
pageId: string;
|
|
5
|
+
item: SurveyConstructItem;
|
|
6
|
+
initialResponse: SurveyItemResponse | undefined;
|
|
7
|
+
scaleLevels: ScaleLevel[];
|
|
8
|
+
onSelected: (itemId: string) => void;
|
|
9
|
+
}
|
|
10
|
+
declare const ItemBlock: React.FC<ItemBlockProps>;
|
|
11
|
+
export default ItemBlock;
|
package/dist/main.d.ts
ADDED
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface BaseParticipant {
|
|
2
|
+
participant_type_key: string;
|
|
3
|
+
external_id: string;
|
|
4
|
+
current_step_id: string;
|
|
5
|
+
current_page_id?: string | null;
|
|
6
|
+
}
|
|
7
|
+
export interface ParticipantTokenObject {
|
|
8
|
+
resume_code: string;
|
|
9
|
+
token: string;
|
|
10
|
+
}
|
|
11
|
+
interface ConsentPageProps {
|
|
12
|
+
children: React.ReactNode;
|
|
13
|
+
participantTypeKey?: string;
|
|
14
|
+
participantTypeId?: string;
|
|
15
|
+
externalId?: string;
|
|
16
|
+
onConsentSuccess?: (token: string, resumeCode: string) => void;
|
|
17
|
+
title?: string;
|
|
18
|
+
itemTitle?: string;
|
|
19
|
+
}
|
|
20
|
+
declare const ConsentPage: React.FC<ConsentPageProps>;
|
|
21
|
+
export default ConsentPage;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export type Feedback = {
|
|
3
|
+
feedback_text: string;
|
|
4
|
+
feedback_type: string;
|
|
5
|
+
feedback_category: string;
|
|
6
|
+
study_step_id: string;
|
|
7
|
+
context_tag: string;
|
|
8
|
+
};
|
|
9
|
+
export type TextResponsePayload = {
|
|
10
|
+
study_step_id: string;
|
|
11
|
+
study_step_page_id?: string;
|
|
12
|
+
context_tag: string;
|
|
13
|
+
response_text: string;
|
|
14
|
+
};
|
|
15
|
+
declare const FeedbackPage: React.FC;
|
|
16
|
+
export default FeedbackPage;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface ResumePayload {
|
|
2
|
+
resume_code: string;
|
|
3
|
+
}
|
|
4
|
+
export interface ResumeResponse {
|
|
5
|
+
current_step_id: string;
|
|
6
|
+
current_page_id: string;
|
|
7
|
+
token: string;
|
|
8
|
+
}
|
|
9
|
+
interface WelcomePageProps {
|
|
10
|
+
isStudyReady?: boolean;
|
|
11
|
+
onStudyStart?: () => void;
|
|
12
|
+
title?: string;
|
|
13
|
+
subtitle?: string;
|
|
14
|
+
ContentComponent?: React.FC;
|
|
15
|
+
children?: React.ReactNode;
|
|
16
|
+
}
|
|
17
|
+
declare const WelcomePage: React.FC<WelcomePageProps>;
|
|
18
|
+
export default WelcomePage;
|