mirror of
https://ghproxy.net/https://github.com/abhijitb/helix.git
synced 2025-08-29 08:12:07 +08:00
folder restructuring for pages
This commit is contained in:
parent
c1e7525a3a
commit
4f35d58a47
19 changed files with 26 additions and 27 deletions
|
@ -1,15 +1,15 @@
|
|||
import React, { useState } from 'react';
|
||||
import { useSettings } from './Settings/hooks/useSettings';
|
||||
import SettingsTabs from './Settings/components/SettingsTabs';
|
||||
import SaveButton from './Settings/components/SaveButton';
|
||||
import Notification from './Settings/components/Notification';
|
||||
import SiteInformationSettings from './Settings/components/SiteInformationSettings';
|
||||
import ContentReadingSettings from './Settings/components/ContentReadingSettings';
|
||||
import WritingPublishingSettings from './Settings/components/WritingPublishingSettings';
|
||||
import MediaAssetsSettings from './Settings/components/MediaAssetsSettings';
|
||||
import UsersMembershipSettings from './Settings/components/UsersMembershipSettings';
|
||||
import HelixSettings from './Settings/components/HelixSettings';
|
||||
import './Settings/styles.css';
|
||||
import { useSettings } from './hooks/useSettings';
|
||||
import SettingsTabs from './components/SettingsTabs';
|
||||
import SaveButton from '../../components/SaveButton';
|
||||
import Notification from '../../components/Notification';
|
||||
import SiteInformationSettings from './components/SiteInformationSettings';
|
||||
import ContentReadingSettings from './components/ContentReadingSettings';
|
||||
import WritingPublishingSettings from './components/WritingPublishingSettings';
|
||||
import MediaAssetsSettings from './components/MediaAssetsSettings';
|
||||
import UsersMembershipSettings from './components/UsersMembershipSettings';
|
||||
import HelixSettings from './components/HelixSettings';
|
||||
import './settings.css';
|
||||
|
||||
/**
|
||||
* Main Settings Page Component
|
|
@ -1,9 +1,9 @@
|
|||
import React from 'react';
|
||||
import SettingsSection from './SettingsSection';
|
||||
import SelectInput from './SelectInput';
|
||||
import NumberInput from './NumberInput';
|
||||
import ToggleInput from './ToggleInput';
|
||||
import TextInput from './TextInput';
|
||||
import SelectInput from '../../../components/SelectInput';
|
||||
import NumberInput from '../../../components/NumberInput';
|
||||
import ToggleInput from '../../../components/ToggleInput';
|
||||
import TextInput from '../../../components/TextInput';
|
||||
|
||||
/**
|
||||
* Content & Reading Settings Component
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
import React from 'react';
|
||||
|
||||
/**
|
||||
* Form field wrapper component
|
||||
* @param root0
|
||||
* @param root0.label
|
||||
* @param root0.description
|
||||
* @param root0.error
|
||||
* @param root0.required
|
||||
* @param root0.children
|
||||
* @param root0.className
|
||||
*/
|
||||
const FormField = ( {
|
||||
label,
|
||||
description,
|
||||
error,
|
||||
required = false,
|
||||
children,
|
||||
className = '',
|
||||
} ) => {
|
||||
return (
|
||||
<div className={ `helix-form-field ${ className }` }>
|
||||
{ label && (
|
||||
<label className="helix-form-label">
|
||||
{ label }
|
||||
{ required && <span className="helix-required">*</span> }
|
||||
</label>
|
||||
) }
|
||||
|
||||
<div className="helix-form-control">{ children }</div>
|
||||
|
||||
{ description && (
|
||||
<p className="helix-form-description">{ description }</p>
|
||||
) }
|
||||
|
||||
{ error && <p className="helix-form-error">{ error }</p> }
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FormField;
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import SettingsSection from './SettingsSection';
|
||||
import ToggleInput from './ToggleInput';
|
||||
import ToggleInput from '../../../components/ToggleInput';
|
||||
|
||||
/**
|
||||
* Helix Specific Settings Component
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import SettingsSection from './SettingsSection';
|
||||
import NumberInput from './NumberInput';
|
||||
import ToggleInput from './ToggleInput';
|
||||
import NumberInput from '../../../components/NumberInput';
|
||||
import ToggleInput from '../../../components/ToggleInput';
|
||||
|
||||
/**
|
||||
* Media & Assets Settings Component
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
|
||||
/**
|
||||
* Notification component for displaying success/error messages
|
||||
* @param root0
|
||||
* @param root0.type
|
||||
* @param root0.message
|
||||
* @param root0.onClose
|
||||
* @param root0.autoClose
|
||||
* @param root0.duration
|
||||
*/
|
||||
const Notification = ( {
|
||||
type = 'info',
|
||||
message,
|
||||
onClose,
|
||||
autoClose = true,
|
||||
duration = 5000,
|
||||
} ) => {
|
||||
const [ visible, setVisible ] = useState( true );
|
||||
|
||||
useEffect( () => {
|
||||
if ( autoClose && duration > 0 ) {
|
||||
const timer = setTimeout( () => {
|
||||
setVisible( false );
|
||||
setTimeout( () => onClose?.(), 300 ); // Allow fade out animation
|
||||
}, duration );
|
||||
|
||||
return () => clearTimeout( timer );
|
||||
}
|
||||
}, [ autoClose, duration, onClose ] );
|
||||
|
||||
if ( ! visible ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const getIcon = () => {
|
||||
switch ( type ) {
|
||||
case 'success':
|
||||
return '✅';
|
||||
case 'error':
|
||||
return '❌';
|
||||
case 'warning':
|
||||
return '⚠️';
|
||||
default:
|
||||
return 'ℹ️';
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={ `helix-notification helix-notification-${ type } ${
|
||||
visible ? 'visible' : ''
|
||||
}` }
|
||||
>
|
||||
<div className="helix-notification-content">
|
||||
<span className="helix-notification-icon">{ getIcon() }</span>
|
||||
<span className="helix-notification-message">{ message }</span>
|
||||
{ onClose && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={ () => {
|
||||
setVisible( false );
|
||||
setTimeout( () => onClose(), 300 );
|
||||
} }
|
||||
className="helix-notification-close"
|
||||
aria-label="Close notification"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
) }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Notification;
|
|
@ -1,63 +0,0 @@
|
|||
import React from 'react';
|
||||
import FormField from './FormField';
|
||||
|
||||
/**
|
||||
* Number input component
|
||||
* @param root0
|
||||
* @param root0.label
|
||||
* @param root0.description
|
||||
* @param root0.value
|
||||
* @param root0.onChange
|
||||
* @param root0.min
|
||||
* @param root0.max
|
||||
* @param root0.step
|
||||
* @param root0.required
|
||||
* @param root0.disabled
|
||||
* @param root0.error
|
||||
* @param root0.className
|
||||
*/
|
||||
const NumberInput = ( {
|
||||
label,
|
||||
description,
|
||||
value,
|
||||
onChange,
|
||||
min = null,
|
||||
max = null,
|
||||
step = 1,
|
||||
required = false,
|
||||
disabled = false,
|
||||
error = null,
|
||||
className = '',
|
||||
...props
|
||||
} ) => {
|
||||
const handleChange = ( event ) => {
|
||||
const newValue = event.target.value;
|
||||
// Convert to number if not empty, otherwise keep as empty string
|
||||
onChange( newValue === '' ? '' : Number( newValue ) );
|
||||
};
|
||||
|
||||
return (
|
||||
<FormField
|
||||
label={ label }
|
||||
description={ description }
|
||||
error={ error }
|
||||
required={ required }
|
||||
className={ className }
|
||||
>
|
||||
<input
|
||||
type="number"
|
||||
value={ value || '' }
|
||||
onChange={ handleChange }
|
||||
min={ min }
|
||||
max={ max }
|
||||
step={ step }
|
||||
required={ required }
|
||||
disabled={ disabled }
|
||||
className="helix-number-input"
|
||||
{ ...props }
|
||||
/>
|
||||
</FormField>
|
||||
);
|
||||
};
|
||||
|
||||
export default NumberInput;
|
|
@ -1,56 +0,0 @@
|
|||
import React from 'react';
|
||||
|
||||
/**
|
||||
* Save button component with loading and status indicators
|
||||
* @param root0
|
||||
* @param root0.onSave
|
||||
* @param root0.onReset
|
||||
* @param root0.saving
|
||||
* @param root0.hasUnsavedChanges
|
||||
* @param root0.disabled
|
||||
*/
|
||||
const SaveButton = ( {
|
||||
onSave,
|
||||
onReset,
|
||||
saving = false,
|
||||
hasUnsavedChanges = false,
|
||||
disabled = false,
|
||||
} ) => {
|
||||
return (
|
||||
<div className="helix-save-buttons">
|
||||
<button
|
||||
type="button"
|
||||
onClick={ onSave }
|
||||
disabled={ disabled || saving || ! hasUnsavedChanges }
|
||||
className={ `helix-btn helix-btn-primary ${
|
||||
saving ? 'saving' : ''
|
||||
}` }
|
||||
>
|
||||
{ saving ? (
|
||||
<>
|
||||
<span className="helix-spinner"></span>
|
||||
Saving...
|
||||
</>
|
||||
) : (
|
||||
'Save Changes'
|
||||
) }
|
||||
</button>
|
||||
|
||||
{ hasUnsavedChanges && ! saving && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={ onReset }
|
||||
className="helix-btn helix-btn-secondary"
|
||||
>
|
||||
Reset Changes
|
||||
</button>
|
||||
) }
|
||||
|
||||
{ ! hasUnsavedChanges && ! saving && (
|
||||
<span className="helix-save-status">✓ All changes saved</span>
|
||||
) }
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SaveButton;
|
|
@ -1,66 +0,0 @@
|
|||
import React from 'react';
|
||||
import FormField from './FormField';
|
||||
|
||||
/**
|
||||
* Select input component
|
||||
* @param root0
|
||||
* @param root0.label
|
||||
* @param root0.description
|
||||
* @param root0.value
|
||||
* @param root0.onChange
|
||||
* @param root0.options
|
||||
* @param root0.required
|
||||
* @param root0.disabled
|
||||
* @param root0.error
|
||||
* @param root0.className
|
||||
* @param root0.placeholder
|
||||
*/
|
||||
const SelectInput = ( {
|
||||
label,
|
||||
description,
|
||||
value,
|
||||
onChange,
|
||||
options = [],
|
||||
required = false,
|
||||
disabled = false,
|
||||
error = null,
|
||||
className = '',
|
||||
placeholder = 'Select an option...',
|
||||
...props
|
||||
} ) => {
|
||||
const handleChange = ( event ) => {
|
||||
onChange( event.target.value );
|
||||
};
|
||||
|
||||
return (
|
||||
<FormField
|
||||
label={ label }
|
||||
description={ description }
|
||||
error={ error }
|
||||
required={ required }
|
||||
className={ className }
|
||||
>
|
||||
<select
|
||||
value={ value || '' }
|
||||
onChange={ handleChange }
|
||||
required={ required }
|
||||
disabled={ disabled }
|
||||
className="helix-select-input"
|
||||
{ ...props }
|
||||
>
|
||||
{ placeholder && (
|
||||
<option value="" disabled>
|
||||
{ placeholder }
|
||||
</option>
|
||||
) }
|
||||
{ options.map( ( option ) => (
|
||||
<option key={ option.value } value={ option.value }>
|
||||
{ option.label }
|
||||
</option>
|
||||
) ) }
|
||||
</select>
|
||||
</FormField>
|
||||
);
|
||||
};
|
||||
|
||||
export default SelectInput;
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import SettingsSection from './SettingsSection';
|
||||
import TextInput from './TextInput';
|
||||
import TextInput from '../../../components/TextInput';
|
||||
|
||||
/**
|
||||
* Site Information Settings Component
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
import React from 'react';
|
||||
import FormField from './FormField';
|
||||
|
||||
/**
|
||||
* Text input component
|
||||
* @param root0
|
||||
* @param root0.label
|
||||
* @param root0.description
|
||||
* @param root0.value
|
||||
* @param root0.onChange
|
||||
* @param root0.placeholder
|
||||
* @param root0.type
|
||||
* @param root0.required
|
||||
* @param root0.disabled
|
||||
* @param root0.error
|
||||
* @param root0.className
|
||||
*/
|
||||
const TextInput = ( {
|
||||
label,
|
||||
description,
|
||||
value,
|
||||
onChange,
|
||||
placeholder = '',
|
||||
type = 'text',
|
||||
required = false,
|
||||
disabled = false,
|
||||
error = null,
|
||||
className = '',
|
||||
...props
|
||||
} ) => {
|
||||
const handleChange = ( event ) => {
|
||||
onChange( event.target.value );
|
||||
};
|
||||
|
||||
return (
|
||||
<FormField
|
||||
label={ label }
|
||||
description={ description }
|
||||
error={ error }
|
||||
required={ required }
|
||||
className={ className }
|
||||
>
|
||||
<input
|
||||
type={ type }
|
||||
value={ value || '' }
|
||||
onChange={ handleChange }
|
||||
placeholder={ placeholder }
|
||||
required={ required }
|
||||
disabled={ disabled }
|
||||
className="helix-text-input"
|
||||
{ ...props }
|
||||
/>
|
||||
</FormField>
|
||||
);
|
||||
};
|
||||
|
||||
export default TextInput;
|
|
@ -1,55 +0,0 @@
|
|||
import React from 'react';
|
||||
import FormField from './FormField';
|
||||
|
||||
/**
|
||||
* Toggle/Checkbox input component
|
||||
* @param root0
|
||||
* @param root0.label
|
||||
* @param root0.description
|
||||
* @param root0.value
|
||||
* @param root0.onChange
|
||||
* @param root0.required
|
||||
* @param root0.disabled
|
||||
* @param root0.error
|
||||
* @param root0.className
|
||||
*/
|
||||
const ToggleInput = ( {
|
||||
label,
|
||||
description,
|
||||
value,
|
||||
onChange,
|
||||
required = false,
|
||||
disabled = false,
|
||||
error = null,
|
||||
className = '',
|
||||
...props
|
||||
} ) => {
|
||||
const handleChange = ( event ) => {
|
||||
onChange( event.target.checked );
|
||||
};
|
||||
|
||||
return (
|
||||
<FormField
|
||||
description={ description }
|
||||
error={ error }
|
||||
required={ required }
|
||||
className={ `helix-toggle-field ${ className }` }
|
||||
>
|
||||
<label className="helix-toggle-wrapper">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={ !! value }
|
||||
onChange={ handleChange }
|
||||
required={ required }
|
||||
disabled={ disabled }
|
||||
className="helix-toggle-input"
|
||||
{ ...props }
|
||||
/>
|
||||
<span className="helix-toggle-slider"></span>
|
||||
<span className="helix-toggle-label">{ label }</span>
|
||||
</label>
|
||||
</FormField>
|
||||
);
|
||||
};
|
||||
|
||||
export default ToggleInput;
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import SettingsSection from './SettingsSection';
|
||||
import SelectInput from './SelectInput';
|
||||
import ToggleInput from './ToggleInput';
|
||||
import SelectInput from '../../../components/SelectInput';
|
||||
import ToggleInput from '../../../components/ToggleInput';
|
||||
|
||||
/**
|
||||
* Users & Membership Settings Component
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import React from 'react';
|
||||
import SettingsSection from './SettingsSection';
|
||||
import SelectInput from './SelectInput';
|
||||
import NumberInput from './NumberInput';
|
||||
import ToggleInput from './ToggleInput';
|
||||
import SelectInput from '../../../components/SelectInput';
|
||||
import NumberInput from '../../../components/NumberInput';
|
||||
import ToggleInput from '../../../components/ToggleInput';
|
||||
|
||||
/**
|
||||
* Writing & Publishing Settings Component
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue