1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-02-20 14:54:15 +01:00

(ui) Dashboard inte

This commit is contained in:
vincent 2023-01-04 18:00:56 +01:00 committed by Sylvain
parent 5aab27e6e7
commit eb7c4de0ce
22 changed files with 422 additions and 225 deletions

View File

@ -12,18 +12,16 @@ interface FabPanelProps {
*/
export const FabPanel: React.FC<FabPanelProps> = ({ className, header, size, children }) => {
return (
<div className={`fab-panel ${className || ''}`}>
{header && <div>
<div className={`fab-panel ${className || ''} ${!header ? 'no-header' : ''}`}>
{header && <>
<div className={`panel-header ${size}`}>
{header}
</div>
<div className="panel-content">
{children}
</div>
</div>}
{!header && <div className="no-header">
{children}
</div>}
</>}
{!header && <>{ children }</>}
</div>
);
};

View File

@ -28,7 +28,7 @@ const CreditsPanel: React.FC<CreditsPanelProps> = ({ userId, onError, reservable
}, []);
/**
* Compute the remainings hours for the given credit
* Compute the remaining hours for the given credit
*/
const remainingHours = (credit: Credit): number => {
return credit.hours - credit.hours_used;
@ -39,29 +39,31 @@ const CreditsPanel: React.FC<CreditsPanelProps> = ({ userId, onError, reservable
*/
const noCredits = (): ReactNode => {
return (
<li className="no-credits">{t('app.logged.dashboard.reservations.credits_panel.no_credits')}</li>
);
};
/**
* Panel title
*/
const header = (): ReactNode => {
return (
<div>
{t(`app.logged.dashboard.reservations.credits_panel.title_${reservableType}`)}
</div>
<div className="fab-alert fab-alert--warning">{t('app.logged.dashboard.reservations_dashboard.credits_panel.no_credits')}</div>
);
};
return (
<FabPanel className="credits-panel" header={header()}>
<ul>
{credits.map(c => <li key={c.id}>
<HtmlTranslate trKey="app.logged.dashboard.reservations.credits_panel.reamaining_credits_html" options={{ NAME: c.creditable.name, REMAINING: remainingHours(c), USED: c.hours_used }} />
</li>)}
<FabPanel className="credits-panel">
<p className="title">{t('app.logged.dashboard.reservations_dashboard.credits_panel.title')}</p>
{credits.length !== 0 &&
<div className="fab-alert fab-alert--warning">
{t('app.logged.dashboard.reservations_dashboard.credits_panel.info')}
</div>
}
<div className="credits-list">
{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 />
{(c.hours_used && c.hours_used > 0) &&
<HtmlTranslate trKey="app.logged.dashboard.reservations_dashboard.credits_panel.used_credits_html" options={{ USED: c.hours_used }} />
}
</p>
</div>)}
</div>
{credits.length === 0 && noCredits()}
</ul>
</FabPanel>
);
};

View File

@ -0,0 +1,56 @@
import { FabPanel } from '../../base/fab-panel';
import { Loader } from '../../base/loader';
import { useTranslation } from 'react-i18next';
interface PrepaidPacksPanelProps {
userId: number,
onError: (message: string) => void
}
/**
* List all available prepaid packs for the given user
*/
const PrepaidPacksPanel: React.FC<PrepaidPacksPanelProps> = () => {
const { t } = useTranslation('logged');
return (
<FabPanel className='prepaid-packs-panel'>
<p className="title">{t('app.logged.dashboard.reservations_dashboard.prepaid_packs_panel.title')}</p>
{/* map */}
<div className='prepaid-packs is-low'>
<div className='prepaid-packs-list'>
<span className="prepaid-packs-list-label name">{t('app.logged.dashboard.reservations_dashboard.prepaid_packs_panel.name')}</span>
<span className="prepaid-packs-list-label end">{t('app.logged.dashboard.reservations_dashboard.prepaid_packs_panel.end')}</span>
<span className="prepaid-packs-list-label countdown">{t('app.logged.dashboard.reservations_dashboard.prepaid_packs_panel.countdown')}</span>
<div className='prepaid-packs-list-item'>
<p className='name'>Pack name</p>
<p className='end'>00/00/0000</p>
<p className="countdown"><span>00H</span> / 00H</p>
</div>
</div>
<div className="prepaid-packs-list is-history">
<span className='prepaid-packs-list-label'>{t('app.logged.dashboard.reservations_dashboard.prepaid_packs_panel.history')}</span>
<div className='prepaid-packs-list-item'>
<p className='name'>00{t('app.logged.dashboard.reservations_dashboard.prepaid_packs_panel.consumed_hours')}</p>
<p className="date">00/00/00</p>
</div>
</div>
</div>
</FabPanel>
);
};
const PrepaidPacksPanelWrapper: React.FC<PrepaidPacksPanelProps> = (props) => {
return (
<Loader>
<PrepaidPacksPanel {...props} />
</Loader>
);
};
export { PrepaidPacksPanelWrapper as PrepaidPacksPanel };

View File

@ -6,6 +6,8 @@ import { ReservationsPanel } from './reservations-panel';
import SettingAPI from '../../../api/setting';
import { SettingName } from '../../../models/setting';
import { CreditsPanel } from './credits-panel';
import { useTranslation } from 'react-i18next';
import { PrepaidPacksPanel } from './prepaid-packs-panel';
declare const Application: IApplication;
@ -18,6 +20,7 @@ interface ReservationsDashboardProps {
* User dashboard showing everything about his spaces/machine reservations and also remaining credits
*/
const ReservationsDashboard: React.FC<ReservationsDashboardProps> = ({ onError, userId }) => {
const { t } = useTranslation('logged');
const [modules, setModules] = useState<Map<SettingName, string>>();
useEffect(() => {
@ -28,10 +31,17 @@ const ReservationsDashboard: React.FC<ReservationsDashboardProps> = ({ onError,
return (
<div className="reservations-dashboard">
{modules?.get('machines_module') !== 'false' && <CreditsPanel userId={userId} onError={onError} reservableType="Machine" />}
{modules?.get('spaces_module') !== 'false' && <CreditsPanel userId={userId} onError={onError} reservableType="Space" />}
{modules?.get('machines_module') !== 'false' && <ReservationsPanel userId={userId} onError={onError} reservableType="Machine" />}
{modules?.get('spaces_module') !== 'false' && <ReservationsPanel userId={userId} onError={onError} reservableType="Space" />}
<div className="section">
<p className="section-title">{t('app.logged.dashboard.reservations_dashboard.machine_section_title')}</p>
{modules?.get('machines_module') !== 'false' && <CreditsPanel userId={userId} onError={onError} reservableType="Machine" />}
<PrepaidPacksPanel userId={userId} onError={onError} />
{modules?.get('machines_module') !== 'false' && <ReservationsPanel userId={userId} onError={onError} reservableType="Machine" />}
</div>
<div className="section">
<p className="section-title">{t('app.logged.dashboard.reservations_dashboard.space_section_title')}</p>
{modules?.get('spaces_module') !== 'false' && <CreditsPanel userId={userId} onError={onError} reservableType="Space" />}
{modules?.get('spaces_module') !== 'false' && <ReservationsPanel userId={userId} onError={onError} reservableType="Space" />}
</div>
</div>
);
};

View File

@ -7,8 +7,6 @@ import { useTranslation } from 'react-i18next';
import moment from 'moment';
import { Loader } from '../../base/loader';
import FormatLib from '../../../lib/format';
import { FabPopover } from '../../base/fab-popover';
import { useImmer } from 'use-immer';
import _ from 'lodash';
import { FabButton } from '../../base/fab-button';
@ -25,7 +23,6 @@ const ReservationsPanel: React.FC<SpaceReservationsProps> = ({ userId, onError,
const { t } = useTranslation('logged');
const [reservations, setReservations] = useState<Array<Reservation>>([]);
const [details, updateDetails] = useImmer<Record<number, boolean>>({});
const [showMore, setShowMore] = useState<boolean>(false);
useEffect(() => {
@ -51,28 +48,6 @@ const ReservationsPanel: React.FC<SpaceReservationsProps> = ({ userId, onError,
(state === 'futur' && moment(sr.slot_attributes.start_at).isAfter());
};
/**
* Panel title
*/
const header = (): ReactNode => {
return (
<div>
{t(`app.logged.dashboard.reservations.reservations_panel.title_${reservableType}`)}
</div>
);
};
/**
* Show/hide the slots details for the given reservation
*/
const toggleDetails = (reservationId: number): () => void => {
return () => {
updateDetails(draft => {
draft[reservationId] = !draft[reservationId];
});
};
};
/**
* Shows/hide the very old reservations list
*/
@ -85,7 +60,7 @@ const ReservationsPanel: React.FC<SpaceReservationsProps> = ({ userId, onError,
*/
const noReservations = (): ReactNode => {
return (
<li className="no-reservations">{t('app.logged.dashboard.reservations.reservations_panel.no_reservations')}</li>
<span className="no-reservations">{t('app.logged.dashboard.reservations_dashboard.reservations_panel.no_reservation')}</span>
);
};
@ -101,18 +76,17 @@ const ReservationsPanel: React.FC<SpaceReservationsProps> = ({ userId, onError,
*/
const renderReservation = (reservation: Reservation, state: 'past' | 'futur'): ReactNode => {
return (
<li key={reservation.id} className="reservation">
<a className={`reservation-title ${details[reservation.id] ? 'clicked' : ''} ${isCancelled(reservation) ? 'canceled' : ''}`} onClick={toggleDetails(reservation.id)}>
{reservation.reservable.name} - {FormatLib.date(reservation.slots_reservations_attributes[0].slot_attributes.start_at)}
</a>
{details[reservation.id] && <FabPopover title={t('app.logged.dashboard.reservations.reservations_panel.slots_details')}>
<div key={reservation.id} className="reservations-list-item">
<p className='name'>{reservation.reservable.name}</p>
<div className="date">
{reservation.slots_reservations_attributes.filter(s => filterSlot(s, state)).map(
slotReservation => <span key={slotReservation.id} className={`slot-details ${slotReservation.canceled_at ? 'canceled' : ''}`}>
{FormatLib.date(slotReservation.slot_attributes.start_at)}, {FormatLib.time(slotReservation.slot_attributes.start_at)} - {FormatLib.time(slotReservation.slot_attributes.end_at)}
</span>
slotReservation => <p key={slotReservation.id}>
{FormatLib.date(slotReservation.slot_attributes.start_at)} - {FormatLib.time(slotReservation.slot_attributes.start_at)} - {FormatLib.time(slotReservation.slot_attributes.end_at)}
</p>
)}
</FabPopover>}
</li>
</div>
</div>
);
};
@ -120,21 +94,31 @@ const ReservationsPanel: React.FC<SpaceReservationsProps> = ({ userId, onError,
const past = _.orderBy(reservationsByDate('past'), r => r.slots_reservations_attributes[0].slot_attributes.start_at, 'desc');
return (
<FabPanel className="reservations-panel" header={header()}>
<h4>{t('app.logged.dashboard.reservations.reservations_panel.upcoming')}</h4>
<ul>
{futur.length === 0 && noReservations()}
{futur.map(r => renderReservation(r, 'futur'))}
</ul>
<h4>{t('app.logged.dashboard.reservations.reservations_panel.past')}</h4>
<ul>
{past.length === 0 && noReservations()}
{past.slice(0, 10).map(r => renderReservation(r, 'past'))}
{past.length > 10 && !showMore && <li className="show-more"><FabButton onClick={toggleShowMore}>
{t('app.logged.dashboard.reservations.reservations_panel.show_more')}
</FabButton></li>}
{past.length > 10 && showMore && past.slice(10).map(r => renderReservation(r, 'past'))}
</ul>
<FabPanel className="reservations-panel">
<p className="title">{t('app.logged.dashboard.reservations_dashboard.reservations_panel.title')}</p>
<div className="reservations">
{futur.length === 0
? noReservations()
: <div className="reservations-list">
<span className="reservations-list-label name">{t('app.logged.dashboard.reservations_dashboard.reservations_panel.upcoming')}</span>
<span className="reservations-list-label date">{t('app.logged.dashboard.reservations_dashboard.reservations_panel.date')}</span>
{futur.map(r => renderReservation(r, 'futur'))}
</div>
}
{past.length > 0 &&
<div className="reservations-list is-history">
<span className="reservations-list-label">{t('app.logged.dashboard.reservations_dashboard.reservations_panel.history')}</span>
{past.slice(0, 5).map(r => renderReservation(r, 'past'))}
{past.length > 5 && !showMore && <FabButton onClick={toggleShowMore} className="show-more is-black">
{t('app.logged.dashboard.reservations_dashboard.reservations_panel.show_more')}
</FabButton>}
{past.length > 5 && showMore && past.slice(5).map(r => renderReservation(r, 'past'))}
</div>
}
</div>
</FabPanel>
);
};

View File

@ -192,7 +192,7 @@ angular.module('application.router', ['ui.router'])
}
}
})
.state('app.logged.dashboard.reservations', {
.state('app.logged.dashboard.reservations_dashboard', {
url: '/reservations',
views: {
'main@': {

View File

@ -39,6 +39,7 @@
@import "modules/cart/cart-button";
@import "modules/cart/store-cart";
@import "modules/dashboard/reservations/credits-panel";
@import "modules/dashboard/reservations/prepaid-packs-panel";
@import "modules/dashboard/reservations/reservations-dashboard";
@import "modules/dashboard/reservations/reservations-panel";
@import "modules/events/event";

View File

@ -2,7 +2,7 @@
padding: 15px;
margin-bottom: 24px;
border: 1px solid transparent;
border-radius: 4px;
border-radius: var(--border-radius);
&--info {
color: #31708f;

View File

@ -8,6 +8,7 @@
position: relative;
display: block;
border-spacing: 0;
overflow: hidden;
.panel-header {
background-color: #f4f3f3;
@ -17,7 +18,7 @@
border-top-left-radius: 3px;
&.small {
padding: 15px 15px;
padding: 24px;
}
}
@ -25,7 +26,7 @@
padding: 15px;
}
.no-header {
&.no-header {
padding: 15px;
background-color: #f4f3f3;
}

View File

@ -1,26 +1,31 @@
.credits-panel {
.no-credits {
list-style: none;
text-align: center;
font-style: italic;
color: #aaa;
}
}
display: flex;
flex-direction: column;
gap: 1.6rem;
&.no-header > * { margin: 0; }
.title { @include text-base(600); }
@media (min-width: 1460px) {
.credits-panel {
width: 45%;
}
}
.credits-list {
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 0.8rem;
@media (max-width: 1459px) {
.credits-panel {
width: 95%;
}
}
&-item {
padding: 1.6rem;
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 1.6rem 2.4rem;
background-color: var(--gray-soft-lightest);
border-radius: var(--border-radius);
@media (max-width: 992px) {
.credits-panel {
width: 90%;
.title { @include text-base(600); }
p { margin: 0; }
@media (min-width: 640px) {
flex-direction: row;
}
}
}
}

View File

@ -0,0 +1,46 @@
.prepaid-packs-panel {
display: flex;
flex-direction: column;
gap: 1.6rem;
.title { @include text-base(600); }
p { margin: 0; }
.prepaid-packs {
padding: 1.6rem;
background-color: var(--gray-soft-lightest);
border-radius: var(--border-radius);
&.is-low {
border: 1px solid var(--alert);
.countdown span { color: var(--alert); }
}
}
.prepaid-packs-list {
display: grid;
grid-template-columns: 2fr 1fr max-content;
gap: 0 1.6rem;
.name { grid-column: 1 / 2; }
.end { grid-column: 2 / 3; }
.countdown, .date { grid-column: 3 / 4; }
&-label {
@include text-xs;
color: var(--gray-soft-darkest);
}
&-item {
display: contents;
@include text-base(600);
}
}
.prepaid-packs-list.is-history {
margin-top: 2.4rem;
.prepaid-packs-list-label {
margin-bottom: 0.8rem;
padding-bottom: 0.8rem;
grid-column: 1 / -1;
border-bottom: 1px solid var(--gray-soft-dark);
}
.prepaid-packs-list-item { font-weight: 400; }
}
}

View File

@ -1,5 +1,29 @@
.reservations-dashboard {
display: flex;
flex-direction: row;
flex-wrap: wrap;
max-width: 1600px;
margin: 0 auto 6rem;
padding: 3.2rem;
display: grid;
grid-template-columns: 1fr;
gap: 3.2rem;
.section {
display: flex;
flex-direction: column;
gap: 3.2rem;
&-title {
@include title-base;
margin-bottom: 0;
}
}
.fab-panel {
width: 100%;
float: none;
margin: 0;
}
@media (min-width: 1440px) {
grid-template-columns: repeat(2, 1fr);
}
}

View File

@ -1,56 +1,63 @@
.reservations-panel {
margin-bottom: 60px;
.reservation {
position: relative;
&-title {
cursor: pointer;
display: flex;
flex-direction: column;
gap: 1.6rem;
.title { @include text-base(600); }
p { margin: 0; }
&.clicked {
color: var(--secondary-dark);
}
&.canceled {
text-decoration: line-through;
}
}
.slot-details {
display: block;
&.canceled {
text-decoration: line-through;
}
}
.fab-popover {
left: 0;
}
.reservations {
padding: 1.6rem;
background-color: var(--gray-soft-lightest);
border-radius: var(--border-radius);
}
.no-reservations,
.show-more {
list-style: none;
text-align: center;
.reservations-list {
display: grid;
grid-template-columns: 1fr max-content;
gap: 0 1.6rem;
.name { grid-column: 1 / 2; }
.date { grid-column: 2 / 3; }
&-label {
@include text-xs;
color: var(--gray-soft-darkest);
}
&-item {
display: contents;
@include text-base(600);
.date{
margin-bottom: 0.4rem;
display: flex;
flex-direction: column;
align-items: flex-end;
}
&.canceled {
text-decoration: line-through;
}
}
}
.reservations-list.is-history {
margin-top: 2.4rem;
.reservations-list-label {
margin-bottom: 0.8rem;
padding-bottom: 0.8rem;
grid-column: 1 / -1;
border-bottom: 1px solid var(--gray-soft-dark);
}
.reservations-list-item { font-weight: 400; }
}
.no-reservations {
display: block;
@include text-sm;
font-style: italic;
color: #aaa;
text-align: center;
color: var(--gray-soft-darkest);
}
.show-more {
margin-top: 10px;
}
}
@media (min-width: 1460px) {
.reservations-panel {
width: 45%;
}
}
@media (max-width: 1459px) {
.reservations-panel {
width: 95%;
}
}
@media (max-width: 992px) {
.reservations-panel {
width: 90%;
width: fit-content;
margin-top: 1rem;
}
}

View File

@ -15,7 +15,7 @@
<li ng-if="!isAuthorized(['admin', 'manager']) && hasProofOfIdentityTypes" ui-sref-active="active"><a class="text-black" ui-sref="app.logged.dashboard.proof_of_identity_files" translate>{{ 'app.public.common.my_supporting_documents_files' }}</a></li>
<li ui-sref-active="active"><a class="text-black" ui-sref="app.logged.dashboard.projects" translate>{{ 'app.public.common.my_projects' }}</a></li>
<li ui-sref-active="active"><a class="text-black" ui-sref="app.logged.dashboard.trainings" translate>{{ 'app.public.common.my_trainings' }}</a></li>
<li ui-sref-active="active"><a class="text-black" ui-sref="app.logged.dashboard.reservations" translate>{{ 'app.public.common.my_reservations' }}</a></li>
<li ui-sref-active="active"><a class="text-black" ui-sref="app.logged.dashboard.reservations_dashboard" translate>{{ 'app.public.common.my_reservations' }}</a></li>
<li ui-sref-active="active"><a class="text-black" ui-sref="app.logged.dashboard.events" translate>{{ 'app.public.common.my_events' }}</a></li>
<li ui-sref-active="active" ng-show="$root.modules.invoicing"><a class="text-black" ui-sref="app.logged.dashboard.invoices" translate>{{ 'app.public.common.my_invoices' }}</a></li>
<li ui-sref-active="active" ng-show="$root.modules.invoicing"><a class="text-black" ui-sref="app.logged.dashboard.payment_schedules" translate>{{ 'app.public.common.my_payment_schedules' }}</a></li>

View File

@ -44,7 +44,7 @@
<li ng-if="!isAuthorized(['admin', 'manager']) && hasProofOfIdentityTypes"><a ui-sref="app.logged.dashboard.proof_of_identity_files" translate>{{ 'app.public.common.my_supporting_documents_files' }}</a></li>
<li><a ui-sref="app.logged.dashboard.projects" translate>{{ 'app.public.common.my_projects' }}</a></li>
<li><a ui-sref="app.logged.dashboard.trainings" translate>{{ 'app.public.common.my_trainings' }}</a></li>
<li><a ui-sref="app.logged.dashboard.reservations" translate>{{ 'app.public.common.my_reservations' }}</a></li>
<li><a ui-sref="app.logged.dashboard.reservations_dashboard" translate>{{ 'app.public.common.my_reservations' }}</a></li>
<li><a ui-sref="app.logged.dashboard.events" translate>{{ 'app.public.common.my_events' }}</a></li>
<li><a ui-sref="app.logged.dashboard.invoices" ng-show="$root.modules.invoicing" translate>{{ 'app.public.common.my_invoices' }}</a></li>
<li><a ui-sref="app.logged.dashboard.payment_schedules" ng-show="$root.modules.invoicing" translate>{{ 'app.public.common.my_payment_schedules' }}</a></li>

View File

@ -143,20 +143,29 @@ de:
save: "Speichern"
browse: "Durchsuchen"
edit: "Bearbeiten"
reservations:
reservations_dashboard:
machine_section_title: "Machines reservations"
space_section_title: "Spaces reservations"
reservations_panel:
title_Space: "My space reservations"
title_Machine: "My machines reservations"
title: "My reservations"
upcoming: "Upcoming"
past: "Past"
slots_details: "Slots details"
no_reservations: "No reservations"
date: "Date"
history: "History"
no_reservation: "No reservation"
show_more: "Show more"
credits_panel:
title_Space: "My space credits"
title_Machine: "My machines credits"
reamaining_credits_html: "<strong>{NAME}</strong>: You can book <em>{REMAINING} {REMAINING, plural, one{slot} other{slots}}</em> for free. You have already used {USED} {USED, plural, one{credit} other{credits}} from your current subscription."
title: "My credits"
info: "Your subscription comes with free credits you can use on reservations"
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."
prepaid_packs_panel:
title: "My prepaid packs"
name: "Prepaid pack name"
end: "Expiry date"
countdown: "Countdown"
history: "History"
consumed_hours: "H consumed"
#public profil of a member
members_show:
members_list: "Mitgliederliste"

View File

@ -143,20 +143,29 @@ en:
save: "Save"
browse: "Browse"
edit: "Edit"
reservations:
reservations_dashboard:
machine_section_title: "Machines reservations"
space_section_title: "Spaces reservations"
reservations_panel:
title_Space: "My space reservations"
title_Machine: "My machines reservations"
title: "My reservations"
upcoming: "Upcoming"
past: "Past"
slots_details: "Slots details"
no_reservations: "No reservations"
date: "Date"
history: "History"
no_reservation: "No reservation"
show_more: "Show more"
credits_panel:
title_Space: "My space credits"
title_Machine: "My machines credits"
reamaining_credits_html: "<strong>{NAME}</strong>: You can book <em>{REMAINING} {REMAINING, plural, one{slot} other{slots}}</em> for free. You have already used {USED} {USED, plural, one{credit} other{credits}} from your current subscription."
title: "My credits"
info: "Your subscription comes with free credits you can use on reservations"
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."
prepaid_packs_panel:
title: "My prepaid packs"
name: "Prepaid pack name"
end: "Expiry date"
countdown: "Countdown"
history: "History"
consumed_hours: "H consumed"
#public profil of a member
members_show:
members_list: "Members list"

View File

@ -143,20 +143,29 @@ es:
save: "Save"
browse: "Browse"
edit: "Edit"
reservations:
reservations_dashboard:
machine_section_title: "Machines reservations"
space_section_title: "Spaces reservations"
reservations_panel:
title_Space: "My space reservations"
title_Machine: "My machines reservations"
title: "My reservations"
upcoming: "Upcoming"
past: "Past"
slots_details: "Slots details"
no_reservations: "No reservations"
date: "Date"
history: "History"
no_reservation: "No reservation"
show_more: "Show more"
credits_panel:
title_Space: "My space credits"
title_Machine: "My machines credits"
reamaining_credits_html: "<strong>{NAME}</strong>: You can book <em>{REMAINING} {REMAINING, plural, one{slot} other{slots}}</em> for free. You have already used {USED} {USED, plural, one{credit} other{credits}} from your current subscription."
title: "My credits"
info: "Your subscription comes with free credits you can use on reservations"
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."
prepaid_packs_panel:
title: "My prepaid packs"
name: "Prepaid pack name"
end: "Expiry date"
countdown: "Countdown"
history: "History"
consumed_hours: "H consumed"
#public profil of a member
members_show:
members_list: "Lista de miembros"

View File

@ -143,20 +143,29 @@ fr:
save: "Enregistrer"
browse: "Parcourir"
edit: "Modifier"
reservations:
reservations_dashboard:
machine_section_title: "Réservations de machines"
space_section_title: "Réservations d'espaces"
reservations_panel:
title_Space: "Mes réservations d'espace"
title_Machine: "Mes réservations de machines"
title: "Mes réservations"
upcoming: "À venir"
past: "Passées"
slots_details: "Détails des créneaux"
no_reservations: "Aucune réservation"
date: "Date"
history: "Historique"
no_reservation: "Aucune réservation"
show_more: "Afficher plus"
credits_panel:
title_Space: "Mes crédits espace"
title_Machine: "Mes crédits machine"
reamaining_credits_html: "<strong>{NAME}</strong> : Vous pouvez réserver gratuitement <em>{REMAINING} {REMAINING, plural, one{créneau} other{créneaux}}</em>. Vous avez déjà utilisé {USED} {USED, plural, one{crédit} other{crédits}} de votre abonnement actuel."
title: "Mes crédits"
info: "Avec votre abonnement, vous bénéficiez de crédits gratuits que vous pouvez utiliser sur les 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."
prepaid_packs_panel:
title: "Mes packs d'heures prépayées"
name: "Nom du pack d'heures prépayées"
end: "Expire le"
countdown: "Décompte"
history: "Historique"
consumed_hours: "H consommée(s)"
#public profil of a member
members_show:
members_list: "Liste des membres"

View File

@ -143,20 +143,29 @@
save: "Lagre"
browse: "Bla igjennom"
edit: "Rediger"
reservations:
reservations_dashboard:
machine_section_title: "Machines reservations"
space_section_title: "Spaces reservations"
reservations_panel:
title_Space: "My space reservations"
title_Machine: "My machines reservations"
title: "My reservations"
upcoming: "Upcoming"
past: "Past"
slots_details: "Slots details"
no_reservations: "No reservations"
date: "Date"
history: "History"
no_reservation: "No reservation"
show_more: "Show more"
credits_panel:
title_Space: "My space credits"
title_Machine: "My machines credits"
reamaining_credits_html: "<strong>{NAME}</strong>: You can book <em>{REMAINING} {REMAINING, plural, one{slot} other{slots}}</em> for free. You have already used {USED} {USED, plural, one{credit} other{credits}} from your current subscription."
title: "My credits"
info: "Your subscription comes with free credits you can use on reservations"
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."
prepaid_packs_panel:
title: "My prepaid packs"
name: "Prepaid pack name"
end: "Expiry date"
countdown: "Countdown"
history: "History"
consumed_hours: "H consumed"
#public profil of a member
members_show:
members_list: "Medlemsliste"

View File

@ -143,20 +143,29 @@ pt:
save: "Salvar"
browse: "Navegar"
edit: "Editar"
reservations:
reservations_dashboard:
machine_section_title: "Machines reservations"
space_section_title: "Spaces reservations"
reservations_panel:
title_Space: "My space reservations"
title_Machine: "My machines reservations"
upcoming: "Upcoming"
past: "Past"
slots_details: "Slots details"
no_reservations: "No reservations"
show_more: "Show more"
title: "Minhas reservas"
upcoming: "Próximas"
date: "Date"
history: "History"
no_reservations: "Sem reservas"
show_more: "Mostrar mais"
credits_panel:
title_Space: "My space credits"
title_Machine: "My machines credits"
reamaining_credits_html: "<strong>{NAME}</strong>: You can book <em>{REMAINING} {REMAINING, plural, one{slot} other{slots}}</em> for free. You have already used {USED} {USED, plural, one{credit} other{credits}} from your current subscription."
no_credits: "You don't have any credits yet. Some subscriptions may allow you to book some slots for free."
title: "Meus créditos"
info: "Your subscription comes with free credits you can use on reservations"
reamaining_credits_html: "Você pode fazer {REMAINING} {REMAINING, plural, one{reserva} other{reservas}} gratuitamente."
used_credits_html: " Você já usou {USED} {USED, plural, one{credito} other{creditos}} da sua assinatura."
no_credits: "Você não tem nenhum crédito ainda. Algumas assinaturas podem permitir que você reserve alguns slots gratuitamente."
prepaid_packs_panel:
title: "My prepaid packs"
name: "Prepaid pack name"
end: "Expiry date"
countdown: "Countdown"
history: "History"
consumed_hours: "H consumed"
#public profil of a member
members_show:
members_list: "Lista de membros"

View File

@ -143,20 +143,29 @@ zu:
save: "crwdns27628:0crwdne27628:0"
browse: "crwdns27630:0crwdne27630:0"
edit: "crwdns27632:0crwdne27632:0"
reservations:
reservations_dashboard:
machine_section_title: "crwdns36291:0crwdne36291:0"
space_section_title: "crwdns36293:0crwdne36293:0"
reservations_panel:
title_Space: "crwdns36761:0crwdne36761:0"
title_Machine: "crwdns36763:0crwdne36763:0"
upcoming: "crwdns36765:0crwdne36765:0"
past: "crwdns36767:0crwdne36767:0"
slots_details: "crwdns36769:0crwdne36769:0"
no_reservations: "crwdns36771:0crwdne36771:0"
show_more: "crwdns36773:0crwdne36773:0"
title: "crwdns36295:0crwdne36295:0"
upcoming: "crwdns36297:0crwdne36297:0"
date: "crwdns36299:0crwdne36299:0"
history: "crwdns36301:0crwdne36301:0"
no_reservation: "crwdns36329:0crwdne36329:0"
show_more: "crwdns36305:0crwdne36305:0"
credits_panel:
title_Space: "crwdns36775:0crwdne36775:0"
title_Machine: "crwdns36777:0crwdne36777:0"
reamaining_credits_html: "crwdns36779:0NAME={NAME}crwdnd36779:0REMAINING={REMAINING}crwdnd36779:0REMAINING={REMAINING}crwdnd36779:0USED={USED}crwdnd36779:0USED={USED}crwdne36779:0"
no_credits: "crwdns36781:0crwdne36781:0"
title: "crwdns36307:0crwdne36307:0"
info: "crwdns36309:0crwdne36309:0"
remaining_credits_html: "crwdns36311:0REMAINING={REMAINING}crwdnd36311:0REMAINING={REMAINING}crwdne36311:0"
used_credits_html: "crwdns36313:0USED={USED}crwdnd36313:0USED={USED}crwdne36313:0"
no_credits: "crwdns36315:0crwdne36315:0"
prepaid_packs_panel:
title: "crwdns36317:0crwdne36317:0"
name: "crwdns36319:0crwdne36319:0"
end: "crwdns36331:0crwdne36331:0"
countdown: "crwdns36323:0crwdne36323:0"
history: "crwdns36325:0crwdne36325:0"
consumed_hours: "crwdns36327:0crwdne36327:0"
#public profil of a member
members_show:
members_list: "crwdns27656:0crwdne27656:0"