mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-22 11:52:21 +01:00
Merge branch 'dev' into staging
This commit is contained in:
commit
ebf157c099
@ -6,6 +6,7 @@
|
||||
- Add extra_authorize_params to OpenIdConnect config
|
||||
- Improvement : add a notification to remind users to upload their supporting documents
|
||||
- Cancel payment schedule subscription after update the payment mean
|
||||
- admin can see reservations of a member
|
||||
|
||||
## v6.0.14 2023 September 6
|
||||
|
||||
|
@ -6,9 +6,11 @@ import { useTranslation } from 'react-i18next';
|
||||
import { Credit, CreditableType } from '../../../models/credit';
|
||||
import CreditAPI from '../../../api/credit';
|
||||
import { HtmlTranslate } from '../../base/html-translate';
|
||||
import { User } from '../../../models/user';
|
||||
|
||||
interface CreditsPanelProps {
|
||||
userId: number,
|
||||
currentUser?: User,
|
||||
onError: (message: string) => void,
|
||||
reservableType: CreditableType
|
||||
}
|
||||
@ -16,7 +18,7 @@ interface CreditsPanelProps {
|
||||
/**
|
||||
* List all available credits for the given user and the given resource
|
||||
*/
|
||||
const CreditsPanel: React.FC<CreditsPanelProps> = ({ userId, onError, reservableType }) => {
|
||||
const CreditsPanel: React.FC<CreditsPanelProps> = ({ userId, currentUser = null, onError, reservableType }) => {
|
||||
const { t } = useTranslation('logged');
|
||||
|
||||
const [credits, setCredits] = useState<Array<Credit>>([]);
|
||||
@ -37,16 +39,30 @@ const CreditsPanel: React.FC<CreditsPanelProps> = ({ userId, onError, reservable
|
||||
/**
|
||||
* Display a placeholder when there's no credits to display
|
||||
*/
|
||||
const noCredits = (): ReactNode => {
|
||||
const noCredits = (currentUser: User): ReactNode => {
|
||||
return (
|
||||
<div className="fab-alert fab-alert--warning">{t('app.logged.dashboard.reservations_dashboard.credits_panel.no_credits')}</div>
|
||||
<div className="fab-alert fab-alert--warning">{t(`app.logged.dashboard.reservations_dashboard.${translationKeyPrefix(currentUser)}.no_credits`) /* eslint-disable-line fabmanager/scoped-translation */ }</div>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* returns true if there is a currentUser and current user is manager or admin
|
||||
*/
|
||||
const currentUserIsAdminOrManager = (currentUser: User): boolean => {
|
||||
return currentUser && (currentUser.role === 'admin' || currentUser.role === 'manager');
|
||||
};
|
||||
|
||||
/**
|
||||
* returns translation key prefix
|
||||
*/
|
||||
const translationKeyPrefix = (currentUser: User): string => {
|
||||
return currentUserIsAdminOrManager(currentUser) ? 'credits_panel_as_admin' : 'credits_panel';
|
||||
};
|
||||
|
||||
return (
|
||||
<FabPanel className="credits-panel">
|
||||
<p className="title">{t('app.logged.dashboard.reservations_dashboard.credits_panel.title')}</p>
|
||||
{credits.length !== 0 &&
|
||||
<p className="title">{t(`app.logged.dashboard.reservations_dashboard.${translationKeyPrefix(currentUser)}.title`) /* eslint-disable-line fabmanager/scoped-translation */}</p>
|
||||
{credits.length !== 0 && !currentUserIsAdminOrManager(currentUser) &&
|
||||
<div className="fab-alert fab-alert--warning">
|
||||
{t('app.logged.dashboard.reservations_dashboard.credits_panel.info')}
|
||||
</div>
|
||||
@ -56,14 +72,14 @@ const CreditsPanel: React.FC<CreditsPanelProps> = ({ userId, onError, reservable
|
||||
{credits.map(c => <div key={c.id} className="credits-list-item">
|
||||
<p className="title">{c.creditable.name}</p>
|
||||
<p>
|
||||
<HtmlTranslate trKey="app.logged.dashboard.reservations_dashboard.credits_panel.remaining_credits_html" options={{ REMAINING: remainingHours(c) }} /><br />
|
||||
<HtmlTranslate trKey={`app.logged.dashboard.reservations_dashboard.${translationKeyPrefix(currentUser)}.remaining_credits_html` /* eslint-disable-line fabmanager/scoped-translation */} options={{ REMAINING: remainingHours(c) }} /><br />
|
||||
{(c.hours_used && c.hours_used > 0) &&
|
||||
<HtmlTranslate trKey="app.logged.dashboard.reservations_dashboard.credits_panel.used_credits_html" options={{ USED: c.hours_used }} />
|
||||
<HtmlTranslate trKey={`app.logged.dashboard.reservations_dashboard.${translationKeyPrefix(currentUser)}.used_credits_html` /* eslint-disable-line fabmanager/scoped-translation */} options={{ USED: c.hours_used }} />
|
||||
}
|
||||
</p>
|
||||
</div>)}
|
||||
</div>
|
||||
{credits.length === 0 && noCredits()}
|
||||
{credits.length === 0 && noCredits(currentUser)}
|
||||
</FabPanel>
|
||||
);
|
||||
};
|
||||
|
@ -21,13 +21,14 @@ import { HtmlTranslate } from '../../base/html-translate';
|
||||
|
||||
interface PrepaidPacksPanelProps {
|
||||
user: User,
|
||||
currentUser?: User,
|
||||
onError: (message: string) => void
|
||||
}
|
||||
|
||||
/**
|
||||
* List all available prepaid packs for the given user
|
||||
*/
|
||||
const PrepaidPacksPanel: React.FC<PrepaidPacksPanelProps> = ({ user, onError }) => {
|
||||
const PrepaidPacksPanel: React.FC<PrepaidPacksPanelProps> = ({ user, currentUser = null, onError }) => {
|
||||
const { t } = useTranslation('logged');
|
||||
|
||||
const [machines, setMachines] = useState<Array<Machine>>([]);
|
||||
@ -101,6 +102,20 @@ const PrepaidPacksPanel: React.FC<PrepaidPacksPanelProps> = ({ user, onError })
|
||||
return (packs.length > 0 && (!packsForSubscribers || (packsForSubscribers && user.subscribed_plan != null)));
|
||||
};
|
||||
|
||||
/**
|
||||
* returns true if there is a currentUser and current user is manager or admin
|
||||
*/
|
||||
const currentUserIsAdminOrManager = (currentUser: User): boolean => {
|
||||
return currentUser && (currentUser.role === 'admin' || currentUser.role === 'manager');
|
||||
};
|
||||
|
||||
/**
|
||||
* returns translation key prefix
|
||||
*/
|
||||
const translationKeyPrefix = (currentUser: User): string => {
|
||||
return currentUserIsAdminOrManager(currentUser) ? 'prepaid_packs_panel_as_admin' : 'prepaid_packs_panel';
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback triggered when a prepaid pack was successfully bought: refresh the list of packs for the user
|
||||
*/
|
||||
@ -113,7 +128,7 @@ const PrepaidPacksPanel: React.FC<PrepaidPacksPanelProps> = ({ user, onError })
|
||||
|
||||
return (
|
||||
<FabPanel className='prepaid-packs-panel'>
|
||||
<p className="title">{t('app.logged.dashboard.reservations_dashboard.prepaid_packs_panel.title')}</p>
|
||||
<p className="title">{t(`app.logged.dashboard.reservations_dashboard.${translationKeyPrefix(currentUser)}.title`) /* eslint-disable-line fabmanager/scoped-translation */}</p>
|
||||
|
||||
{userPacks.map(pack => (
|
||||
<div className={`prepaid-packs ${isLow(pack) ? 'is-low' : ''}`} key={pack.id}>
|
||||
@ -124,7 +139,7 @@ const PrepaidPacksPanel: React.FC<PrepaidPacksPanelProps> = ({ user, onError })
|
||||
|
||||
<div className='prepaid-packs-list-item'>
|
||||
<p className='name'>{pack.prepaid_pack.priceable.name}</p>
|
||||
{FormatLib.date(pack.expires_at) && <p className="end">{FormatLib.date(pack.expires_at)}</p>}
|
||||
{pack.expires_at && FormatLib.date(pack.expires_at) && <p className="end">{FormatLib.date(pack.expires_at)}</p>}
|
||||
<p className="countdown"><span>{(pack.prepaid_pack.minutes - pack.minutes_used) / 60}H</span> / {pack.prepaid_pack.minutes / 60}H</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -143,7 +158,7 @@ const PrepaidPacksPanel: React.FC<PrepaidPacksPanelProps> = ({ user, onError })
|
||||
</div>
|
||||
))}
|
||||
|
||||
{canBuyPacks() && <div className='prepaid-packs-cta'>
|
||||
{canBuyPacks() && !currentUserIsAdminOrManager(currentUser) && <div className='prepaid-packs-cta'>
|
||||
<p>{t('app.logged.dashboard.reservations_dashboard.prepaid_packs_panel.cta_info')}</p>
|
||||
<form onSubmit={handleSubmit(onBuyPack)}>
|
||||
<FormSelect options={buildMachinesOptions(machines)} control={control} id="machine_id" rules={{ required: true }} formState={formState} label={t('app.logged.dashboard.reservations_dashboard.prepaid_packs_panel.select_machine')} />
|
||||
@ -163,7 +178,7 @@ const PrepaidPacksPanel: React.FC<PrepaidPacksPanelProps> = ({ user, onError })
|
||||
onSuccess={onPackBoughtSuccess} />}
|
||||
</div>}
|
||||
{packs.length === 0 && <p>{t('app.logged.dashboard.reservations_dashboard.prepaid_packs_panel.no_packs')}</p>}
|
||||
{(packsForSubscribers && user.subscribed_plan == null && packs.length > 0) &&
|
||||
{(packsForSubscribers && user.subscribed_plan == null && packs.length > 0 && !currentUserIsAdminOrManager(currentUser)) &&
|
||||
<HtmlTranslate trKey={'app.logged.dashboard.reservations_dashboard.prepaid_packs_panel.reserved_for_subscribers_html'} options={{ LINK: '#!/plans' }} />
|
||||
}
|
||||
</FabPanel>
|
||||
|
@ -14,13 +14,14 @@ declare const Application: IApplication;
|
||||
|
||||
interface ReservationsDashboardProps {
|
||||
onError: (message: string) => void,
|
||||
user: User
|
||||
user: User,
|
||||
currentUser?: User
|
||||
}
|
||||
|
||||
/**
|
||||
* User dashboard showing everything about his spaces/machine reservations and also remaining credits
|
||||
*/
|
||||
const ReservationsDashboard: React.FC<ReservationsDashboardProps> = ({ onError, user }) => {
|
||||
const ReservationsDashboard: React.FC<ReservationsDashboardProps> = ({ onError, user, currentUser = null }) => {
|
||||
const { t } = useTranslation('logged');
|
||||
const [modules, setModules] = useState<Map<SettingName, string>>();
|
||||
|
||||
@ -34,17 +35,17 @@ const ReservationsDashboard: React.FC<ReservationsDashboardProps> = ({ onError,
|
||||
<div className="reservations-dashboard">
|
||||
{modules?.get('machines_module') !== 'false' && <div className="section">
|
||||
<p className="section-title">{t('app.logged.dashboard.reservations_dashboard.machine_section_title')}</p>
|
||||
<CreditsPanel userId={user.id} onError={onError} reservableType="Machine" />
|
||||
<PrepaidPacksPanel user={user} onError={onError} />
|
||||
<ReservationsPanel userId={user.id} onError={onError} reservableType="Machine" />
|
||||
<CreditsPanel userId={user.id} currentUser={currentUser} onError={onError} reservableType="Machine" />
|
||||
<PrepaidPacksPanel user={user} currentUser={currentUser} onError={onError} />
|
||||
<ReservationsPanel userId={user.id} currentUser={currentUser} onError={onError} reservableType="Machine" />
|
||||
</div>}
|
||||
{modules?.get('spaces_module') !== 'false' && <div className="section">
|
||||
<p className="section-title">{t('app.logged.dashboard.reservations_dashboard.space_section_title')}</p>
|
||||
<CreditsPanel userId={user.id} onError={onError} reservableType="Space" />
|
||||
<ReservationsPanel userId={user.id} onError={onError} reservableType="Space" />
|
||||
<CreditsPanel userId={user.id} currentUser={currentUser} onError={onError} reservableType="Space" />
|
||||
<ReservationsPanel userId={user.id} currentUser={currentUser} onError={onError} reservableType="Space" />
|
||||
</div>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Application.Components.component('reservationsDashboard', react2angular(ReservationsDashboard, ['onError', 'user']));
|
||||
Application.Components.component('reservationsDashboard', react2angular(ReservationsDashboard, ['onError', 'user', 'currentUser']));
|
||||
|
@ -9,9 +9,11 @@ import { Loader } from '../../base/loader';
|
||||
import FormatLib from '../../../lib/format';
|
||||
import _ from 'lodash';
|
||||
import { FabButton } from '../../base/fab-button';
|
||||
import { User } from '../../../models/user';
|
||||
|
||||
interface SpaceReservationsProps {
|
||||
userId: number,
|
||||
currentUser?: User,
|
||||
onError: (message: string) => void,
|
||||
reservableType: 'Machine' | 'Space'
|
||||
}
|
||||
@ -19,7 +21,7 @@ interface SpaceReservationsProps {
|
||||
/**
|
||||
* List all reservations for the given user and the given type
|
||||
*/
|
||||
const ReservationsPanel: React.FC<SpaceReservationsProps> = ({ userId, onError, reservableType }) => {
|
||||
const ReservationsPanel: React.FC<SpaceReservationsProps> = ({ userId, currentUser = null, onError, reservableType }) => {
|
||||
const { t } = useTranslation('logged');
|
||||
|
||||
const [reservations, setReservations] = useState<Array<Reservation>>([]);
|
||||
@ -71,6 +73,20 @@ const ReservationsPanel: React.FC<SpaceReservationsProps> = ({ userId, onError,
|
||||
return reservation.slots_reservations_attributes.map(sr => sr.canceled_at).every(ca => ca != null);
|
||||
};
|
||||
|
||||
/**
|
||||
* returns true if there is a currentUser and current user is manager or admin
|
||||
*/
|
||||
const currentUserIsAdminOrManager = (currentUser: User): boolean => {
|
||||
return currentUser && (currentUser.role === 'admin' || currentUser.role === 'manager');
|
||||
};
|
||||
|
||||
/**
|
||||
* returns translation key prefix
|
||||
*/
|
||||
const translationKeyPrefix = (currentUser: User): string => {
|
||||
return currentUserIsAdminOrManager(currentUser) ? 'reservations_panel_as_admin' : 'reservations_panel';
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the reservation in a user-friendly way
|
||||
*/
|
||||
@ -95,7 +111,7 @@ const ReservationsPanel: React.FC<SpaceReservationsProps> = ({ userId, onError,
|
||||
|
||||
return (
|
||||
<FabPanel className="reservations-panel">
|
||||
<p className="title">{t('app.logged.dashboard.reservations_dashboard.reservations_panel.title')}</p>
|
||||
<p className="title">{t(`app.logged.dashboard.reservations_dashboard.${translationKeyPrefix(currentUser)}.title`) /* eslint-disable-line fabmanager/scoped-translation */}</p>
|
||||
<div className="reservations">
|
||||
{futur.length === 0
|
||||
? noReservations()
|
||||
|
@ -66,6 +66,10 @@
|
||||
<children-dashboard user="user" operator="currentUser" admin-panel="true" on-success="onSuccess" on-error="onError" />
|
||||
</uib-tab>
|
||||
|
||||
<uib-tab heading="{{ 'app.admin.members_edit.reservations' | translate }}">
|
||||
<reservations-dashboard user="user" current-user="currentUser" on-error="onError" />
|
||||
</uib-tab>
|
||||
|
||||
<uib-tab heading="{{ 'app.admin.members_edit.supporting_documents' | translate }}" ng-show="hasProofOfIdentityTypes">
|
||||
<supporting-documents-validation
|
||||
operator="currentUser"
|
||||
|
@ -19,6 +19,6 @@ class CreditPolicy < ApplicationPolicy
|
||||
end
|
||||
|
||||
def user_resource?
|
||||
record.id == user.id
|
||||
record.id == user.id || user.admin?
|
||||
end
|
||||
end
|
||||
|
@ -80,6 +80,7 @@ Rails.application.configure do
|
||||
config.file_watcher = ActiveSupport::EventedFileUpdateChecker
|
||||
|
||||
config.log_level = Rails.application.secrets.log_level || :debug
|
||||
config.log_tags = [:request_id]
|
||||
|
||||
config.action_controller.default_url_options = {
|
||||
host: Rails.application.secrets.default_host,
|
||||
|
@ -1273,6 +1273,7 @@ de:
|
||||
#edit a member
|
||||
members_edit:
|
||||
subscription: "Abonnement"
|
||||
reservations: "Reservations"
|
||||
duration: "Dauer:"
|
||||
expires_at: "Läuft ab am:"
|
||||
price_: "Preis:"
|
||||
|
@ -1336,6 +1336,7 @@ en:
|
||||
#edit a member
|
||||
members_edit:
|
||||
subscription: "Subscription"
|
||||
reservations: "Reservations"
|
||||
duration: "Duration:"
|
||||
expires_at: "Expires at:"
|
||||
price_: "Price:"
|
||||
|
@ -1273,6 +1273,7 @@ es:
|
||||
#edit a member
|
||||
members_edit:
|
||||
subscription: "Suscripción"
|
||||
reservations: "Reservations"
|
||||
duration: "Duración:"
|
||||
expires_at: "Caduca en:"
|
||||
price_: "Precio:"
|
||||
|
@ -1328,6 +1328,7 @@ fr:
|
||||
#edit a member
|
||||
members_edit:
|
||||
subscription: "Abonnement"
|
||||
reservations: "Réservations"
|
||||
duration: "Durée :"
|
||||
expires_at: "Expire le :"
|
||||
price_: "Prix :"
|
||||
|
@ -1273,6 +1273,7 @@ it:
|
||||
#edit a member
|
||||
members_edit:
|
||||
subscription: "Abbonamento"
|
||||
reservations: "Reservations"
|
||||
duration: "Durata:"
|
||||
expires_at: "Scadenza:"
|
||||
price_: "Prezzo:"
|
||||
|
@ -1273,6 +1273,7 @@
|
||||
#edit a member
|
||||
members_edit:
|
||||
subscription: "Medlemskap"
|
||||
reservations: "Reservations"
|
||||
duration: "Varighet:"
|
||||
expires_at: "Utløper:"
|
||||
price_: "Pris:"
|
||||
|
@ -1273,6 +1273,7 @@ pt:
|
||||
#edit a member
|
||||
members_edit:
|
||||
subscription: "Assinatura"
|
||||
reservations: "Reservations"
|
||||
duration: "Duração:"
|
||||
expires_at: "Experia em:"
|
||||
price_: "Preço:"
|
||||
|
@ -1273,6 +1273,7 @@ zu:
|
||||
#edit a member
|
||||
members_edit:
|
||||
subscription: "crwdns25848:0crwdne25848:0"
|
||||
reservations: "crwdns37747:0crwdne37747:0"
|
||||
duration: "crwdns25850:0crwdne25850:0"
|
||||
expires_at: "crwdns25852:0crwdne25852:0"
|
||||
price_: "crwdns25854:0crwdne25854:0"
|
||||
|
@ -154,12 +154,19 @@ de:
|
||||
no_reservation: "No reservation"
|
||||
show_more: "Show more"
|
||||
cancelled_slot: "Cancelled"
|
||||
reservations_panel_as_admin:
|
||||
title: "Reservations"
|
||||
credits_panel:
|
||||
title: "My credits"
|
||||
info: "Your subscription comes with free credits you can use when reserving"
|
||||
remaining_credits_html: "You can book {REMAINING} {REMAINING, plural, one{slot} other{slots}} for free."
|
||||
used_credits_html: "You have already used <strong> {USED} {USED, plural, =0{credit} one{credit} other{credits}}</strong>."
|
||||
no_credits: "You don't have any credits yet. Some subscriptions may allow you to book some slots for free."
|
||||
credits_panel_as_admin:
|
||||
title: "Credits"
|
||||
remaining_credits_html: "{REMAINING} {REMAINING, plural, one{slot} other{slots}} can be booked for free."
|
||||
used_credits_html: "<strong> {USED} {USED, plural, =0{credit} one{credit} other{credits}}</strong> already used."
|
||||
no_credits: "No credits yet."
|
||||
prepaid_packs_panel:
|
||||
title: "My prepaid packs"
|
||||
name: "Prepaid pack name"
|
||||
@ -172,6 +179,8 @@ de:
|
||||
cta_button: "Buy a pack"
|
||||
no_packs: "No prepaid packs available for sale"
|
||||
reserved_for_subscribers_html: 'The purchase of prepaid packs is reserved for subscribers. <a href="{LINK}">Subscribe now</a> to benefit.'
|
||||
prepaid_packs_panel_as_admin:
|
||||
title: "Prepaid packs"
|
||||
#public profil of a member
|
||||
members_show:
|
||||
members_list: "Mitgliederliste"
|
||||
|
@ -169,12 +169,19 @@ en:
|
||||
no_reservation: "No reservation"
|
||||
show_more: "Show more"
|
||||
cancelled_slot: "Cancelled"
|
||||
reservations_panel_as_admin:
|
||||
title: "Reservations"
|
||||
credits_panel:
|
||||
title: "My credits"
|
||||
info: "Your subscription comes with free credits you can use when reserving"
|
||||
remaining_credits_html: "You can book {REMAINING} {REMAINING, plural, one{slot} other{slots}} for free."
|
||||
used_credits_html: "You have already used <strong> {USED} {USED, plural, =0{credit} one{credit} other{credits}}</strong>."
|
||||
no_credits: "You don't have any credits yet. Some subscriptions may allow you to book some slots for free."
|
||||
credits_panel_as_admin:
|
||||
title: "Credits"
|
||||
remaining_credits_html: "{REMAINING} {REMAINING, plural, one{slot} other{slots}} can be booked for free."
|
||||
used_credits_html: "<strong> {USED} {USED, plural, =0{credit} one{credit} other{credits}}</strong> already used."
|
||||
no_credits: "No credits yet."
|
||||
prepaid_packs_panel:
|
||||
title: "My prepaid packs"
|
||||
name: "Prepaid pack name"
|
||||
@ -187,6 +194,8 @@ en:
|
||||
cta_button: "Buy a pack"
|
||||
no_packs: "No prepaid packs available for sale"
|
||||
reserved_for_subscribers_html: 'The purchase of prepaid packs is reserved for subscribers. <a href="{LINK}">Subscribe now</a> to benefit.'
|
||||
prepaid_packs_panel_as_admin:
|
||||
title: "Prepaid packs"
|
||||
#public profil of a member
|
||||
members_show:
|
||||
members_list: "Members list"
|
||||
|
@ -154,12 +154,19 @@ es:
|
||||
no_reservation: "Sin reserva"
|
||||
show_more: "Mostrar más"
|
||||
cancelled_slot: "Cancelado"
|
||||
reservations_panel_as_admin:
|
||||
title: "Reservations"
|
||||
credits_panel:
|
||||
title: "Mis créditos"
|
||||
info: "Su suscripción incluye créditos gratuitos que puede utilizar al reservar"
|
||||
remaining_credits_html: "Puede reservar {REMAINING} {REMAINING, plural, one{franja horaria} other{franjas horarias}} gratis."
|
||||
used_credits_html: "Ya has utilizado <strong> {USED} {USED, plural, =0{crédito} one{crédito} other{créditos}}</strong>."
|
||||
no_credits: "Aún no tienes créditos. Algunos abonos te permiten reservar franjas horarias gratuitamente."
|
||||
credits_panel_as_admin:
|
||||
title: "Credits"
|
||||
remaining_credits_html: "{REMAINING} {REMAINING, plural, one{slot} other{slots}} can be booked for free."
|
||||
used_credits_html: "<strong> {USED} {USED, plural, =0{credit} one{credit} other{credits}}</strong> already used."
|
||||
no_credits: "No credits yet."
|
||||
prepaid_packs_panel:
|
||||
title: "Mis paquetes de prepago"
|
||||
name: "Nombre del paquete prepago"
|
||||
@ -172,6 +179,8 @@ es:
|
||||
cta_button: "Comprar un paquete"
|
||||
no_packs: "No hay paquetes de prepago disponibles para la venta"
|
||||
reserved_for_subscribers_html: 'La compra de paquetes de prepago está reservada a los abonados. <a href="{LINK}">Suscríbete ahora</a> para beneficiarte.'
|
||||
prepaid_packs_panel_as_admin:
|
||||
title: "Prepaid packs"
|
||||
#public profil of a member
|
||||
members_show:
|
||||
members_list: "Lista de miembros"
|
||||
|
@ -169,12 +169,19 @@ fr:
|
||||
no_reservation: "Aucune réservation"
|
||||
show_more: "Afficher plus"
|
||||
cancelled_slot: "Annulé"
|
||||
reservations_panel_as_admin:
|
||||
title: "Réservations"
|
||||
credits_panel:
|
||||
title: "Mes crédits"
|
||||
info: "Avec votre abonnement, vous bénéficiez de crédits gratuits que vous pouvez utiliser lors de vos réservations"
|
||||
remaining_credits_html: "Vous pouvez réserver {REMAINING} {REMAINING, plural, one{créneau} other{créneaux}} gratuitement."
|
||||
used_credits_html: "Vous avez déjà utilisé <strong> {USED} {USED, plural, =0{crédit} one{crédit} other{crédits}}</strong>."
|
||||
no_credits: "Vous n'avez pas encore de crédits. Certains abonnements peuvent vous permettre de réserver des créneaux gratuitement."
|
||||
credits_panel_as_admin:
|
||||
title: "Crédits"
|
||||
remaining_credits_html: "{REMAINING} {REMAINING, plural, one{slot} other{slots}} peut être réservé gratuitement."
|
||||
used_credits_html: "<strong> {USED} {USED, plural, =0{crédit} one{crédit} other{crédits}}</strong> déjà utilisé."
|
||||
no_credits: "Pas encore de crédits."
|
||||
prepaid_packs_panel:
|
||||
title: "Mes packs d'heures prépayées"
|
||||
name: "Nom du pack d'heures prépayées"
|
||||
@ -187,6 +194,8 @@ fr:
|
||||
cta_button: "Acheter un pack"
|
||||
no_packs: "Aucun pack prépayé disponible à la vente"
|
||||
reserved_for_subscribers_html: 'L''achat de packs prépayés est réservé aux abonnés. <a href="{LINK}">Abonnez-vous maintenant</a> pour en bénéficier.'
|
||||
prepaid_packs_panel_as_admin:
|
||||
title: "Packs d'heures prépayées"
|
||||
#public profil of a member
|
||||
members_show:
|
||||
members_list: "Liste des membres"
|
||||
|
@ -154,12 +154,19 @@ it:
|
||||
no_reservation: "Nessuna prenotazione"
|
||||
show_more: "Mostra altro"
|
||||
cancelled_slot: "Annullato"
|
||||
reservations_panel_as_admin:
|
||||
title: "Reservations"
|
||||
credits_panel:
|
||||
title: "I miei crediti"
|
||||
info: "Il tuo abbonamento viene fornito con crediti gratuiti che puoi utilizzare durante le prenotazioni"
|
||||
remaining_credits_html: "Puoi prenotare {REMAINING} {REMAINING, plural, one{slot} other{slot}} gratis."
|
||||
used_credits_html: "Hai già usato <strong> {USED} {USED, plural, =0{credito} one{credito} other{crediti}}</strong>."
|
||||
no_credits: "Non hai ancora alcun credito. Alcuni abbonamenti potrebbero permetterti di prenotare alcuni slot gratis."
|
||||
credits_panel_as_admin:
|
||||
title: "Credits"
|
||||
remaining_credits_html: "{REMAINING} {REMAINING, plural, one{slot} other{slots}} can be booked for free."
|
||||
used_credits_html: "<strong> {USED} {USED, plural, =0{credit} one{credit} other{credits}}</strong> already used."
|
||||
no_credits: "No credits yet."
|
||||
prepaid_packs_panel:
|
||||
title: "I miei pacchetti prepagati"
|
||||
name: "Nome pacchetto prepagato"
|
||||
@ -172,6 +179,8 @@ it:
|
||||
cta_button: "Acquista un pacchetto"
|
||||
no_packs: "Nessun pacchetto prepagato disponibile per la vendita"
|
||||
reserved_for_subscribers_html: 'L''acquisto di pacchetti prepagati è riservato agli abbonati. <a href="{LINK}">Iscriviti ora</a> per ottenerne.'
|
||||
prepaid_packs_panel_as_admin:
|
||||
title: "Prepaid packs"
|
||||
#public profil of a member
|
||||
members_show:
|
||||
members_list: "Lista dei membri"
|
||||
|
@ -154,12 +154,19 @@
|
||||
no_reservation: "No reservation"
|
||||
show_more: "Show more"
|
||||
cancelled_slot: "Cancelled"
|
||||
reservations_panel_as_admin:
|
||||
title: "Reservations"
|
||||
credits_panel:
|
||||
title: "My credits"
|
||||
info: "Your subscription comes with free credits you can use when reserving"
|
||||
remaining_credits_html: "You can book {REMAINING} {REMAINING, plural, one{slot} other{slots}} for free."
|
||||
used_credits_html: "You have already used <strong> {USED} {USED, plural, =0{credit} one{credit} other{credits}}</strong>."
|
||||
no_credits: "You don't have any credits yet. Some subscriptions may allow you to book some slots for free."
|
||||
credits_panel_as_admin:
|
||||
title: "Credits"
|
||||
remaining_credits_html: "{REMAINING} {REMAINING, plural, one{slot} other{slots}} can be booked for free."
|
||||
used_credits_html: "<strong> {USED} {USED, plural, =0{credit} one{credit} other{credits}}</strong> already used."
|
||||
no_credits: "No credits yet."
|
||||
prepaid_packs_panel:
|
||||
title: "My prepaid packs"
|
||||
name: "Prepaid pack name"
|
||||
@ -172,6 +179,8 @@
|
||||
cta_button: "Buy a pack"
|
||||
no_packs: "No prepaid packs available for sale"
|
||||
reserved_for_subscribers_html: 'The purchase of prepaid packs is reserved for subscribers. <a href="{LINK}">Subscribe now</a> to benefit.'
|
||||
prepaid_packs_panel_as_admin:
|
||||
title: "Prepaid packs"
|
||||
#public profil of a member
|
||||
members_show:
|
||||
members_list: "Medlemsliste"
|
||||
|
@ -154,12 +154,19 @@ pt:
|
||||
no_reservation: "Nenhuma reserva"
|
||||
show_more: "Exibir mais"
|
||||
cancelled_slot: "Cancelado"
|
||||
reservations_panel_as_admin:
|
||||
title: "Reservations"
|
||||
credits_panel:
|
||||
title: "Meus créditos"
|
||||
info: "Sua assinatura vem com créditos gratuitos que você pode usar na reserva"
|
||||
remaining_credits_html: "Você pode reservar {REMAINING} {REMAINING, plural, one{slot} other{slots}} de graça."
|
||||
used_credits_html: "Você já usou <strong>{USED} {USED, plural, =0{crédito} one{crédito} other{créditos}}</strong>."
|
||||
no_credits: "Você não tem nenhum crédito ainda. Algumas assinaturas podem permitir que você reserve alguns slots gratuitamente."
|
||||
credits_panel_as_admin:
|
||||
title: "Credits"
|
||||
remaining_credits_html: "{REMAINING} {REMAINING, plural, one{slot} other{slots}} can be booked for free."
|
||||
used_credits_html: "<strong> {USED} {USED, plural, =0{credit} one{credit} other{credits}}</strong> already used."
|
||||
no_credits: "No credits yet."
|
||||
prepaid_packs_panel:
|
||||
title: "Meus pacotes pré-pagos"
|
||||
name: "Nome do pacote pré-pago"
|
||||
@ -172,6 +179,8 @@ pt:
|
||||
cta_button: "Comprar um pacote"
|
||||
no_packs: "Não há pacotes pré-pagos disponíveis para venda"
|
||||
reserved_for_subscribers_html: 'A compra de pacotes pré-pagos é reservada para os inscritos. <a href="{LINK}">Inscreva-se agora</a> para beneficiar.'
|
||||
prepaid_packs_panel_as_admin:
|
||||
title: "Prepaid packs"
|
||||
#public profil of a member
|
||||
members_show:
|
||||
members_list: "Lista de membros"
|
||||
|
@ -154,12 +154,19 @@ zu:
|
||||
no_reservation: "crwdns37037:0crwdne37037:0"
|
||||
show_more: "crwdns37039:0crwdne37039:0"
|
||||
cancelled_slot: "crwdns37041:0crwdne37041:0"
|
||||
reservations_panel_as_admin:
|
||||
title: "crwdns37749:0crwdne37749:0"
|
||||
credits_panel:
|
||||
title: "crwdns37043:0crwdne37043:0"
|
||||
info: "crwdns37045:0crwdne37045:0"
|
||||
remaining_credits_html: "crwdns37047:0REMAINING={REMAINING}crwdnd37047:0REMAINING={REMAINING}crwdne37047:0"
|
||||
used_credits_html: "crwdns37049:0USED={USED}crwdnd37049:0USED={USED}crwdne37049:0"
|
||||
no_credits: "crwdns37051:0crwdne37051:0"
|
||||
credits_panel_as_admin:
|
||||
title: "crwdns37751:0crwdne37751:0"
|
||||
remaining_credits_html: "crwdns37753:0REMAINING={REMAINING}crwdnd37753:0REMAINING={REMAINING}crwdne37753:0"
|
||||
used_credits_html: "crwdns37755:0USED={USED}crwdnd37755:0USED={USED}crwdne37755:0"
|
||||
no_credits: "crwdns37757:0crwdne37757:0"
|
||||
prepaid_packs_panel:
|
||||
title: "crwdns37053:0crwdne37053:0"
|
||||
name: "crwdns37055:0crwdne37055:0"
|
||||
@ -172,6 +179,8 @@ zu:
|
||||
cta_button: "crwdns37069:0crwdne37069:0"
|
||||
no_packs: "crwdns37389:0crwdne37389:0"
|
||||
reserved_for_subscribers_html: 'crwdns37391:0{LINK}crwdne37391:0'
|
||||
prepaid_packs_panel_as_admin:
|
||||
title: "crwdns37759:0crwdne37759:0"
|
||||
#public profil of a member
|
||||
members_show:
|
||||
members_list: "crwdns27656:0crwdne27656:0"
|
||||
|
@ -3390,9 +3390,7 @@ CREATE TABLE public.spaces (
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
characteristics text,
|
||||
disabled boolean,
|
||||
deleted_at timestamp without time zone,
|
||||
ancestry character varying NOT NULL COLLATE pg_catalog."C",
|
||||
ancestry_depth integer DEFAULT 0
|
||||
deleted_at timestamp without time zone
|
||||
);
|
||||
|
||||
|
||||
@ -7470,13 +7468,6 @@ CREATE INDEX index_spaces_availabilities_on_availability_id ON public.spaces_ava
|
||||
CREATE INDEX index_spaces_availabilities_on_space_id ON public.spaces_availabilities USING btree (space_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_spaces_on_ancestry; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_spaces_on_ancestry ON public.spaces USING btree (ancestry);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_spaces_on_deleted_at; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
@ -9266,5 +9257,3 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||
('20230831103208'),
|
||||
('20230901090637'),
|
||||
('20230907124230');
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user