--- /dev/null
+import axios from 'axios';
+import PropTypes from 'prop-types';
+import React from 'react';
+import { Button } from 'react-bootstrap';
+import { withTranslation } from 'react-i18next';
+import toastr from 'toastr';
+
+import Icon from '../common/Icon';
+import { isApplicant, isDeniedApplicant, mayApply } from '../../helpers/permissions';
+import { withUser } from '../../helpers/UserContext';
+import i18n from '../../i18n';
+
+const apply = async tournament => {
+ try {
+ await axios.post(`/api/tournaments/${tournament.id}/apply`);
+ toastr.success(i18n.t('tournaments.applySuccess'));
+ } catch (e) {
+ toastr.error(i18n.t('tournaments.applyError'));
+ }
+};
+
+const getTitle = (user, tournament) => {
+ if (isDeniedApplicant(user, tournament)) {
+ return i18n.t('tournaments.applicationDenied');
+ }
+ if (isApplicant(user, tournament)) {
+ return i18n.t('tournaments.applicationPending');
+ }
+ return i18n.t('tournaments.apply');
+};
+
+const ApplyButton = ({ tournament, user }) => {
+ if (!tournament.accept_applications) return null;
+
+ return <span className="d-inline-block" title={getTitle(user, tournament)}>
+ <Button
+ disabled={!mayApply(user, tournament)}
+ onClick={() => apply(tournament)}
+ variant="primary"
+ >
+ <Icon.APPLY title="" />
+ </Button>
+ </span>;
+};
+
+ApplyButton.propTypes = {
+ tournament: PropTypes.shape({
+ accept_applications: PropTypes.bool,
+ id: PropTypes.number,
+ }),
+ user: PropTypes.shape({
+ }),
+};
+
+export default withTranslation()(withUser(ApplyButton));