Skip to content
Draft
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
44 changes: 44 additions & 0 deletions env.config.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { DemographicsFields } from "@openedx/openedx-demographics-plugin";
import {
DIRECT_PLUGIN,
PLUGIN_OPERATIONS,
} from "@openedx/frontend-plugin-framework";

function addPlugins(config, slot_name, plugins) {
if (slot_name in config.pluginSlots === false) {
config.pluginSlots[slot_name] = {
keepDefault: true,
plugins: [],
};
}

config.pluginSlots[slot_name].plugins.push(...plugins);
}

async function setConfig() {
let config = {
pluginSlots: {},
};

try {
addPlugins(config, "org.openedx.frontend.authn.register.additional_fields.v1", [
{
op: PLUGIN_OPERATIONS.Insert,
widget: {
id: "demographics_fields",
type: DIRECT_PLUGIN,
priority: 50,
RenderWidget: DemographicsFields,
},
},
]);
} catch (err) {
console.error("env.config.jsx failed to apply: ", err);
}

// eslint-disable-next-line no-console
console.log("[env.config] setConfig returning:", JSON.stringify(config, null, 2));
return config;
}

export default setConfig;
13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"@fortawesome/free-solid-svg-icons": "6.7.2",
"@fortawesome/react-fontawesome": "0.2.6",
"@openedx/frontend-plugin-framework": "^1.7.0",
"@openedx/openedx-demographics-plugin": "file:../oex26-demographics-plugin/frontend/openedx-demographics-plugin-0.1.0.tgz",
"@openedx/paragon": "^23.4.2",
"@optimizely/react-sdk": "^2.9.1",
"@tanstack/react-query": "^5.90.19",
Expand Down
60 changes: 60 additions & 0 deletions src/plugin-slots/RegisterAdditionalFieldsSlot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# RegisterAdditionalFieldsSlot

### Slot ID

`org.openedx.frontend.authn.register.additional_fields.v1`

### Plugin Props

| Name | Type | Description |
| -------------- | ------------------------------- | ----------------------------------------------------------------- |
| `formFields` | `Record<string, string>` | Current values of every field in the registration form. |
| `setFormField` | `(event: ChangeEvent) => void` | Form change handler — call with a synthetic event whose `target` |
| | | has `name` and `value` to update form state. |

### Description

Renders just above the **Create Account** submit button. Use this slot
to append optional fields whose values should travel with the standard
registration POST. The plugin component is responsible for its own
layout but should match Paragon form spacing for visual consistency.

Fields written via `setFormField` are submitted as part of `request.POST`
to the LMS registration view alongside the built-in fields.

### Example usage

```jsx
import { Form } from '@openedx/paragon';

const DemographicsFields = ({ formFields, setFormField }) => (
<>
<Form.Group>
<Form.Control
name="pronouns"
floatingLabel="Pronouns (optional)"
value={formFields.pronouns || ''}
onChange={setFormField}
/>
</Form.Group>
<Form.Group>
<Form.Control
as="select"
name="department"
floatingLabel="Department (optional)"
value={formFields.department || ''}
onChange={setFormField}
>
<option value="">—</option>
<option value="eng">Engineering</option>
<option value="ops">Operations</option>
<option value="edu">Education</option>
</Form.Control>
</Form.Group>
</>
);
```

The companion backend plugin
(`openedx-registration-demographics-plugin`) validates these fields via
the `StudentRegistrationRequested` filter and persists them on receipt
22 changes: 22 additions & 0 deletions src/plugin-slots/RegisterAdditionalFieldsSlot/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import PropTypes from 'prop-types';
import { PluginSlot } from '@openedx/frontend-plugin-framework';

const RegisterAdditionalFieldsSlot = ({ formFields, setFormField }) => {
// eslint-disable-next-line no-console
console.log('[RegisterAdditionalFieldsSlot] rendering, formFields keys:', Object.keys(formFields));
return (
<PluginSlot
id="org.openedx.frontend.authn.register.additional_fields.v1"
pluginProps={{ formFields, setFormField }}
/>
);
}

RegisterAdditionalFieldsSlot.propTypes = {
// eslint-disable-next-line react/forbid-prop-types
formFields: PropTypes.object.isRequired,
setFormField: PropTypes.func.isRequired,
};

export default RegisterAdditionalFieldsSlot;

6 changes: 6 additions & 0 deletions src/register/RegistrationPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
import {
getAllPossibleQueryParams, getTpaHint, getTpaProvider, isHostAvailableInQueryParams, setCookie,
} from '../data/utils';
import RegisterAdditionalFieldsSlot from '../plugin-slots/RegisterAdditionalFieldsSlot';
import { useRegisterContext } from './components/RegisterContext';
/**
* Inner Registration Page component that uses the context
Expand Down Expand Up @@ -391,6 +392,11 @@ const RegistrationPage = (props) => {
autoSubmitRegisterForm={autoSubmitRegForm}
fieldDescriptions={fieldDescriptions}
/>

<RegisterAdditionalFieldsSlot
formFields={formFields}
setFormField={handleOnChange}
/>
<StatefulButton
id="register-user"
name="register-user"
Expand Down
6 changes: 4 additions & 2 deletions webpack.prod.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
const { createConfig } = require('@openedx/frontend-build');
const { createConfig } = require("@openedx/frontend-build");

const config = createConfig('webpack-prod');
const config = createConfig("webpack-prod");

config.module.rules[0].exclude = /node_modules\/(?!(fastest-levenshtein|@edx))/;
config.module.rules[0].exclude =
/node_modules\/(?!(fastest-levenshtein|@(open)?edx))/;

module.exports = config;
Loading