@devmayo/lms-sdk-nextjs
v1.3.10
Published
This package provides an SDK for integrating `@devmayo/lms-sdk` functionalities within Next.js applications. It is designed to work seamlessly with Next.js version 14.1.0 and React 18, facilitating the development of learning management systems (LMS) with
Readme
@devmayo/lms-sdk-nextjs
This package provides an SDK for integrating @devmayo/lms-sdk functionalities within Next.js applications. It is designed to work seamlessly with Next.js version 14.1.0 and React 18, facilitating the development of learning management systems (LMS) with modern web technologies.
Installation
To install @devmayo/lms-sdk-nextjs, run the following commands in your project directory:
npm install @devmayo/lms-sdk @devmayo/lms-sdk-nextjsOR
yarn add @devmayo/lms-sdk @devmayo/lms-sdk-nextjsUsage
In order to use the register form provided by the SDK you have to do the following:
First create an environment file with the following env variable:
LMS_URL=https://<yourlmsurl.com>/apiChange <yourlmsurl.com> for the url of your LMS.
‼️ Important ‼️
This env variable will be available only in server side, that means that all the methods provided by the SDK that have API logic, have to be called in server side.
Once you have configured the environment, and to start using the RegisterForm component and registerAction provided by the SDK, you have to do the following:
First you'll need to import the styles provided by the sdk in your root layout file
// app/layout.tsx
import '@devmayo/lms-sdk-nextjs/dist/index.css';Then you have to wrap both, the component and the action, by your own client component and server action respectively. For example:
// your-action-wrapper.ts
'use server';
import { registerAction } from '@devmayo/lms-sdk-nextjs';
export const registerActionWrapper = registerAction;And then use the action in your component wrapper, you'll need to define your own state and pass it to the component. Like the following:
// your-component-wrapper.tsx
'use client';
import { RegisterForm } from '@devmayo/lms-sdk-nextjs';
import { registerActionWrapper } from './action';
import { useFormState } from 'react-dom';
const initialState: Record<string, any> = {
errors: {},
message: null
};
export default function Home() {
const [state, action] = useFormState(registerActionWrapper, initialState);
return (
<form action={action}>
<RegisterForm state={state} />
</form>
);
}This will render the form with the fields defined in the registerFieldsService, if you need to modify, ovewrite, add or remove fields, then you can do it inside of your-component-wrapper.tsx file, like this:
// your-component-wrapper.tsx
'use client';
import { RegisterForm } from '@devmayo/lms-sdk-nextjs';
import { registerActionWrapper } from './action';
import { registerFieldsService } from '@devmayo/lms-sdk';
import { useFormState } from 'react-dom';
const initialState: Record<string, any> = {
errors: {},
message: null
};
// here you can modify, ovewrite, add or remove fields using the service provided
// for example, to modify the return_url you can do the following:
registerFieldsService.findOneAndUpdate('return_url', {
value: 'https://grupomayo.com/'
})
export default function Home() {
const [state, action] = useFormState(registerActionWrapper, initialState);
return (
<form action={action}>
<RegisterForm state={state} />
</form>
);
}If you need to modify, ovewrite, add or remove specialties, then you can do it inside of your-component-wrapper.tsx file, like this:
// your-component-wrapper.tsx
'use client';
import { RegisterForm } from '@devmayo/lms-sdk-nextjs';
import { registerActionWrapper } from './action';
import { registerFieldsService } from '@devmayo/lms-sdk';
import { useFormState } from 'react-dom';
const initialState: Record<string, any> = {
errors: {},
message: null
};
// here you can modify, ovewrite, add or remove specialties using the service provided
// for example, to add a specialty you can do the following:
specialtiesService.add({
label: 'Specialty',
value: 'Specialty',
order: 0,
});
// It's important after adding, modifying or removing specialties, perform a refresh of the form fields.
// This have to be done AFTER all the modifications to the specialties and BEFORE all the modifications to the fields
registerFieldsService.refresh()
// here you can modify, ovewrite, add or remove fields using the service provided
// for example, to modify the return_url you can do the following:
registerFieldsService.findOneAndUpdate('return_url', {
value: 'https://grupomayo.com/'
})
export default function Home() {
const [state, action] = useFormState(registerActionWrapper, initialState);
return (
<form action={action}>
<RegisterForm state={state} />
</form>
);
}For executing some actions, like perform a redirect or display a modal, you can pass an onFail and an onSuccess to the component. onSuccess will be executed when the registration is completed and recieve as an argument the values of the fields. onFail will be executed when something fail, like field validation errors or postcode not found, as an argument you'll recieve the state with information about the corresponding error
// your-component-wrapper.tsx
'use client';
import { RegisterForm } from '@devmayo/lms-sdk-nextjs';
import { registerActionWrapper } from './action';
import { useFormState } from 'react-dom';
export default function Home() {
const [state, action] = useFormState(registerActionWrapper, initialState);
function onSuccess(values: any) {
console.log('values on success', values);
}
function onFail(state: any) {
console.log('state on fail', state);
}
return (
<form action={action}>
<RegisterForm state={state} onFail={onFail} onSuccess={onSuccess} />
</form>
);
}If you want to change the styling of the inputs, you have 2 options:
First one, you can pass a prop to the form component with a dictionary defining the new components for each field type you want to overwrite
// your-component-wrapper.tsx
'use client';
import { RegisterForm } from '@devmayo/lms-sdk-nextjs';
import { registerActionWrapper } from './action';
import { useFormState } from 'react-dom';
import { FieldTypes, RegisterField } from '@devmayo/lms-sdk';
export default function Home() {
const [state, action] = useFormState(registerActionWrapper, initialState);
function onSuccess(values: any) {
console.log('values on success', values);
}
function onFail(state: any) {
console.log('state on fail', state);
}
const componentsMap: Record<string, React.ComponentType<RegisterField>> = {
[FieldTypes.TEXT]: (props: TextInputProps) => /* Your component here */,
// ...more field types to overwrite
}
return (
<form action={action}>
<RegisterForm state={state} onFail={onFail} onSuccess={onSuccess} customComponents={componentsMap} />
</form>
);
}The custom components will recieve as props everything you need to handle the logic and errors of that field, for example, the default TextInput component will look like this:
// text-input.tsx
import { ErrorMessage } from '../atoms/error-message';
import { Input, InputProps } from '../atoms/input';
import { Label } from '../atoms/label';
export type TextInputProps = Omit<InputProps, 'id' | 'type'> & {
label: string;
id?: string;
errorMessage?: string | null;
type?: string;
};
export function TextInput({ type = 'text', name = '', placeholder, label, id = '', required = false, errorMessage, value, onChange, disabled }: TextInputProps) {
return (
<div className={`flex flex-col p-2 gap-2 min-w-max`}>
<Label label={label} htmlFor={name} />
<Input type={type} name={name} placeholder={placeholder} id={id} value={value} required={required} hasError={errorMessage != null} onChange={onChange} disabled={disabled} />
{errorMessage && <ErrorMessage message={errorMessage} />}
</div>
);
}
// input.tsx
export interface InputProps {
id: string;
type: string;
name: string;
placeholder?: string;
required?: boolean;
hasError?: boolean;
value?: string;
stateValue?: string;
disabled?: boolean;
checked?: boolean;
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
onKeyUp?: (event: React.KeyboardEvent<HTMLInputElement>) => void;
}
export function Input({ disabled, type, stateValue, name, placeholder, id, required = false, hasError = false, value, onChange, onKeyUp, checked }: InputProps) {
return (
<input
id={id}
disabled={disabled}
type={type}
required={required}
className={`py-1 px-3 text-xs rounded-md ${hasError ? 'border-2 border-red-500' : 'border border-black'}`}
name={name}
defaultChecked={checked}
placeholder={placeholder}
defaultValue={value}
value={stateValue}
onChange={onChange}
onKeyDown={onKeyUp}
/>
);
}Second, you can use the stylesService like the following:
import { StylesEnum, stylesService } from '@devmayo/lms-sdk';
stylesService.set(StylesEnum.LABEL, 'text-yellow-900 font-bold text-3xl');
stylesService.set(StylesEnum.ERROR_MESSAGE, 'text-green-500 text-2xl');
stylesService.set(StylesEnum.BORDDER_ON_ERROR, 'border-2 border-blue-500');you have all of these options in StylesEnum available for modification:
- LABEL
- INPUT
- SELECT
- RADIO
- CHECKBOX
- ERROR_MESSAGE
- BORDER_ON_ERROR
Change Log
Version 1.1.4
- Disable tailwind preflight
Version 1.1.3
- Fix tailwind classes not created
Version 1.1.2
- Add prefix to all tailwind's classes
Version 1.1.0
- Integrate with the new styles service
- Remove the default submit button in form component
Version 1.0.1
- Fix no css file on build result
Version 1.0.0
- Add the
RegisterFormcomponent. - Add the
registerActionserver action. - Integrate with the
@devmayo/lms-sdk
