Skip to content

Commit

Permalink
Paramètres du calendrier (affichage uniquement) (#302)
Browse files Browse the repository at this point in the history
  • Loading branch information
Donov4n committed Jan 8, 2022
1 parent d944e78 commit c69a7ce
Show file tree
Hide file tree
Showing 10 changed files with 212 additions and 0 deletions.
3 changes: 3 additions & 0 deletions client/src/components/Button/_variables.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/// Marge entre l'icône et le texte des boutons (quand il y en a une, d'icône)
/// @type Number
$icon-margin: 0.3571rem !default;
21 changes: 21 additions & 0 deletions client/src/components/Button/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@use './variables' as *;

.Button {
// - Icône
&::before,
&__icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 1.1em;
height: 1.1em;
font-size: 1.1em;
line-height: 1.35em;
text-align: center;
vertical-align: -0.05rem;
}

&__icon + &__content {
margin-left: $icon-margin;
}
}
78 changes: 78 additions & 0 deletions client/src/components/Button/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import './index.scss';
import { toRefs, computed } from '@vue/composition-api';
import Icon from '@/components/Icon';

import type { Component, SetupContext } from '@vue/composition-api';
import type { Props as IconProps } from '@/components/Icon';

type Props = {
/**
* Le type de bouton pour l'attribut `type` de la balise `<button>`?
*
* Options disponibles: `submit`, `button` ou `reset`.
*/
htmlType?: 'submit' | 'button' | 'reset',

/**
* Le code de l'éventuelle icône qui sera ajoutée au bouton.
*
* Pour utiliser une variante de l'icône, vous pouvez suffixer le nom de l'icône avec `:[variante]`.
* Par exemple: `plus:solid` ou `birthday-cake:regular`.
*
* Voir le component <Icon> concernant la liste des codes et les variantes possibles.
*/
icon?: string | undefined,

/** Le bouton est-il désactivé ? */
disabled?: boolean,

/** Des éventuelles classes supplémentaires qui seront ajoutées au component. */
class?: string,
};

// @vue/component
const Button: Component<Props> = (props: Props, { slots }: SetupContext) => {
const { htmlType, icon, disabled } = toRefs(props as Required<Props>);
const _icon = computed<IconProps | null>(() => {
if (!icon.value) {
return null;
}

if (!icon.value.includes(':')) {
return { name: icon.value };
}

const [iconType, variant] = icon.value.split(':');
return { name: iconType, variant: variant as any };
});

const _className = ['Button', {
'Button--with-icon': !!_icon,
}];

return () => {
const children = slots.default?.();

return (
// eslint-disable-next-line react/button-has-type
<button type={htmlType.value} class={_className} disabled={disabled.value}>
{_icon.value && <Icon {...{ props: _icon.value } as any} class="Button__icon" />}
{children && <span class="Button__content">{children}</span>}
</button>
);
};
};

Button.props = {
htmlType: {
default: 'button',
validator: (value: unknown) => (
typeof value === 'string' &&
['button', 'submit', 'reset'].includes(value)
),
},
icon: { type: String, default: undefined },
disabled: { type: Boolean, default: false },
};

export default Button;
4 changes: 4 additions & 0 deletions client/src/components/FormField/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
width: 90%;
}

&__switch {
display: flex;
}

&__addon {
display: inline-block;
min-width: 2.7rem;
Expand Down
44 changes: 44 additions & 0 deletions client/src/components/Icon/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { toRefs, computed } from '@vue/composition-api';

import type { Component } from '@vue/composition-api';

export type Props = {
/**
* Le nom de l'icône à afficher.
*
* Pour une liste exhaustive des codes, voir : https://fontawesome.com/v5.15/icons?m=free
*/
name: string,

/** Quelle variante faut-il utiliser pour l'icône ? */
variant?: 'regular' | 'solid' | 'brands',

/** Des éventuelles classes supplémentaires qui seront ajoutées au component. */
class?: string,
};

const VARIANT_MAP = {
'regular': 'far',
'solid': 'fas',
'brands': 'fab',
} as const;

// @vue/component
const Icon: Component<Props> = (props: Props) => {
const { name, variant } = toRefs(props as Required<Props>);
const baseClass = computed(() => VARIANT_MAP[variant.value]);
return () => <i class={[baseClass.value, `fa-${name.value}`]} aria-hidden="true" />;
};

Icon.props = {
name: { type: String, required: true },
variant: {
default: 'solid',
validator: (value: unknown) => (
typeof value === 'string' &&
['solid', 'regular', 'brands'].includes(value)
),
},
};

export default Icon;
3 changes: 3 additions & 0 deletions client/src/locale/en/pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,9 @@ export default {
'custom-text-content': "Text content",
'saved': "Event summaries settings were successfully saved.",
},
'calendar': {
'title': "Calendar",
},
},

'page-estimate': {
Expand Down
3 changes: 3 additions & 0 deletions client/src/locale/fr/pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,9 @@ export default {
'custom-text-content': "Contenu du texte",
'saved': "Les paramètres des fiches de sortie ont bien été sauvegardés.",
},
'calendar': {
'title': "Calendrier",
},
},

'page-estimate': {
Expand Down
48 changes: 48 additions & 0 deletions client/src/pages/Settings/Calendar/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { ref } from '@vue/composition-api';
import useI18n from '@/hooks/useI18n';
import FormField from '@/components/FormField';
import Button from '@/components/Button';

import type { Component } from '@vue/composition-api';

// @vue/component
const CalendarSettings: Component = () => {
const __ = useI18n();
const isSaving = ref(false);

const handleSubmit = (e: SubmitEvent): void => {
e.preventDefault();
};

return () => (
<div class="CalendarSettings">
<form class="CalendarSettings__form" onSubmit={handleSubmit}>
<section class="CalendarSettings__section">
<h3>Données affichées dans les événements du calendrier</h3>
<FormField
type="switch"
label="Afficher le lieu de l'événement ?"
name="calendar.event.showLocation"
/>
<FormField
type="switch"
label="Afficher le bénéficiaire / emprunteur ?"
name="calendar.event.showBorrower"
/>
</section>
<section class="CalendarSettings__actions">
<Button
icon="save"
htmlType="submit"
class="success"
disabled={isSaving.value}
>
{isSaving.value ? __('saving') : __('save')}
</Button>
</section>
</form>
</div>
);
};

export default CalendarSettings;
1 change: 1 addition & 0 deletions client/src/pages/Settings/EventSummary/Form/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import './index.scss';
import getFormDataAsJson from '@/utils/getFormDataAsJson';
import FormField from '@/components/FormField';
import getFormDataAsJson from '@/utils/getFormDataAsJson';

const LIST_MODES = ['categories', 'sub-categories', 'parks', 'flat'];

Expand Down
7 changes: 7 additions & 0 deletions client/src/pages/Settings/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Tabs, Tab } from 'vue-slim-tabs';
import EventSummarySettings from './EventSummary';
import CalendarSettings from './Calendar';

// @vue/component
export default {
Expand All @@ -15,9 +16,15 @@ export default {
<template slot="event-summary">
<i class="fas fa-print" /> {__('page-settings.event-summary.title')}
</template>
<template slot="calendar">
<i class="fas fa-calendar-alt" /> {__('page-settings.calendar.title')}
</template>
<Tab title-slot="event-summary">
<EventSummarySettings />
</Tab>
<Tab title-slot="calendar">
<CalendarSettings />
</Tab>
</Tabs>
</div>
</div>
Expand Down

0 comments on commit c69a7ce

Please sign in to comment.