• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / mender-server / 1590815032

16 Dec 2024 01:53PM UTC coverage: 73.522% (+0.7%) from 72.839%
1590815032

Pull #253

gitlab-ci

mineralsfree
feat: updated billing section in My Organization settings

Ticket: MEN-7466
Changelog: None

Signed-off-by: Mikita Pilinka <mikita.pilinka@northern.tech>
Pull Request #253: MEN-7466-feat: updated billing section in My Organization settings

4257 of 6186 branches covered (68.82%)

Branch coverage included in aggregate %.

57 of 89 new or added lines in 11 files covered. (64.04%)

1 existing line in 1 file now uncovered.

40090 of 54132 relevant lines covered (74.06%)

22.98 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

50.94
/frontend/src/js/components/settings/PlanExpanded.tsx
1
// Copyright 2024 Northern.tech AS
2
//
3
//    Licensed under the Apache License, Version 2.0 (the "License");
4
//    you may not use this file except in compliance with the License.
5
//    You may obtain a copy of the License at
6
//
7
//        http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//    Unless required by applicable law or agreed to in writing, software
10
//    distributed under the License is distributed on an "AS IS" BASIS,
11
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//    See the License for the specific language governing permissions and
13
//    limitations under the License.
14
import { useRef, useState } from 'react';
15
import { useSelector } from 'react-redux';
16

17
import { Button, Divider, Drawer } from '@mui/material';
18
import { makeStyles } from 'tss-react/mui';
19

20
import { DrawerTitle } from '@northern.tech/common-ui/DrawerTitle';
21
import Form from '@northern.tech/common-ui/forms/form';
22
import storeActions from '@northern.tech/store/actions';
23
import { Plan } from '@northern.tech/store/constants';
24
import { BillingProfile, Card, Organization } from '@northern.tech/store/organizationSlice/types';
25
import { getCurrentUser } from '@northern.tech/store/selectors';
26
import { useAppDispatch } from '@northern.tech/store/store';
27
import { completeUpgrade, editBillingProfile } from '@northern.tech/store/thunks';
28

29
import CardSection from './CardSection';
30
import { PlanExpandedForm } from './PlanExpandedForm';
31
import OrganizationPaymentSettings from './organization/OrganizationPaymentSettings';
32

33
const { setSnackbar } = storeActions;
8✔
34

35
interface PlanExpandedPropsBase {
36
  organization: Organization;
37
  onCloseClick: () => void;
38
  isEdit: boolean;
39
}
40
interface ProfileEditProps extends PlanExpandedPropsBase {
41
  isEdit: true;
42
  previousValues: BillingProfile;
43
  card: Card;
44
}
45

46
interface PlanProps extends PlanExpandedPropsBase {
47
  isEdit: false;
48
  plan: Plan;
49
}
50

51
const useStyles = makeStyles()(() => ({
8✔
52
  submitButtonContainer: {
53
    position: 'relative',
54
    top: '172px',
55
    height: 0
56
  }
57
}));
58

59
const successMessage = (plan: string) =>
8✔
60
  `Thank you! You have successfully subscribed to the ${plan} plan.  You can view and edit your billing details on the Organization and billing page.`;
×
61

62
export const PlanExpanded = (props: ProfileEditProps | PlanProps) => {
8✔
63
  const { onCloseClick, isEdit } = props;
2✔
64
  const organization = !isEdit ? props.organization : null;
1!
65
  const [isValid, setIsValid] = useState(isEdit);
1✔
66
  const [updatingCard, setUpdatingCard] = useState(false);
1✔
67
  const selectedPlan = isEdit ? null : props.plan;
1!
68
  const dispatch = useAppDispatch();
1✔
69
  const formSubmitRef = useRef<() => void | null>(null);
1✔
70
  const { email } = useSelector(getCurrentUser);
1✔
71
  const { classes } = useStyles();
1✔
72
  const handleUpgrade = () => {
1✔
73
    if (formSubmitRef.current) {
×
74
      formSubmitRef.current();
×
75
    }
76
  };
77
  const initialValues = isEdit
1!
78
    ? { ...props.previousValues.address, name: props.previousValues.name, email: props.previousValues.email }
79
    : { email, name: organization?.name || '', line1: '', state: '', city: '', postal_code: '', country: '' };
1!
80
  const handleSubmit = async values => {
1✔
NEW
81
    const { email, name, state, city, line1, postal_code } = values;
×
NEW
82
    const code: string = values.country.code ? values.country.code : values.country;
×
83
    const billing_profile = { email, name, address: { country: code, state, city, line1, postal_code } };
×
NEW
84
    if (isEdit) {
×
NEW
85
      await dispatch(editBillingProfile({ billingProfile: billing_profile }));
×
86
    } else {
NEW
87
      await dispatch(completeUpgrade({ tenantId: (organization as Organization).id, plan: (selectedPlan as Plan).id, billing_profile }));
×
NEW
88
      dispatch(setSnackbar(successMessage((selectedPlan as Plan).name)));
×
89
    }
UNCOV
90
    onCloseClick();
×
91
  };
92

93
  return (
1✔
94
    <Drawer anchor="right" open={true} PaperProps={{ style: { minWidth: '75vw' } }}>
95
      <DrawerTitle title={<>{selectedPlan ? `Subscribe to ${selectedPlan.name}` : 'Edit billing details'}</>} onClose={onCloseClick} />
1!
96
      <Divider className="margin-bottom" />
97
      {selectedPlan && (
2✔
98
        <div>
99
          Complete checkout to subscribe to <b>{selectedPlan.name}</b> at <b>{selectedPlan.price}</b>
100
        </div>
101
      )}
102
      <Form submitRef={formSubmitRef} onSubmit={handleSubmit} defaultValues={initialValues} showButtons={false} autocomplete="off">
103
        <PlanExpandedForm setIsValid={setIsValid} />
104
        {isEdit && !updatingCard && (
1!
105
          <div className={classes.submitButtonContainer}>
106
            <Button className="margin-right-small" onClick={onCloseClick}>
107
              Cancel
108
            </Button>
109
            <Button type="submit" color="secondary" variant="contained" disabled={!isValid}>
110
              Save
111
            </Button>
112
          </div>
113
        )}
114
      </Form>
115
      {isEdit ? (
1!
116
        <>
117
          <OrganizationPaymentSettings onComplete={handleUpgrade} updatingCard={updatingCard} setUpdatingCard={setUpdatingCard} isValid={isValid} />
118
        </>
119
      ) : (
120
        isValid && (
1!
121
          <>
122
            <h4>Card Details</h4>
123
            <CardSection organization={organization as Organization} onCardConfirmed={handleUpgrade} isSignUp />
124
          </>
125
        )
126
      )}
127
    </Drawer>
128
  );
129
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc