1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-29 18:52:22 +01:00

delete & disable packs

This commit is contained in:
Sylvain 2021-06-24 17:59:05 +02:00
parent 1a65b97653
commit 0345d22582
13 changed files with 115 additions and 22 deletions

View File

@ -47,6 +47,6 @@ class API::PrepaidPacksController < API::ApiController
def pack_params
pack_params = params
pack_params[:pack][:amount] = pack_params[:pack][:amount].to_f * 100.0 if pack_params[:pack][:amount]
params.require(:pack).permit(:priceable_id, :priceable_type, :group_id, :amount, :minutes)
params.require(:pack).permit(:priceable_id, :priceable_type, :group_id, :amount, :minutes, :disabled)
end
end

View File

@ -7,6 +7,7 @@ import PrepaidPackAPI from '../../api/prepaid-pack';
import { IFablab } from '../../models/fablab';
import { duration } from 'moment';
import { FabButton } from '../base/fab-button';
import { DeletePack } from './delete-pack';
declare var Fablab: IFablab;
@ -30,7 +31,6 @@ export const ConfigurePacksButton: React.FC<ConfigurePacksButtonProps> = ({ pack
const [showList, setShowList] = useState<boolean>(false);
const [addPackModal, setAddPackModal] = useState<boolean>(false);
const [editPackModal, setEditPackModal] = useState<boolean>(false);
const [deletePackModal, setDeletePackModal] = useState<boolean>(false);
/**
* Return the formatted localized amount for the given price (e.g. 20.5 => "20,50 €")
@ -68,17 +68,10 @@ export const ConfigurePacksButton: React.FC<ConfigurePacksButtonProps> = ({ pack
}
/**
* Open/closes the "confirm delete pack" modal
* Callback triggered when the PrepaidPack was successfully created/deleted/updated.
* We refresh the list of packs for the current tooltip to display the new data.
*/
const toggleRemovePackModal = (): void => {
setDeletePackModal(!deletePackModal);
}
/**
* Callback triggered when the PrepaidPack was successfully created.
* We refresh the list of packs for the current button to get the new one.
*/
const handlePackCreated = (message: string) => {
const handleSuccess = (message: string) => {
onSuccess(message);
PrepaidPackAPI.index({ group_id: groupId, priceable_id: priceableId, priceable_type: priceableType })
.then(data => setPacks(data))
@ -100,11 +93,11 @@ export const ConfigurePacksButton: React.FC<ConfigurePacksButtonProps> = ({ pack
{showList && <FabPopover title={t('app.admin.configure_packs_button.packs')} headerButton={renderAddButton()}>
<ul>
{packs?.map(p =>
<li key={p.id}>
<li key={p.id} className={p.disabled ? 'disabled' : ''}>
{formatDuration(p.minutes)} - {formatPrice(p.amount)}
<span className="pack-actions">
<FabButton className="edit-pack-button" onClick={toggleEditPackModal}><i className="fas fa-edit"/></FabButton>
<FabButton className="remove-pack-button" onClick={toggleRemovePackModal}><i className="fas fa-trash"/></FabButton>
<DeletePack onSuccess={handleSuccess} onError={onError} pack={p} />
</span>
</li>)}
</ul>
@ -112,7 +105,7 @@ export const ConfigurePacksButton: React.FC<ConfigurePacksButtonProps> = ({ pack
</FabPopover>}
<NewPackModal isOpen={addPackModal}
toggleModal={toggleAddPackModal}
onSuccess={handlePackCreated}
onSuccess={handleSuccess}
onError={onError}
groupId={groupId}
priceableId={priceableId}

View File

@ -0,0 +1,67 @@
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { FabButton } from '../base/fab-button';
import { FabModal } from '../base/fab-modal';
import { Loader } from '../base/loader';
import { PrepaidPack } from '../../models/prepaid-pack';
import PrepaidPackAPI from '../../api/prepaid-pack';
interface DeletePackProps {
onSuccess: (message: string) => void,
onError: (message: string) => void,
pack: PrepaidPack,
}
/**
* This component shows a button.
* When clicked, we show a modal dialog to ask the user for confirmation about the deletion of the provided pack.
*/
const DeletePackComponent: React.FC<DeletePackProps> = ({ onSuccess, onError, pack }) => {
const { t } = useTranslation('admin');
const [deletionModal, setDeletionModal] = useState<boolean>(false);
/**
* Opens/closes the deletion modal
*/
const toggleDeletionModal = (): void => {
setDeletionModal(!deletionModal);
};
/**
* The deletion has been confirmed by the user.
* Call the API to trigger the deletion of the temporary set plan-category
*/
const onDeleteConfirmed = (): void => {
PrepaidPackAPI.destroy(pack.id).then(() => {
onSuccess(t('app.admin.delete_pack.pack_deleted'));
}).catch((error) => {
onError(t('app.admin.delete_pack.unable_to_delete') + error);
});
toggleDeletionModal();
};
return (
<div className="delete-pack">
<FabButton type='button' className="remove-pack-button" icon={<i className="fa fa-trash" />} onClick={toggleDeletionModal} />
<FabModal title={t('app.admin.delete_pack.delete_pack')}
isOpen={deletionModal}
toggleModal={toggleDeletionModal}
closeButton={true}
confirmButton={t('app.admin.delete_pack.confirm_delete')}
onConfirm={onDeleteConfirmed}>
<span>{t('app.admin.delete_pack.delete_confirmation')}</span>
</FabModal>
</div>
)
};
export const DeletePack: React.FC<DeletePackProps> = ({ onSuccess, onError, pack }) => {
return (
<Loader>
<DeletePackComponent onSuccess={onSuccess} onError={onError} pack={pack} />
</Loader>
);
}

View File

@ -1,5 +1,6 @@
import React, { BaseSyntheticEvent } from 'react';
import Select from 'react-select';
import Switch from 'react-switch';
import { PrepaidPack } from '../../models/prepaid-pack';
import { useTranslation } from 'react-i18next';
import { useImmer } from 'use-immer';
@ -85,6 +86,15 @@ export const PackForm: React.FC<PackFormProps> = ({ formId, onSubmit, packData }
});
}
/**
* Callback triggered when the user disables the pack.
*/
const handleUpdateDisabled = (checked: boolean) => {
updatePack(draft => {
draft.disabled = checked;
})
}
return (
<form id={formId} onSubmit={handleSubmit} className="pack-form">
<label htmlFor="hours">{t('app.admin.pack_form.hours')} *</label>
@ -119,6 +129,10 @@ export const PackForm: React.FC<PackFormProps> = ({ formId, onSubmit, packData }
onChange={handleUpdateValidityInterval}
options={buildOptions()} />
</div>
<label htmlFor="disabled">{t('app.admin.pack_form.disabled')}</label>
<div>
<Switch checked={pack?.disabled || false} onChange={handleUpdateDisabled} id="disabled" />
</div>
</form>
);
}

View File

@ -15,4 +15,5 @@ export interface PrepaidPack {
minutes: number,
amount: number,
usages?: number,
disabled?: boolean,
}

View File

@ -60,5 +60,6 @@
@import "modules/pricing/editable-price";
@import "modules/pricing/configure-packs-button";
@import "modules/pricing/pack-form";
@import "modules/pricing/delete-pack";
@import "app.responsive";

View File

@ -44,16 +44,16 @@
line-height: 24px;
}
.pack-actions > button {
.pack-actions button {
font-size: 10px;
vertical-align: middle;
line-height: 10px;
height: auto;
}
&.remove-pack-button {
background-color: #cb1117;
color: white;
}
&.disabled {
background-color: #eeeeee;
color: #999999;
}
}
}

View File

@ -0,0 +1,8 @@
.delete-pack {
display: inline;
.remove-pack-button {
background-color: #cb1117;
color: white;
}
}

View File

@ -1,5 +1,5 @@
# frozen_string_literal: true
json.extract! pack, :id, :priceable_id, :priceable_type, :group_id, :validity_interval, :validity_count, :minutes
json.extract! pack, :id, :priceable_id, :priceable_type, :group_id, :validity_interval, :validity_count, :minutes, :disabled
json.amount pack.amount / 100.0
json.usages pack.statistic_profile_prepaid_packs.count

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
json.array! @packs do |pack|
json.extract! pack, :priceable_id, :priceable_type, :group_id, :minutes
json.extract! pack, :id, :priceable_id, :priceable_type, :group_id, :minutes, :disabled
json.amount pack.amount / 100.0
end

View File

@ -381,6 +381,7 @@ en:
pack_form:
hours: "Hours"
amount: "Price"
disabled: "Disabled"
validity_count: "Maximum validity"
select_interval: "Interval..."
intervals:
@ -393,6 +394,12 @@ en:
new_pack_info: "A prepaid pack allows users to buy {TYPE, select, Machine{machine} Space{space} other{}} hours before booking any slots. These packs can provide discounts on volumes purchases."
create_pack: "Create this pack"
pack_successfully_created: "The new prepaid pack was successfully created."
delete_pack:
pack_deleted: "The prepaid pack was successfully deleted."
unable_to_delete: "Unable to delete the prepaid pack: "
delete_pack: "Delete the prepaid pack"
confirm_delete: "Delete"
delete_confirmation: "Are you sure you want to delete this prepaid pack? This won't be possible if the pack was already bought by users."
#ajouter un code promotionnel
coupons_new:
add_a_coupon: "Add a coupon"

View File

@ -10,6 +10,7 @@ class CreatePrepaidPacks < ActiveRecord::Migration[5.2]
t.integer :minutes
t.string :validity_interval
t.integer :validity_count
t.boolean :disabled
t.timestamps
end

View File

@ -1727,6 +1727,7 @@ CREATE TABLE public.prepaid_packs (
minutes integer,
validity_interval character varying,
validity_count integer,
disabled boolean,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
);