beem-component 2.1.8 → 2.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/BmTabv2/BmTabV2..js +72 -0
- package/dist/components/DepartmentCard/DepartmentCard.js +99 -0
- package/dist/components/DepartmentCard/DepartmentCard.stories.js +53 -0
- package/dist/components/ResourceCard/ResourceCard.js +132 -0
- package/dist/components/ResourceCard/ResourceCard.stories.js +94 -0
- package/dist/components/index.js +14 -0
- package/package.json +1 -1
- package/src/App.js +66 -1
- package/src/fonts.scss +1 -4
- package/src/lib/components/BmTabv2/BmTabV2..js +122 -0
- package/src/lib/components/DepartmentCard/DepartmentCard.js +130 -0
- package/src/lib/components/DepartmentCard/DepartmentCard.stories.jsx +38 -0
- package/src/lib/components/ResourceCard/ResourceCard.js +213 -0
- package/src/lib/components/ResourceCard/ResourceCard.stories.jsx +68 -0
- package/src/lib/components/index.js +4 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.TabPanel = TabPanel;
|
|
8
|
+
exports.Tabs = Tabs;
|
|
9
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
10
|
+
var _styledComponents = _interopRequireWildcard(require("styled-components"));
|
|
11
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
12
|
+
// Utility
|
|
13
|
+
const cn = function () {
|
|
14
|
+
for (var _len = arguments.length, classes = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
15
|
+
classes[_key] = arguments[_key];
|
|
16
|
+
}
|
|
17
|
+
return classes.filter(Boolean).join(' ');
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// Styled components
|
|
21
|
+
|
|
22
|
+
const TabsContainer = _styledComponents.default.div.withConfig({
|
|
23
|
+
displayName: "BmTabV2__TabsContainer"
|
|
24
|
+
})(["display:flex;flex-direction:column;gap:0.5rem;@media (max-width:640px){gap:0.25rem;}"]);
|
|
25
|
+
const TabsList = _styledComponents.default.div.withConfig({
|
|
26
|
+
displayName: "BmTabV2__TabsList"
|
|
27
|
+
})(["display:flex;flex-wrap:nowrap;background:#f5f5f5;overflow-x:auto;padding:3px;border-radius:8px;&::-webkit-scrollbar{display:none;}"]);
|
|
28
|
+
const TabButton = _styledComponents.default.button.withConfig({
|
|
29
|
+
displayName: "BmTabV2__TabButton"
|
|
30
|
+
})(["flex:1 0 auto;display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:0.5rem 0.75rem;font-size:0.875rem;font-weight:500;white-space:nowrap;border:1px solid transparent;border-radius:8px;background:transparent;color:#333;cursor:pointer;transition:all 0.2s;", " &:focus-visible{outline:2px solid #3b82f6;outline-offset:2px;}&:disabled{pointer-events:none;opacity:0.5;}svg{flex-shrink:0;pointer-events:none;width:1rem;height:1rem;}"], _ref => {
|
|
31
|
+
let {
|
|
32
|
+
active
|
|
33
|
+
} = _ref;
|
|
34
|
+
return active && (0, _styledComponents.css)(["background:#ffffff;color:#111111;border-color:#ddd;"]);
|
|
35
|
+
});
|
|
36
|
+
const TabContent = _styledComponents.default.div.withConfig({
|
|
37
|
+
displayName: "BmTabV2__TabContent"
|
|
38
|
+
})(["flex:1;padding:0.5rem 0;"]);
|
|
39
|
+
|
|
40
|
+
// Main Tabs component
|
|
41
|
+
|
|
42
|
+
// eslint-disable-next-line func-style
|
|
43
|
+
function Tabs(_ref2) {
|
|
44
|
+
let {
|
|
45
|
+
defaultValue = 0,
|
|
46
|
+
children,
|
|
47
|
+
className
|
|
48
|
+
} = _ref2;
|
|
49
|
+
const [activeIndex, setActiveIndex] = (0, _react.useState)(defaultValue);
|
|
50
|
+
|
|
51
|
+
// Get all children that are type of TabPanel (so we can match titles & content)
|
|
52
|
+
const tabPanels = _react.default.Children.toArray(children).filter(child => child.type.displayName === 'TabPanel');
|
|
53
|
+
return /*#__PURE__*/_react.default.createElement(TabsContainer, {
|
|
54
|
+
className: cn(className)
|
|
55
|
+
}, /*#__PURE__*/_react.default.createElement(TabsList, null, tabPanels.map((panel, index) => /*#__PURE__*/_react.default.createElement(TabButton
|
|
56
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
57
|
+
, {
|
|
58
|
+
key: index,
|
|
59
|
+
active: activeIndex === index,
|
|
60
|
+
onClick: () => setActiveIndex(index)
|
|
61
|
+
}, panel.props.title))), /*#__PURE__*/_react.default.createElement(TabContent, null, tabPanels[activeIndex] && tabPanels[activeIndex].props.children));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Individual Tab panel component
|
|
65
|
+
// eslint-disable-next-line func-style
|
|
66
|
+
function TabPanel(_ref3) {
|
|
67
|
+
let {
|
|
68
|
+
children
|
|
69
|
+
} = _ref3;
|
|
70
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, children);
|
|
71
|
+
}
|
|
72
|
+
TabPanel.displayName = 'TabPanel';
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _styledComponents = _interopRequireDefault(require("styled-components"));
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
const CardWrapper = _styledComponents.default.div.withConfig({
|
|
11
|
+
displayName: "DepartmentCard__CardWrapper"
|
|
12
|
+
})(["overflow:hidden;border-radius:0.5rem;border:1px solid #e5e7eb;border-top:4px solid ", ";background-color:#ffffff;opacity:", ";transition:opacity 0.3s;"], _ref => {
|
|
13
|
+
let {
|
|
14
|
+
borderTopColor
|
|
15
|
+
} = _ref;
|
|
16
|
+
return borderTopColor || '#cccccc';
|
|
17
|
+
}, _ref2 => {
|
|
18
|
+
let {
|
|
19
|
+
isActive
|
|
20
|
+
} = _ref2;
|
|
21
|
+
return isActive ? 1 : 0.5;
|
|
22
|
+
});
|
|
23
|
+
const Header = _styledComponents.default.div.withConfig({
|
|
24
|
+
displayName: "DepartmentCard__Header"
|
|
25
|
+
})(["padding:1rem 1rem 0.5rem 1rem;"]);
|
|
26
|
+
const TitleRow = _styledComponents.default.div.withConfig({
|
|
27
|
+
displayName: "DepartmentCard__TitleRow"
|
|
28
|
+
})(["display:flex;justify-content:space-between;align-items:flex-start;"]);
|
|
29
|
+
const CardTitle = _styledComponents.default.h3.withConfig({
|
|
30
|
+
displayName: "DepartmentCard__CardTitle"
|
|
31
|
+
})(["font-size:1.125rem;margin:0;"]);
|
|
32
|
+
const CardDescription = _styledComponents.default.p.withConfig({
|
|
33
|
+
displayName: "DepartmentCard__CardDescription"
|
|
34
|
+
})(["font-size:0.875rem;color:#6b7280;margin-top:0.25rem;"]);
|
|
35
|
+
const Content = _styledComponents.default.div.withConfig({
|
|
36
|
+
displayName: "DepartmentCard__Content"
|
|
37
|
+
})(["margin-top:1rem;padding:0 1rem 0.5rem 1rem;display:flex;justify-content:space-between;align-items:center;"]);
|
|
38
|
+
const ResourceText = _styledComponents.default.span.withConfig({
|
|
39
|
+
displayName: "DepartmentCard__ResourceText"
|
|
40
|
+
})(["font-size:0.875rem;color:#6b7280;"]);
|
|
41
|
+
const StatusRow = _styledComponents.default.div.withConfig({
|
|
42
|
+
displayName: "DepartmentCard__StatusRow"
|
|
43
|
+
})(["display:flex;align-items:center;"]);
|
|
44
|
+
const StatusDot = _styledComponents.default.span.withConfig({
|
|
45
|
+
displayName: "DepartmentCard__StatusDot"
|
|
46
|
+
})(["flex-shrink:0;width:0.5rem;height:0.5rem;margin-right:0.5rem;border-radius:9999px;background-color:", ";"], _ref3 => {
|
|
47
|
+
let {
|
|
48
|
+
isActive
|
|
49
|
+
} = _ref3;
|
|
50
|
+
return isActive ? '#22c55e' : '#9ca3af';
|
|
51
|
+
});
|
|
52
|
+
const StatusText = _styledComponents.default.span.withConfig({
|
|
53
|
+
displayName: "DepartmentCard__StatusText"
|
|
54
|
+
})(["font-size:0.75rem;color:#6b7280;"]);
|
|
55
|
+
const IconButtonsContainer = _styledComponents.default.div.withConfig({
|
|
56
|
+
displayName: "DepartmentCard__IconButtonsContainer"
|
|
57
|
+
})(["display:flex;gap:0.25rem;"]);
|
|
58
|
+
const IconButton = _styledComponents.default.button.withConfig({
|
|
59
|
+
displayName: "DepartmentCard__IconButton"
|
|
60
|
+
})(["background:none;border:none;padding:0;height:2rem;width:2rem;display:flex;align-items:center;justify-content:center;cursor:pointer;color:", ";&:hover{color:", ";}"], _ref4 => {
|
|
61
|
+
let {
|
|
62
|
+
destructive
|
|
63
|
+
} = _ref4;
|
|
64
|
+
return destructive ? '#ef4444' : 'inherit';
|
|
65
|
+
}, _ref5 => {
|
|
66
|
+
let {
|
|
67
|
+
destructive
|
|
68
|
+
} = _ref5;
|
|
69
|
+
return destructive ? '#ef4444' : '#374151';
|
|
70
|
+
});
|
|
71
|
+
const BmDepartmentCard = _ref6 => {
|
|
72
|
+
let {
|
|
73
|
+
borderTopColor = '#cccccc',
|
|
74
|
+
isActive = true,
|
|
75
|
+
name,
|
|
76
|
+
description,
|
|
77
|
+
resourcesCount,
|
|
78
|
+
onEdit,
|
|
79
|
+
onDelete,
|
|
80
|
+
EditIcon,
|
|
81
|
+
DeleteIcon
|
|
82
|
+
} = _ref6;
|
|
83
|
+
return /*#__PURE__*/_react.default.createElement(CardWrapper, {
|
|
84
|
+
borderTopColor: borderTopColor,
|
|
85
|
+
isActive: isActive
|
|
86
|
+
}, /*#__PURE__*/_react.default.createElement(Header, null, /*#__PURE__*/_react.default.createElement(TitleRow, null, /*#__PURE__*/_react.default.createElement(CardTitle, null, name), /*#__PURE__*/_react.default.createElement(IconButtonsContainer, null, /*#__PURE__*/_react.default.createElement(IconButton, {
|
|
87
|
+
onClick: onEdit
|
|
88
|
+
}, EditIcon && /*#__PURE__*/_react.default.createElement(EditIcon, {
|
|
89
|
+
fontSize: "small"
|
|
90
|
+
})), /*#__PURE__*/_react.default.createElement(IconButton, {
|
|
91
|
+
destructive: true,
|
|
92
|
+
onClick: onDelete
|
|
93
|
+
}, DeleteIcon && /*#__PURE__*/_react.default.createElement(DeleteIcon, {
|
|
94
|
+
fontSize: "small"
|
|
95
|
+
})))), /*#__PURE__*/_react.default.createElement(CardDescription, null, description)), /*#__PURE__*/_react.default.createElement(Content, null, /*#__PURE__*/_react.default.createElement(ResourceText, null, resourcesCount, " Resources"), /*#__PURE__*/_react.default.createElement(StatusRow, null, /*#__PURE__*/_react.default.createElement(StatusDot, {
|
|
96
|
+
isActive: isActive
|
|
97
|
+
}), /*#__PURE__*/_react.default.createElement(StatusText, null, isActive ? 'Active' : 'Inactive'))));
|
|
98
|
+
};
|
|
99
|
+
var _default = exports.default = BmDepartmentCard;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = exports.Inactive = exports.Active = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _Edit = _interopRequireDefault(require("@mui/icons-material/Edit"));
|
|
9
|
+
var _Delete = _interopRequireDefault(require("@mui/icons-material/Delete"));
|
|
10
|
+
var _DepartmentCard = _interopRequireDefault(require("./DepartmentCard"));
|
|
11
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
13
|
+
var _default = exports.default = {
|
|
14
|
+
title: 'Components/BmDepartmentCard',
|
|
15
|
+
component: _DepartmentCard.default,
|
|
16
|
+
argTypes: {
|
|
17
|
+
borderTopColor: {
|
|
18
|
+
control: 'color'
|
|
19
|
+
},
|
|
20
|
+
isActive: {
|
|
21
|
+
control: 'boolean'
|
|
22
|
+
},
|
|
23
|
+
name: {
|
|
24
|
+
control: 'text'
|
|
25
|
+
},
|
|
26
|
+
description: {
|
|
27
|
+
control: 'text'
|
|
28
|
+
},
|
|
29
|
+
resourcesCount: {
|
|
30
|
+
control: 'number'
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const Template = args => /*#__PURE__*/_react.default.createElement(_DepartmentCard.default, _extends({}, args, {
|
|
35
|
+
EditIcon: _Edit.default,
|
|
36
|
+
DeleteIcon: _Delete.default
|
|
37
|
+
}));
|
|
38
|
+
const Active = exports.Active = Template.bind({});
|
|
39
|
+
Active.args = {
|
|
40
|
+
borderTopColor: '#3b82f6',
|
|
41
|
+
isActive: true,
|
|
42
|
+
name: 'Radiology',
|
|
43
|
+
description: 'Handles imaging and scans for diagnosis',
|
|
44
|
+
resourcesCount: 5
|
|
45
|
+
};
|
|
46
|
+
const Inactive = exports.Inactive = Template.bind({});
|
|
47
|
+
Inactive.args = {
|
|
48
|
+
borderTopColor: '#ef4444',
|
|
49
|
+
isActive: false,
|
|
50
|
+
name: 'Cardiology',
|
|
51
|
+
description: 'Provides heart-related care and surgeries',
|
|
52
|
+
resourcesCount: 3
|
|
53
|
+
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _styledComponents = _interopRequireDefault(require("styled-components"));
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
/* eslint-disable react/no-array-index-key */
|
|
11
|
+
|
|
12
|
+
const CardWrapper = _styledComponents.default.div.withConfig({
|
|
13
|
+
displayName: "ResourceCard__CardWrapper"
|
|
14
|
+
})(["overflow:hidden;border:1px solid #e5e7eb;border-radius:0.5rem;border-top:4px solid ", ";background-color:#ffffff;opacity:", ";transition:opacity 0.3s;"], _ref => {
|
|
15
|
+
let {
|
|
16
|
+
borderTopColor
|
|
17
|
+
} = _ref;
|
|
18
|
+
return borderTopColor || '#cccccc';
|
|
19
|
+
}, _ref2 => {
|
|
20
|
+
let {
|
|
21
|
+
isActive
|
|
22
|
+
} = _ref2;
|
|
23
|
+
return isActive ? 1 : 0.5;
|
|
24
|
+
});
|
|
25
|
+
const Header = _styledComponents.default.div.withConfig({
|
|
26
|
+
displayName: "ResourceCard__Header"
|
|
27
|
+
})(["padding:1rem 1rem 0.5rem 1rem;"]);
|
|
28
|
+
const TitleRow = _styledComponents.default.div.withConfig({
|
|
29
|
+
displayName: "ResourceCard__TitleRow"
|
|
30
|
+
})(["display:flex;justify-content:space-between;align-items:flex-start;"]);
|
|
31
|
+
const TitleContainer = _styledComponents.default.div.withConfig({
|
|
32
|
+
displayName: "ResourceCard__TitleContainer"
|
|
33
|
+
})(["display:flex;flex-direction:column;"]);
|
|
34
|
+
const CardTitle = _styledComponents.default.h3.withConfig({
|
|
35
|
+
displayName: "ResourceCard__CardTitle"
|
|
36
|
+
})(["font-size:1.125rem;margin:0;"]);
|
|
37
|
+
const BadgeRow = _styledComponents.default.div.withConfig({
|
|
38
|
+
displayName: "ResourceCard__BadgeRow"
|
|
39
|
+
})(["display:flex;gap:0.5rem;margin-top:0.25rem;flex-wrap:wrap;"]);
|
|
40
|
+
const Badge = _styledComponents.default.span.withConfig({
|
|
41
|
+
displayName: "ResourceCard__Badge"
|
|
42
|
+
})(["display:inline-flex;align-items:center;border:1px solid #e5e7eb;border-radius:0.375rem;padding:0.125rem 0.5rem;font-size:0.75rem;background-color:#f9fafb;color:", ";"], _ref3 => {
|
|
43
|
+
let {
|
|
44
|
+
color
|
|
45
|
+
} = _ref3;
|
|
46
|
+
return color || 'inherit';
|
|
47
|
+
});
|
|
48
|
+
const IconsContainer = _styledComponents.default.div.withConfig({
|
|
49
|
+
displayName: "ResourceCard__IconsContainer"
|
|
50
|
+
})(["display:flex;gap:0.25rem;"]);
|
|
51
|
+
const IconButton = _styledComponents.default.button.withConfig({
|
|
52
|
+
displayName: "ResourceCard__IconButton"
|
|
53
|
+
})(["background:none;border:none;padding:0;height:2rem;width:2rem;display:flex;align-items:center;justify-content:center;cursor:pointer;color:", ";&:hover{color:", ";}"], _ref4 => {
|
|
54
|
+
let {
|
|
55
|
+
destructive
|
|
56
|
+
} = _ref4;
|
|
57
|
+
return destructive ? '#ef4444' : 'inherit';
|
|
58
|
+
}, _ref5 => {
|
|
59
|
+
let {
|
|
60
|
+
destructive
|
|
61
|
+
} = _ref5;
|
|
62
|
+
return destructive ? '#ef4444' : '#374151';
|
|
63
|
+
});
|
|
64
|
+
const Content = _styledComponents.default.div.withConfig({
|
|
65
|
+
displayName: "ResourceCard__Content"
|
|
66
|
+
})(["margin-top:1rem;padding:0 1rem 0.5rem 1rem;display:flex;flex-direction:column;gap:0.5rem;font-size:0.875rem;"]);
|
|
67
|
+
const InfoRow = _styledComponents.default.div.withConfig({
|
|
68
|
+
displayName: "ResourceCard__InfoRow"
|
|
69
|
+
})(["display:flex;flex-wrap:wrap;gap:0.25rem;"]);
|
|
70
|
+
const Label = _styledComponents.default.span.withConfig({
|
|
71
|
+
displayName: "ResourceCard__Label"
|
|
72
|
+
})(["color:#6b7280;font-size:0.875rem;"]);
|
|
73
|
+
const Value = _styledComponents.default.span.withConfig({
|
|
74
|
+
displayName: "ResourceCard__Value"
|
|
75
|
+
})(["color:#374151;font-size:0.875rem;"]);
|
|
76
|
+
const Footer = _styledComponents.default.div.withConfig({
|
|
77
|
+
displayName: "ResourceCard__Footer"
|
|
78
|
+
})(["display:flex;justify-content:flex-end;align-items:center;margin-top:1rem;padding:0 1rem 0.75rem 1rem;"]);
|
|
79
|
+
const StatusDot = _styledComponents.default.span.withConfig({
|
|
80
|
+
displayName: "ResourceCard__StatusDot"
|
|
81
|
+
})(["flex-shrink:0;width:0.5rem;height:0.5rem;margin-right:0.5rem;border-radius:9999px;background-color:", ";"], _ref6 => {
|
|
82
|
+
let {
|
|
83
|
+
isActive
|
|
84
|
+
} = _ref6;
|
|
85
|
+
return isActive ? '#22c55e' : '#9ca3af';
|
|
86
|
+
});
|
|
87
|
+
const StatusText = _styledComponents.default.span.withConfig({
|
|
88
|
+
displayName: "ResourceCard__StatusText"
|
|
89
|
+
})(["font-size:0.75rem;color:#6b7280;"]);
|
|
90
|
+
const BmResourceCard = _ref7 => {
|
|
91
|
+
let {
|
|
92
|
+
borderTopColor = '#cccccc',
|
|
93
|
+
isActive = true,
|
|
94
|
+
name,
|
|
95
|
+
type,
|
|
96
|
+
resourceBadges = [],
|
|
97
|
+
departmentName,
|
|
98
|
+
email,
|
|
99
|
+
phone,
|
|
100
|
+
capacity,
|
|
101
|
+
features,
|
|
102
|
+
availability,
|
|
103
|
+
onEdit,
|
|
104
|
+
onDelete,
|
|
105
|
+
EditIcon,
|
|
106
|
+
DeleteIcon
|
|
107
|
+
} = _ref7;
|
|
108
|
+
return /*#__PURE__*/_react.default.createElement(CardWrapper, {
|
|
109
|
+
borderTopColor: borderTopColor,
|
|
110
|
+
isActive: isActive
|
|
111
|
+
}, /*#__PURE__*/_react.default.createElement(Header, null, /*#__PURE__*/_react.default.createElement(TitleRow, null, /*#__PURE__*/_react.default.createElement(TitleContainer, null, /*#__PURE__*/_react.default.createElement(CardTitle, null, name), /*#__PURE__*/_react.default.createElement(BadgeRow, null, /*#__PURE__*/_react.default.createElement(Badge, null, type), resourceBadges.map((badge, index) => /*#__PURE__*/_react.default.createElement(Badge, {
|
|
112
|
+
key: index,
|
|
113
|
+
color: badge.color
|
|
114
|
+
}, badge.icon && /*#__PURE__*/_react.default.createElement(badge.icon, {
|
|
115
|
+
style: {
|
|
116
|
+
fontSize: 14,
|
|
117
|
+
marginRight: 4
|
|
118
|
+
}
|
|
119
|
+
}), badge.label)))), /*#__PURE__*/_react.default.createElement(IconsContainer, null, /*#__PURE__*/_react.default.createElement(IconButton, {
|
|
120
|
+
onClick: onEdit
|
|
121
|
+
}, EditIcon && /*#__PURE__*/_react.default.createElement(EditIcon, {
|
|
122
|
+
fontSize: "small"
|
|
123
|
+
})), /*#__PURE__*/_react.default.createElement(IconButton, {
|
|
124
|
+
destructive: true,
|
|
125
|
+
onClick: onDelete
|
|
126
|
+
}, DeleteIcon && /*#__PURE__*/_react.default.createElement(DeleteIcon, {
|
|
127
|
+
fontSize: "small"
|
|
128
|
+
}))))), /*#__PURE__*/_react.default.createElement(Content, null, departmentName && /*#__PURE__*/_react.default.createElement(InfoRow, null, /*#__PURE__*/_react.default.createElement(Label, null, "Department:"), /*#__PURE__*/_react.default.createElement(Value, null, departmentName)), type === 'staff' && email && /*#__PURE__*/_react.default.createElement(InfoRow, null, /*#__PURE__*/_react.default.createElement(Label, null, "Email:"), /*#__PURE__*/_react.default.createElement(Value, null, email)), type === 'staff' && phone && /*#__PURE__*/_react.default.createElement(InfoRow, null, /*#__PURE__*/_react.default.createElement(Label, null, "Phone:"), /*#__PURE__*/_react.default.createElement(Value, null, phone)), type === 'room' && capacity && /*#__PURE__*/_react.default.createElement(InfoRow, null, /*#__PURE__*/_react.default.createElement(Label, null, "Capacity:"), /*#__PURE__*/_react.default.createElement(Value, null, capacity)), type === 'room' && features && features.length > 0 && /*#__PURE__*/_react.default.createElement(InfoRow, null, /*#__PURE__*/_react.default.createElement(Label, null, "Features:"), /*#__PURE__*/_react.default.createElement(Value, null, features.join(', '))), availability && /*#__PURE__*/_react.default.createElement(InfoRow, null, /*#__PURE__*/_react.default.createElement(Label, null, "Availability:"), /*#__PURE__*/_react.default.createElement(Value, null, availability))), /*#__PURE__*/_react.default.createElement(Footer, null, /*#__PURE__*/_react.default.createElement(StatusDot, {
|
|
129
|
+
isActive: isActive
|
|
130
|
+
}), /*#__PURE__*/_react.default.createElement(StatusText, null, isActive ? 'Active' : 'Inactive')));
|
|
131
|
+
};
|
|
132
|
+
var _default = exports.default = BmResourceCard;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = exports.StaffExample = exports.RoomExample = exports.Default = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _Edit = _interopRequireDefault(require("@mui/icons-material/Edit"));
|
|
9
|
+
var _Delete = _interopRequireDefault(require("@mui/icons-material/Delete"));
|
|
10
|
+
var _CalendarToday = _interopRequireDefault(require("@mui/icons-material/CalendarToday"));
|
|
11
|
+
var _ResourceCard = _interopRequireDefault(require("./ResourceCard"));
|
|
12
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
14
|
+
var _default = exports.default = {
|
|
15
|
+
title: 'Components/BmResourceCard',
|
|
16
|
+
component: _ResourceCard.default,
|
|
17
|
+
argTypes: {
|
|
18
|
+
borderTopColor: {
|
|
19
|
+
control: 'color'
|
|
20
|
+
},
|
|
21
|
+
isActive: {
|
|
22
|
+
control: 'boolean'
|
|
23
|
+
},
|
|
24
|
+
name: {
|
|
25
|
+
control: 'text'
|
|
26
|
+
},
|
|
27
|
+
type: {
|
|
28
|
+
control: 'text'
|
|
29
|
+
},
|
|
30
|
+
departmentName: {
|
|
31
|
+
control: 'text'
|
|
32
|
+
},
|
|
33
|
+
email: {
|
|
34
|
+
control: 'text'
|
|
35
|
+
},
|
|
36
|
+
phone: {
|
|
37
|
+
control: 'text'
|
|
38
|
+
},
|
|
39
|
+
capacity: {
|
|
40
|
+
control: 'number'
|
|
41
|
+
},
|
|
42
|
+
availability: {
|
|
43
|
+
control: 'text'
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const Template = args => /*#__PURE__*/_react.default.createElement(_ResourceCard.default, _extends({}, args, {
|
|
48
|
+
EditIcon: _Edit.default,
|
|
49
|
+
DeleteIcon: _Delete.default
|
|
50
|
+
}));
|
|
51
|
+
const Default = exports.Default = Template.bind({});
|
|
52
|
+
Default.args = {
|
|
53
|
+
borderTopColor: '#3b82f6',
|
|
54
|
+
isActive: true,
|
|
55
|
+
name: 'Room 101',
|
|
56
|
+
type: 'room',
|
|
57
|
+
resourceBadges: [{
|
|
58
|
+
label: 'Synced',
|
|
59
|
+
icon: _CalendarToday.default,
|
|
60
|
+
color: '#10b981'
|
|
61
|
+
}],
|
|
62
|
+
departmentName: 'Radiology',
|
|
63
|
+
capacity: 12,
|
|
64
|
+
features: ['Projector', 'Whiteboard'],
|
|
65
|
+
availability: 'Weekdays 9am - 5pm'
|
|
66
|
+
};
|
|
67
|
+
const StaffExample = exports.StaffExample = Template.bind({});
|
|
68
|
+
StaffExample.args = {
|
|
69
|
+
borderTopColor: '#10b981',
|
|
70
|
+
isActive: true,
|
|
71
|
+
name: 'Dr. Sarah Johnson',
|
|
72
|
+
type: 'staff',
|
|
73
|
+
resourceBadges: [{
|
|
74
|
+
label: 'Google Synced',
|
|
75
|
+
icon: _CalendarToday.default,
|
|
76
|
+
color: '#3b82f6'
|
|
77
|
+
}],
|
|
78
|
+
departmentName: 'Cardiology',
|
|
79
|
+
email: 'sarah.johnson@hospital.com',
|
|
80
|
+
phone: '+1 555 123 4567',
|
|
81
|
+
availability: 'Mon - Fri, 9am - 3pm'
|
|
82
|
+
};
|
|
83
|
+
const RoomExample = exports.RoomExample = Template.bind({});
|
|
84
|
+
RoomExample.args = {
|
|
85
|
+
borderTopColor: '#f59e0b',
|
|
86
|
+
isActive: false,
|
|
87
|
+
name: 'Conference Room B',
|
|
88
|
+
type: 'room',
|
|
89
|
+
resourceBadges: [],
|
|
90
|
+
departmentName: 'Oncology',
|
|
91
|
+
capacity: 20,
|
|
92
|
+
features: ['Video Conferencing', 'AC', 'Whiteboard'],
|
|
93
|
+
availability: 'Available on demand'
|
|
94
|
+
};
|
package/dist/components/index.js
CHANGED
|
@@ -178,6 +178,12 @@ Object.defineProperty(exports, "BmCustomCardTitle", {
|
|
|
178
178
|
return _CustomCardTitle.default;
|
|
179
179
|
}
|
|
180
180
|
});
|
|
181
|
+
Object.defineProperty(exports, "BmDepartmentCard", {
|
|
182
|
+
enumerable: true,
|
|
183
|
+
get: function () {
|
|
184
|
+
return _DepartmentCard.default;
|
|
185
|
+
}
|
|
186
|
+
});
|
|
181
187
|
Object.defineProperty(exports, "BmEmojiIcon", {
|
|
182
188
|
enumerable: true,
|
|
183
189
|
get: function () {
|
|
@@ -310,6 +316,12 @@ Object.defineProperty(exports, "BmQuickReplyIcon", {
|
|
|
310
316
|
return _iconStyles.BmQuickReplyIcon;
|
|
311
317
|
}
|
|
312
318
|
});
|
|
319
|
+
Object.defineProperty(exports, "BmResourceCard", {
|
|
320
|
+
enumerable: true,
|
|
321
|
+
get: function () {
|
|
322
|
+
return _ResourceCard.default;
|
|
323
|
+
}
|
|
324
|
+
});
|
|
313
325
|
Object.defineProperty(exports, "BmRouteLink", {
|
|
314
326
|
enumerable: true,
|
|
315
327
|
get: function () {
|
|
@@ -479,5 +491,7 @@ var _InfoPanel = _interopRequireDefault(require("./InfoPanel/InfoPanel"));
|
|
|
479
491
|
var _BmSelector = _interopRequireDefault(require("./BmSelector/BmSelector"));
|
|
480
492
|
var _CustomCardTitle = _interopRequireDefault(require("./BmCustomCardTitle/CustomCardTitle"));
|
|
481
493
|
var _Alert = _interopRequireDefault(require("./Alert/Alert"));
|
|
494
|
+
var _DepartmentCard = _interopRequireDefault(require("./DepartmentCard/DepartmentCard"));
|
|
495
|
+
var _ResourceCard = _interopRequireDefault(require("./ResourceCard/ResourceCard"));
|
|
482
496
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
483
497
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
package/package.json
CHANGED
package/src/App.js
CHANGED
|
@@ -4,11 +4,14 @@
|
|
|
4
4
|
import React, { useState } from 'react';
|
|
5
5
|
// import AbcIcon from '@mui/icons-material/Abc';
|
|
6
6
|
// import LocalOfferOutlinedIcon from '@mui/icons-material/LocalOfferOutlined';
|
|
7
|
-
|
|
7
|
+
import CalendarTodayIcon from '@mui/icons-material/CalendarToday';
|
|
8
8
|
import AccessTimeIcon from '@mui/icons-material/AccessTime';
|
|
9
9
|
import PersonIcon from '@mui/icons-material/Person';
|
|
10
10
|
import CalendarTodayOutlinedIcon from '@mui/icons-material/CalendarTodayOutlined';
|
|
11
11
|
import CheckIcon from '@mui/icons-material/Check';
|
|
12
|
+
import EditIcon from '@mui/icons-material/Edit';
|
|
13
|
+
import DeleteIcon from '@mui/icons-material/Delete';
|
|
14
|
+
// import CalendarTodayIcon from '@mui/icons-material/CalendarToday';
|
|
12
15
|
// import { Tooltip } from '@mui/material';
|
|
13
16
|
import PeopleIcon from '@mui/icons-material/People';
|
|
14
17
|
// import BusinessIcon from '@mui/icons-material/Business';
|
|
@@ -36,8 +39,11 @@ import {
|
|
|
36
39
|
BmSelectionNotice,
|
|
37
40
|
BmSelector,
|
|
38
41
|
BmCustomCardTitle,
|
|
42
|
+
BmDepartmentCard,
|
|
43
|
+
BmResourceCard,
|
|
39
44
|
} from './lib/components';
|
|
40
45
|
import AlertBox from './lib/components/Alert/Alert';
|
|
46
|
+
import { TabPanel, Tabs } from './lib/components/BmTabv2/BmTabV2.';
|
|
41
47
|
// import ProgressIndicator from './lib/components/newProgress';
|
|
42
48
|
|
|
43
49
|
// const datsa = JSON.stringify({
|
|
@@ -1011,6 +1017,65 @@ const Chat = () => {
|
|
|
1011
1017
|
<>
|
|
1012
1018
|
<GlobalStyle />
|
|
1013
1019
|
<div style={{ display: 'flex', flexDirection: 'column', gap: '2rem' }}>
|
|
1020
|
+
<Tabs defaultValue={0}>
|
|
1021
|
+
<TabPanel title="Overview">
|
|
1022
|
+
<p>This is the Overview content.</p>
|
|
1023
|
+
</TabPanel>
|
|
1024
|
+
<TabPanel title="Details">
|
|
1025
|
+
<p>This is the Details content.</p>
|
|
1026
|
+
</TabPanel>
|
|
1027
|
+
<TabPanel title="Settings">
|
|
1028
|
+
<p>This is the Settings content.</p>
|
|
1029
|
+
</TabPanel>
|
|
1030
|
+
</Tabs>
|
|
1031
|
+
<div style={{ width: '100%', maxWidth: '900px', margin: '2rem auto' }}>
|
|
1032
|
+
<div style={{ maxWidth: 400, margin: '2rem auto' }}>
|
|
1033
|
+
<BmDepartmentCard
|
|
1034
|
+
borderTopColor="#3b82f6" // blue
|
|
1035
|
+
isActive="true"
|
|
1036
|
+
name="Radiology Department"
|
|
1037
|
+
description="Handles imaging and diagnostic scans"
|
|
1038
|
+
resourcesCount={0}
|
|
1039
|
+
onEdit={() => alert('Edit department')}
|
|
1040
|
+
onDelete={() => alert('Delete department')}
|
|
1041
|
+
EditIcon={EditIcon}
|
|
1042
|
+
DeleteIcon={DeleteIcon}
|
|
1043
|
+
/>
|
|
1044
|
+
|
|
1045
|
+
<BmDepartmentCard
|
|
1046
|
+
borderTopColor="#f97316" // orange
|
|
1047
|
+
isActive={false}
|
|
1048
|
+
name="Cardiology Department"
|
|
1049
|
+
description="Heart and blood vessel treatments"
|
|
1050
|
+
resourcesCount={5}
|
|
1051
|
+
onEdit={() => alert('Edit department')}
|
|
1052
|
+
onDelete={() => alert('Delete department')}
|
|
1053
|
+
EditIcon={EditIcon}
|
|
1054
|
+
DeleteIcon={DeleteIcon}
|
|
1055
|
+
/>
|
|
1056
|
+
<BmResourceCard
|
|
1057
|
+
borderTopColor="#10b981"
|
|
1058
|
+
isActive="true"
|
|
1059
|
+
name="Dr. Jane Smith"
|
|
1060
|
+
type="staff"
|
|
1061
|
+
resourceBadges={[
|
|
1062
|
+
{
|
|
1063
|
+
label: 'Google Synced',
|
|
1064
|
+
color: '#10b981',
|
|
1065
|
+
icon: CalendarTodayIcon,
|
|
1066
|
+
},
|
|
1067
|
+
]}
|
|
1068
|
+
departmentName="Radiology"
|
|
1069
|
+
email="jane.smith@example.com"
|
|
1070
|
+
phone="+123456789"
|
|
1071
|
+
availability="Mon-Fri 9am-5pm"
|
|
1072
|
+
onEdit={() => alert('Edit resource')}
|
|
1073
|
+
onDelete={() => alert('Delete resource')}
|
|
1074
|
+
EditIcon={EditIcon}
|
|
1075
|
+
DeleteIcon={DeleteIcon}
|
|
1076
|
+
/>
|
|
1077
|
+
</div>
|
|
1078
|
+
</div>
|
|
1014
1079
|
<div>
|
|
1015
1080
|
<BmInfoPanel.SectionSummary
|
|
1016
1081
|
iconColor="#33B1BA"
|
package/src/fonts.scss
CHANGED
|
@@ -28,7 +28,4 @@
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
@
|
|
32
|
-
font-family: 'Inter';
|
|
33
|
-
src: url('../src/fonts/Inter-regular.woff2')format('woff2'),url('../src/fonts/Inter-Bold.woff2')format('woff2'),url('../src/fonts/Inter-ExtraBold.woff2')format('woff2'),url('../src/fonts/Inter-ExtraLight.woff2')format('woff2'),url('../src/fonts/Inter-medium.woff2')format('woff2'),url('../src/fonts/Inter-SemiBold.woff2')format('woff2');
|
|
34
|
-
}
|
|
31
|
+
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
|
+
import styled, { css } from 'styled-components';
|
|
5
|
+
|
|
6
|
+
// Utility
|
|
7
|
+
const cn = (...classes) => classes.filter(Boolean).join(' ');
|
|
8
|
+
|
|
9
|
+
// Styled components
|
|
10
|
+
|
|
11
|
+
const TabsContainer = styled.div`
|
|
12
|
+
display: flex;
|
|
13
|
+
flex-direction: column;
|
|
14
|
+
gap: 0.5rem;
|
|
15
|
+
|
|
16
|
+
@media (max-width: 640px) {
|
|
17
|
+
gap: 0.25rem;
|
|
18
|
+
}
|
|
19
|
+
`;
|
|
20
|
+
|
|
21
|
+
const TabsList = styled.div`
|
|
22
|
+
display: flex;
|
|
23
|
+
flex-wrap: nowrap;
|
|
24
|
+
background: #f5f5f5;
|
|
25
|
+
overflow-x: auto;
|
|
26
|
+
padding: 3px;
|
|
27
|
+
border-radius: 8px;
|
|
28
|
+
|
|
29
|
+
&::-webkit-scrollbar {
|
|
30
|
+
display: none;
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
const TabButton = styled.button`
|
|
35
|
+
flex: 1 0 auto;
|
|
36
|
+
display: inline-flex;
|
|
37
|
+
align-items: center;
|
|
38
|
+
justify-content: center;
|
|
39
|
+
gap: 6px;
|
|
40
|
+
padding: 0.5rem 0.75rem;
|
|
41
|
+
font-size: 0.875rem;
|
|
42
|
+
font-weight: 500;
|
|
43
|
+
white-space: nowrap;
|
|
44
|
+
border: 1px solid transparent;
|
|
45
|
+
border-radius: 8px;
|
|
46
|
+
background: transparent;
|
|
47
|
+
color: #333;
|
|
48
|
+
cursor: pointer;
|
|
49
|
+
transition: all 0.2s;
|
|
50
|
+
|
|
51
|
+
${({ active }) =>
|
|
52
|
+
active &&
|
|
53
|
+
css`
|
|
54
|
+
background: #ffffff;
|
|
55
|
+
color: #111111;
|
|
56
|
+
border-color: #ddd;
|
|
57
|
+
`}
|
|
58
|
+
|
|
59
|
+
&:focus-visible {
|
|
60
|
+
outline: 2px solid #3b82f6;
|
|
61
|
+
outline-offset: 2px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
&:disabled {
|
|
65
|
+
pointer-events: none;
|
|
66
|
+
opacity: 0.5;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
svg {
|
|
70
|
+
flex-shrink: 0;
|
|
71
|
+
pointer-events: none;
|
|
72
|
+
width: 1rem;
|
|
73
|
+
height: 1rem;
|
|
74
|
+
}
|
|
75
|
+
`;
|
|
76
|
+
|
|
77
|
+
const TabContent = styled.div`
|
|
78
|
+
flex: 1;
|
|
79
|
+
padding: 0.5rem 0;
|
|
80
|
+
`;
|
|
81
|
+
|
|
82
|
+
// Main Tabs component
|
|
83
|
+
|
|
84
|
+
// eslint-disable-next-line func-style
|
|
85
|
+
function Tabs({ defaultValue = 0, children, className }) {
|
|
86
|
+
const [activeIndex, setActiveIndex] = useState(defaultValue);
|
|
87
|
+
|
|
88
|
+
// Get all children that are type of TabPanel (so we can match titles & content)
|
|
89
|
+
const tabPanels = React.Children.toArray(children).filter(
|
|
90
|
+
(child) => child.type.displayName === 'TabPanel'
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<TabsContainer className={cn(className)}>
|
|
95
|
+
<TabsList>
|
|
96
|
+
{tabPanels.map((panel, index) => (
|
|
97
|
+
<TabButton
|
|
98
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
99
|
+
key={index}
|
|
100
|
+
active={activeIndex === index}
|
|
101
|
+
onClick={() => setActiveIndex(index)}
|
|
102
|
+
>
|
|
103
|
+
{panel.props.title}
|
|
104
|
+
</TabButton>
|
|
105
|
+
))}
|
|
106
|
+
</TabsList>
|
|
107
|
+
<TabContent>
|
|
108
|
+
{tabPanels[activeIndex] && tabPanels[activeIndex].props.children}
|
|
109
|
+
</TabContent>
|
|
110
|
+
</TabsContainer>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Individual Tab panel component
|
|
115
|
+
// eslint-disable-next-line func-style
|
|
116
|
+
function TabPanel({ children }) {
|
|
117
|
+
return <>{children}</>;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
TabPanel.displayName = 'TabPanel';
|
|
121
|
+
|
|
122
|
+
export { Tabs, TabPanel };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
|
|
4
|
+
const CardWrapper = styled.div`
|
|
5
|
+
overflow: hidden;
|
|
6
|
+
|
|
7
|
+
border-radius: 0.5rem;
|
|
8
|
+
border: 1px solid #e5e7eb;
|
|
9
|
+
border-top: 4px solid ${({ borderTopColor }) => borderTopColor || '#cccccc'};
|
|
10
|
+
|
|
11
|
+
background-color: #ffffff;
|
|
12
|
+
opacity: ${({ isActive }) => (isActive ? 1 : 0.5)};
|
|
13
|
+
transition: opacity 0.3s;
|
|
14
|
+
`;
|
|
15
|
+
|
|
16
|
+
const Header = styled.div`
|
|
17
|
+
padding: 1rem 1rem 0.5rem 1rem;
|
|
18
|
+
`;
|
|
19
|
+
|
|
20
|
+
const TitleRow = styled.div`
|
|
21
|
+
display: flex;
|
|
22
|
+
justify-content: space-between;
|
|
23
|
+
align-items: flex-start;
|
|
24
|
+
`;
|
|
25
|
+
|
|
26
|
+
const CardTitle = styled.h3`
|
|
27
|
+
font-size: 1.125rem;
|
|
28
|
+
margin: 0;
|
|
29
|
+
`;
|
|
30
|
+
|
|
31
|
+
const CardDescription = styled.p`
|
|
32
|
+
font-size: 0.875rem;
|
|
33
|
+
color: #6b7280;
|
|
34
|
+
margin-top: 0.25rem;
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
const Content = styled.div`
|
|
38
|
+
margin-top: 1rem;
|
|
39
|
+
padding: 0 1rem 0.5rem 1rem;
|
|
40
|
+
display: flex;
|
|
41
|
+
justify-content: space-between;
|
|
42
|
+
align-items: center;
|
|
43
|
+
`;
|
|
44
|
+
|
|
45
|
+
const ResourceText = styled.span`
|
|
46
|
+
font-size: 0.875rem;
|
|
47
|
+
color: #6b7280;
|
|
48
|
+
`;
|
|
49
|
+
|
|
50
|
+
const StatusRow = styled.div`
|
|
51
|
+
display: flex;
|
|
52
|
+
align-items: center;
|
|
53
|
+
`;
|
|
54
|
+
|
|
55
|
+
const StatusDot = styled.span`
|
|
56
|
+
flex-shrink: 0;
|
|
57
|
+
width: 0.5rem;
|
|
58
|
+
height: 0.5rem;
|
|
59
|
+
margin-right: 0.5rem;
|
|
60
|
+
border-radius: 9999px;
|
|
61
|
+
background-color: ${({ isActive }) => (isActive ? '#22c55e' : '#9ca3af')};
|
|
62
|
+
`;
|
|
63
|
+
|
|
64
|
+
const StatusText = styled.span`
|
|
65
|
+
font-size: 0.75rem;
|
|
66
|
+
color: #6b7280;
|
|
67
|
+
`;
|
|
68
|
+
|
|
69
|
+
const IconButtonsContainer = styled.div`
|
|
70
|
+
display: flex;
|
|
71
|
+
gap: 0.25rem;
|
|
72
|
+
`;
|
|
73
|
+
|
|
74
|
+
const IconButton = styled.button`
|
|
75
|
+
background: none;
|
|
76
|
+
border: none;
|
|
77
|
+
padding: 0;
|
|
78
|
+
height: 2rem;
|
|
79
|
+
width: 2rem;
|
|
80
|
+
display: flex;
|
|
81
|
+
align-items: center;
|
|
82
|
+
justify-content: center;
|
|
83
|
+
cursor: pointer;
|
|
84
|
+
color: ${({ destructive }) => (destructive ? '#ef4444' : 'inherit')};
|
|
85
|
+
|
|
86
|
+
&:hover {
|
|
87
|
+
color: ${({ destructive }) => (destructive ? '#ef4444' : '#374151')};
|
|
88
|
+
}
|
|
89
|
+
`;
|
|
90
|
+
|
|
91
|
+
const BmDepartmentCard = ({
|
|
92
|
+
borderTopColor = '#cccccc',
|
|
93
|
+
isActive = true,
|
|
94
|
+
name,
|
|
95
|
+
description,
|
|
96
|
+
resourcesCount,
|
|
97
|
+
onEdit,
|
|
98
|
+
onDelete,
|
|
99
|
+
EditIcon,
|
|
100
|
+
DeleteIcon,
|
|
101
|
+
}) => {
|
|
102
|
+
return (
|
|
103
|
+
<CardWrapper borderTopColor={borderTopColor} isActive={isActive}>
|
|
104
|
+
<Header>
|
|
105
|
+
<TitleRow>
|
|
106
|
+
<CardTitle>{name}</CardTitle>
|
|
107
|
+
<IconButtonsContainer>
|
|
108
|
+
<IconButton onClick={onEdit}>
|
|
109
|
+
{EditIcon && <EditIcon fontSize="small" />}
|
|
110
|
+
</IconButton>
|
|
111
|
+
<IconButton destructive onClick={onDelete}>
|
|
112
|
+
{DeleteIcon && <DeleteIcon fontSize="small" />}
|
|
113
|
+
</IconButton>
|
|
114
|
+
</IconButtonsContainer>
|
|
115
|
+
</TitleRow>
|
|
116
|
+
<CardDescription>{description}</CardDescription>
|
|
117
|
+
</Header>
|
|
118
|
+
<Content>
|
|
119
|
+
<ResourceText>{resourcesCount} Resources</ResourceText>
|
|
120
|
+
|
|
121
|
+
<StatusRow>
|
|
122
|
+
<StatusDot isActive={isActive} />
|
|
123
|
+
<StatusText>{isActive ? 'Active' : 'Inactive'}</StatusText>
|
|
124
|
+
</StatusRow>
|
|
125
|
+
</Content>
|
|
126
|
+
</CardWrapper>
|
|
127
|
+
);
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export default BmDepartmentCard;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import EditIcon from '@mui/icons-material/Edit';
|
|
3
|
+
import DeleteIcon from '@mui/icons-material/Delete';
|
|
4
|
+
import BmDepartmentCard from './DepartmentCard';
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
title: 'Components/BmDepartmentCard',
|
|
8
|
+
component: BmDepartmentCard,
|
|
9
|
+
argTypes: {
|
|
10
|
+
borderTopColor: { control: 'color' },
|
|
11
|
+
isActive: { control: 'boolean' },
|
|
12
|
+
name: { control: 'text' },
|
|
13
|
+
description: { control: 'text' },
|
|
14
|
+
resourcesCount: { control: 'number' },
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const Template = (args) => (
|
|
19
|
+
<BmDepartmentCard {...args} EditIcon={EditIcon} DeleteIcon={DeleteIcon} />
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
export const Active = Template.bind({});
|
|
23
|
+
Active.args = {
|
|
24
|
+
borderTopColor: '#3b82f6',
|
|
25
|
+
isActive: true,
|
|
26
|
+
name: 'Radiology',
|
|
27
|
+
description: 'Handles imaging and scans for diagnosis',
|
|
28
|
+
resourcesCount: 5,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const Inactive = Template.bind({});
|
|
32
|
+
Inactive.args = {
|
|
33
|
+
borderTopColor: '#ef4444',
|
|
34
|
+
isActive: false,
|
|
35
|
+
name: 'Cardiology',
|
|
36
|
+
description: 'Provides heart-related care and surgeries',
|
|
37
|
+
resourcesCount: 3,
|
|
38
|
+
};
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/* eslint-disable react/no-array-index-key */
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import styled from 'styled-components';
|
|
4
|
+
|
|
5
|
+
const CardWrapper = styled.div`
|
|
6
|
+
overflow: hidden;
|
|
7
|
+
border: 1px solid #e5e7eb;
|
|
8
|
+
border-radius: 0.5rem;
|
|
9
|
+
border-top: 4px solid ${({ borderTopColor }) => borderTopColor || '#cccccc'};
|
|
10
|
+
background-color: #ffffff;
|
|
11
|
+
opacity: ${({ isActive }) => (isActive ? 1 : 0.5)};
|
|
12
|
+
transition: opacity 0.3s;
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
const Header = styled.div`
|
|
16
|
+
padding: 1rem 1rem 0.5rem 1rem;
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
const TitleRow = styled.div`
|
|
20
|
+
display: flex;
|
|
21
|
+
justify-content: space-between;
|
|
22
|
+
align-items: flex-start;
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
const TitleContainer = styled.div`
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-direction: column;
|
|
28
|
+
`;
|
|
29
|
+
|
|
30
|
+
const CardTitle = styled.h3`
|
|
31
|
+
font-size: 1.125rem;
|
|
32
|
+
margin: 0;
|
|
33
|
+
`;
|
|
34
|
+
|
|
35
|
+
const BadgeRow = styled.div`
|
|
36
|
+
display: flex;
|
|
37
|
+
gap: 0.5rem;
|
|
38
|
+
margin-top: 0.25rem;
|
|
39
|
+
flex-wrap: wrap;
|
|
40
|
+
`;
|
|
41
|
+
|
|
42
|
+
const Badge = styled.span`
|
|
43
|
+
display: inline-flex;
|
|
44
|
+
align-items: center;
|
|
45
|
+
border: 1px solid #e5e7eb;
|
|
46
|
+
border-radius: 0.375rem;
|
|
47
|
+
padding: 0.125rem 0.5rem;
|
|
48
|
+
font-size: 0.75rem;
|
|
49
|
+
background-color: #f9fafb;
|
|
50
|
+
color: ${({ color }) => color || 'inherit'};
|
|
51
|
+
`;
|
|
52
|
+
|
|
53
|
+
const IconsContainer = styled.div`
|
|
54
|
+
display: flex;
|
|
55
|
+
gap: 0.25rem;
|
|
56
|
+
`;
|
|
57
|
+
|
|
58
|
+
const IconButton = styled.button`
|
|
59
|
+
background: none;
|
|
60
|
+
border: none;
|
|
61
|
+
padding: 0;
|
|
62
|
+
height: 2rem;
|
|
63
|
+
width: 2rem;
|
|
64
|
+
display: flex;
|
|
65
|
+
align-items: center;
|
|
66
|
+
justify-content: center;
|
|
67
|
+
cursor: pointer;
|
|
68
|
+
color: ${({ destructive }) => (destructive ? '#ef4444' : 'inherit')};
|
|
69
|
+
|
|
70
|
+
&:hover {
|
|
71
|
+
color: ${({ destructive }) => (destructive ? '#ef4444' : '#374151')};
|
|
72
|
+
}
|
|
73
|
+
`;
|
|
74
|
+
|
|
75
|
+
const Content = styled.div`
|
|
76
|
+
margin-top: 1rem;
|
|
77
|
+
padding: 0 1rem 0.5rem 1rem;
|
|
78
|
+
display: flex;
|
|
79
|
+
flex-direction: column;
|
|
80
|
+
gap: 0.5rem;
|
|
81
|
+
font-size: 0.875rem;
|
|
82
|
+
`;
|
|
83
|
+
|
|
84
|
+
const InfoRow = styled.div`
|
|
85
|
+
display: flex;
|
|
86
|
+
flex-wrap: wrap;
|
|
87
|
+
gap: 0.25rem;
|
|
88
|
+
`;
|
|
89
|
+
|
|
90
|
+
const Label = styled.span`
|
|
91
|
+
color: #6b7280;
|
|
92
|
+
font-size: 0.875rem;
|
|
93
|
+
`;
|
|
94
|
+
|
|
95
|
+
const Value = styled.span`
|
|
96
|
+
color: #374151;
|
|
97
|
+
font-size: 0.875rem;
|
|
98
|
+
`;
|
|
99
|
+
|
|
100
|
+
const Footer = styled.div`
|
|
101
|
+
display: flex;
|
|
102
|
+
justify-content: flex-end;
|
|
103
|
+
align-items: center;
|
|
104
|
+
margin-top: 1rem;
|
|
105
|
+
padding: 0 1rem 0.75rem 1rem;
|
|
106
|
+
`;
|
|
107
|
+
|
|
108
|
+
const StatusDot = styled.span`
|
|
109
|
+
flex-shrink: 0;
|
|
110
|
+
width: 0.5rem;
|
|
111
|
+
height: 0.5rem;
|
|
112
|
+
margin-right: 0.5rem;
|
|
113
|
+
border-radius: 9999px;
|
|
114
|
+
background-color: ${({ isActive }) => (isActive ? '#22c55e' : '#9ca3af')};
|
|
115
|
+
`;
|
|
116
|
+
|
|
117
|
+
const StatusText = styled.span`
|
|
118
|
+
font-size: 0.75rem;
|
|
119
|
+
color: #6b7280;
|
|
120
|
+
`;
|
|
121
|
+
|
|
122
|
+
const BmResourceCard = ({
|
|
123
|
+
borderTopColor = '#cccccc',
|
|
124
|
+
isActive = true,
|
|
125
|
+
name,
|
|
126
|
+
type,
|
|
127
|
+
resourceBadges = [],
|
|
128
|
+
departmentName,
|
|
129
|
+
email,
|
|
130
|
+
phone,
|
|
131
|
+
capacity,
|
|
132
|
+
features,
|
|
133
|
+
availability,
|
|
134
|
+
onEdit,
|
|
135
|
+
onDelete,
|
|
136
|
+
EditIcon,
|
|
137
|
+
DeleteIcon,
|
|
138
|
+
}) => {
|
|
139
|
+
return (
|
|
140
|
+
<CardWrapper borderTopColor={borderTopColor} isActive={isActive}>
|
|
141
|
+
<Header>
|
|
142
|
+
<TitleRow>
|
|
143
|
+
<TitleContainer>
|
|
144
|
+
<CardTitle>{name}</CardTitle>
|
|
145
|
+
<BadgeRow>
|
|
146
|
+
<Badge>{type}</Badge>
|
|
147
|
+
{resourceBadges.map((badge, index) => (
|
|
148
|
+
<Badge key={index} color={badge.color}>
|
|
149
|
+
{badge.icon && (
|
|
150
|
+
<badge.icon style={{ fontSize: 14, marginRight: 4 }} />
|
|
151
|
+
)}
|
|
152
|
+
{badge.label}
|
|
153
|
+
</Badge>
|
|
154
|
+
))}
|
|
155
|
+
</BadgeRow>
|
|
156
|
+
</TitleContainer>
|
|
157
|
+
<IconsContainer>
|
|
158
|
+
<IconButton onClick={onEdit}>
|
|
159
|
+
{EditIcon && <EditIcon fontSize="small" />}
|
|
160
|
+
</IconButton>
|
|
161
|
+
<IconButton destructive onClick={onDelete}>
|
|
162
|
+
{DeleteIcon && <DeleteIcon fontSize="small" />}
|
|
163
|
+
</IconButton>
|
|
164
|
+
</IconsContainer>
|
|
165
|
+
</TitleRow>
|
|
166
|
+
</Header>
|
|
167
|
+
<Content>
|
|
168
|
+
{departmentName && (
|
|
169
|
+
<InfoRow>
|
|
170
|
+
<Label>Department:</Label>
|
|
171
|
+
<Value>{departmentName}</Value>
|
|
172
|
+
</InfoRow>
|
|
173
|
+
)}
|
|
174
|
+
{type === 'staff' && email && (
|
|
175
|
+
<InfoRow>
|
|
176
|
+
<Label>Email:</Label>
|
|
177
|
+
<Value>{email}</Value>
|
|
178
|
+
</InfoRow>
|
|
179
|
+
)}
|
|
180
|
+
{type === 'staff' && phone && (
|
|
181
|
+
<InfoRow>
|
|
182
|
+
<Label>Phone:</Label>
|
|
183
|
+
<Value>{phone}</Value>
|
|
184
|
+
</InfoRow>
|
|
185
|
+
)}
|
|
186
|
+
{type === 'room' && capacity && (
|
|
187
|
+
<InfoRow>
|
|
188
|
+
<Label>Capacity:</Label>
|
|
189
|
+
<Value>{capacity}</Value>
|
|
190
|
+
</InfoRow>
|
|
191
|
+
)}
|
|
192
|
+
{type === 'room' && features && features.length > 0 && (
|
|
193
|
+
<InfoRow>
|
|
194
|
+
<Label>Features:</Label>
|
|
195
|
+
<Value>{features.join(', ')}</Value>
|
|
196
|
+
</InfoRow>
|
|
197
|
+
)}
|
|
198
|
+
{availability && (
|
|
199
|
+
<InfoRow>
|
|
200
|
+
<Label>Availability:</Label>
|
|
201
|
+
<Value>{availability}</Value>
|
|
202
|
+
</InfoRow>
|
|
203
|
+
)}
|
|
204
|
+
</Content>
|
|
205
|
+
<Footer>
|
|
206
|
+
<StatusDot isActive={isActive} />
|
|
207
|
+
<StatusText>{isActive ? 'Active' : 'Inactive'}</StatusText>
|
|
208
|
+
</Footer>
|
|
209
|
+
</CardWrapper>
|
|
210
|
+
);
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
export default BmResourceCard;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import EditIcon from '@mui/icons-material/Edit';
|
|
3
|
+
import DeleteIcon from '@mui/icons-material/Delete';
|
|
4
|
+
import CalendarTodayIcon from '@mui/icons-material/CalendarToday';
|
|
5
|
+
import BmResourceCard from './ResourceCard';
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
title: 'Components/BmResourceCard',
|
|
9
|
+
component: BmResourceCard,
|
|
10
|
+
argTypes: {
|
|
11
|
+
borderTopColor: { control: 'color' },
|
|
12
|
+
isActive: { control: 'boolean' },
|
|
13
|
+
name: { control: 'text' },
|
|
14
|
+
type: { control: 'text' },
|
|
15
|
+
departmentName: { control: 'text' },
|
|
16
|
+
email: { control: 'text' },
|
|
17
|
+
phone: { control: 'text' },
|
|
18
|
+
capacity: { control: 'number' },
|
|
19
|
+
availability: { control: 'text' },
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const Template = (args) => (
|
|
24
|
+
<BmResourceCard {...args} EditIcon={EditIcon} DeleteIcon={DeleteIcon} />
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
export const Default = Template.bind({});
|
|
28
|
+
Default.args = {
|
|
29
|
+
borderTopColor: '#3b82f6',
|
|
30
|
+
isActive: true,
|
|
31
|
+
name: 'Room 101',
|
|
32
|
+
type: 'room',
|
|
33
|
+
resourceBadges: [
|
|
34
|
+
{ label: 'Synced', icon: CalendarTodayIcon, color: '#10b981' },
|
|
35
|
+
],
|
|
36
|
+
departmentName: 'Radiology',
|
|
37
|
+
capacity: 12,
|
|
38
|
+
features: ['Projector', 'Whiteboard'],
|
|
39
|
+
availability: 'Weekdays 9am - 5pm',
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const StaffExample = Template.bind({});
|
|
43
|
+
StaffExample.args = {
|
|
44
|
+
borderTopColor: '#10b981',
|
|
45
|
+
isActive: true,
|
|
46
|
+
name: 'Dr. Sarah Johnson',
|
|
47
|
+
type: 'staff',
|
|
48
|
+
resourceBadges: [
|
|
49
|
+
{ label: 'Google Synced', icon: CalendarTodayIcon, color: '#3b82f6' },
|
|
50
|
+
],
|
|
51
|
+
departmentName: 'Cardiology',
|
|
52
|
+
email: 'sarah.johnson@hospital.com',
|
|
53
|
+
phone: '+1 555 123 4567',
|
|
54
|
+
availability: 'Mon - Fri, 9am - 3pm',
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const RoomExample = Template.bind({});
|
|
58
|
+
RoomExample.args = {
|
|
59
|
+
borderTopColor: '#f59e0b',
|
|
60
|
+
isActive: false,
|
|
61
|
+
name: 'Conference Room B',
|
|
62
|
+
type: 'room',
|
|
63
|
+
resourceBadges: [],
|
|
64
|
+
departmentName: 'Oncology',
|
|
65
|
+
capacity: 20,
|
|
66
|
+
features: ['Video Conferencing', 'AC', 'Whiteboard'],
|
|
67
|
+
availability: 'Available on demand',
|
|
68
|
+
};
|
|
@@ -83,6 +83,8 @@ import BmInfoPanel from './InfoPanel/InfoPanel';
|
|
|
83
83
|
import BmSelector from './BmSelector/BmSelector';
|
|
84
84
|
import BmCustomCardTitle from './BmCustomCardTitle/CustomCardTitle';
|
|
85
85
|
import BmAlertBox from './Alert/Alert';
|
|
86
|
+
import BmDepartmentCard from './DepartmentCard/DepartmentCard';
|
|
87
|
+
import BmResourceCard from './ResourceCard/ResourceCard';
|
|
86
88
|
|
|
87
89
|
export {
|
|
88
90
|
BmAccordion,
|
|
@@ -163,4 +165,6 @@ export {
|
|
|
163
165
|
BmSelector,
|
|
164
166
|
BmCustomCardTitle,
|
|
165
167
|
BmAlertBox,
|
|
168
|
+
BmDepartmentCard,
|
|
169
|
+
BmResourceCard,
|
|
166
170
|
};
|