Skip to content

Commit be49827

Browse files
authored
✨ Create an organization (#20)
1 parent 0bd9d4a commit be49827

28 files changed

+503
-144
lines changed

frontend/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="UTF-8" />
55
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7-
<title>Full Stack FastAPI Project</title>
7+
<title>FastAPI Cloud</title>
88
<link rel="icon" type="image/x-icon" href="./src/assets/images/favicon.png" />
99
</head>
1010
<body>

frontend/src/components/Admin/AddUser.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,10 @@ const AddUser = ({ isOpen, onClose }: AddUserProps) => {
166166
</Flex>
167167
</ModalBody>
168168
<ModalFooter gap={3}>
169+
<Button onClick={onClose}>Cancel</Button>
169170
<Button variant="primary" type="submit" isLoading={isSubmitting}>
170171
Save
171172
</Button>
172-
<Button onClick={onClose}>Cancel</Button>
173173
</ModalFooter>
174174
</ModalContent>
175175
</Modal>

frontend/src/components/Admin/EditUser.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ const EditUser = ({ user, isOpen, onClose }: EditUserProps) => {
166166
</ModalBody>
167167

168168
<ModalFooter gap={3}>
169+
<Button onClick={onCancel}>Cancel</Button>
169170
<Button
170171
variant="primary"
171172
type="submit"
@@ -174,7 +175,6 @@ const EditUser = ({ user, isOpen, onClose }: EditUserProps) => {
174175
>
175176
Save
176177
</Button>
177-
<Button onClick={onCancel}>Cancel</Button>
178178
</ModalFooter>
179179
</ModalContent>
180180
</Modal>

frontend/src/components/Billing/Plans.tsx

Lines changed: 47 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,65 @@
11
import {
22
Box,
3+
Button,
34
Flex,
5+
Icon,
46
List,
5-
Radio,
6-
RadioGroup,
77
Stack,
88
Text,
99
VStack,
1010
} from "@chakra-ui/react"
1111
import { FaCheckCircle } from "react-icons/fa"
1212

13-
const items = [
14-
{
15-
value: "1",
16-
title: "Basic",
17-
description: "For small teams and early-stage startups.",
18-
price: "5",
19-
},
20-
{
21-
value: "2",
22-
title: "Advanced",
23-
description: "For larger teams and established companies.",
24-
price: "18",
25-
},
26-
{
27-
value: "3",
28-
title: "Enterprise",
29-
description: "For large organizations with advanced needs.",
30-
price: "32",
31-
},
32-
]
13+
import { FaCircleXmark } from "react-icons/fa6"
14+
import { items } from "./PlansData"
3315

3416
const Plans = () => {
35-
const listItems = items.map(({ value, title, description, price }) => (
36-
<Box border="1px solid lightgray" p={4} borderRadius="16px" key={value}>
37-
<VStack spacing={4}>
38-
<Radio value={value} colorScheme="teal">
39-
{title}
40-
</Radio>
41-
<Text fontSize="sm">{description}</Text>
42-
<Flex textAlign="center" flexDir="column">
43-
<Text fontSize="xl" color="ui.main">
44-
$ {price}
17+
const listItems = items.map(
18+
({ value, title, description, price, features }) => (
19+
<Box border="1px solid lightgray" p={4} borderRadius="lg" key={value}>
20+
<VStack spacing={4}>
21+
<Text textTransform="uppercase" fontWeight="bold">
22+
{title}
4523
</Text>
46-
<Text fontSize="sm">per user/month</Text>
47-
</Flex>
48-
<List>
49-
<Text fontSize="sm" display="flex" gap={2}>
50-
<FaCheckCircle />
51-
Up to 10 users
52-
</Text>
53-
<Text fontSize="sm" display="flex" gap={2}>
54-
<FaCheckCircle />
55-
Basic support
56-
</Text>
57-
<Text fontSize="sm" display="flex" gap={2}>
58-
<FaCheckCircle />
59-
Unlimited projects
60-
</Text>
61-
</List>
62-
</VStack>
63-
</Box>
64-
))
24+
<Text fontSize="sm">{description}</Text>
25+
<Flex textAlign="center" flexDir="column">
26+
<Text fontSize="4xl" fontWeight="bold" color="ui.main">
27+
$ {price}
28+
</Text>
29+
<Text fontSize="sm">per month</Text>
30+
</Flex>
31+
<List>
32+
{Object.values(features).map((feature, index) => (
33+
<Text
34+
key={index}
35+
fontSize="sm"
36+
display="flex"
37+
alignItems="center"
38+
textDecoration={feature.value ? "none" : "line-through"}
39+
gap={2}
40+
>
41+
{feature.value ? (
42+
<Icon as={FaCheckCircle} color="ui.main" />
43+
) : (
44+
<Icon as={FaCircleXmark} color="ui.dim" />
45+
)}
46+
47+
{feature.name}
48+
</Text>
49+
))}
50+
</List>
51+
<Button variant="outline" size="sm">
52+
Choose Plan
53+
</Button>
54+
</VStack>
55+
</Box>
56+
),
57+
)
6558
return (
6659
<>
67-
<RadioGroup>
68-
<Stack direction={{ base: "column", md: "row" }} gap={10}>
69-
{listItems}
70-
</Stack>
71-
</RadioGroup>
60+
<Stack direction={{ base: "column", md: "row" }} gap={10}>
61+
{listItems}
62+
</Stack>
7263
</>
7364
)
7465
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
export const items = [
2+
{
3+
value: "1",
4+
title: "Team",
5+
description: "For small teams and early-stage startups.",
6+
price: "50",
7+
features: {
8+
users: {
9+
name: "Up to 10 users",
10+
value: true,
11+
},
12+
bandwidth: {
13+
name: "500 GB in free bandwidth",
14+
value: true,
15+
},
16+
migration: {
17+
name: "Migration support",
18+
value: false,
19+
},
20+
support: {
21+
name: "Dedicated support",
22+
value: false,
23+
},
24+
hibba: {
25+
name: "HIPAA/BAA support",
26+
value: false,
27+
},
28+
},
29+
},
30+
{
31+
value: "2",
32+
title: "Organization",
33+
description: "For larger teams and established companies.",
34+
price: "180",
35+
features: {
36+
users: {
37+
name: "Up to 50 users",
38+
value: true,
39+
},
40+
bandwidth: {
41+
name: "1 TB in free bandwidth",
42+
value: true,
43+
},
44+
migration: {
45+
name: "Migration support",
46+
value: false,
47+
},
48+
support: {
49+
name: "Dedicated support",
50+
value: false,
51+
},
52+
hibba: {
53+
name: "HIPAA/BAA support",
54+
value: false,
55+
},
56+
},
57+
},
58+
{
59+
value: "300",
60+
title: "Enterprise",
61+
description: "For large organizations with advanced needs.",
62+
price: "320",
63+
features: {
64+
users: {
65+
name: "Unlimited users",
66+
value: true,
67+
},
68+
bandwidth: {
69+
name: "Custom bandwidth usage",
70+
value: true,
71+
},
72+
migration: {
73+
name: "Migration support",
74+
value: true,
75+
},
76+
support: {
77+
name: "Dedicated support",
78+
value: true,
79+
},
80+
hibba: {
81+
name: "HIPAA/BAA support",
82+
value: true,
83+
},
84+
},
85+
},
86+
]

frontend/src/components/Common/ActionsMenu.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import {
77
useDisclosure,
88
} from "@chakra-ui/react"
99
import { BsThreeDotsVertical } from "react-icons/bs"
10-
import { FiEdit, FiTrash } from "react-icons/fi"
1110

11+
import { FaEdit, FaTrash } from "react-icons/fa"
1212
import type { ItemPublic, UserPublic } from "../../client"
1313
import EditUser from "../Admin/EditUser"
1414
import EditItem from "../Items/EditItem"
@@ -36,13 +36,13 @@ const ActionsMenu = ({ type, value, disabled }: ActionsMenuProps) => {
3636
<MenuList>
3737
<MenuItem
3838
onClick={editUserModal.onOpen}
39-
icon={<FiEdit fontSize="16px" />}
39+
icon={<FaEdit fontSize="16px" />}
4040
>
4141
Edit {type}
4242
</MenuItem>
4343
<MenuItem
4444
onClick={deleteModal.onOpen}
45-
icon={<FiTrash fontSize="16px" />}
45+
icon={<FaTrash fontSize="16px" />}
4646
color="ui.danger"
4747
>
4848
Delete {type}

frontend/src/components/Common/DeleteAlert.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,16 @@ const Delete = ({ type, id, isOpen, onClose }: DeleteProps) => {
9292
</AlertDialogBody>
9393

9494
<AlertDialogFooter gap={3}>
95-
<Button variant="danger" type="submit" isLoading={isSubmitting}>
96-
Delete
97-
</Button>
9895
<Button
9996
ref={cancelRef}
10097
onClick={onClose}
10198
isDisabled={isSubmitting}
10299
>
103100
Cancel
104101
</Button>
102+
<Button variant="danger" type="submit" isLoading={isSubmitting}>
103+
Delete
104+
</Button>
105105
</AlertDialogFooter>
106106
</AlertDialogContent>
107107
</AlertDialogOverlay>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { Icon, Input, InputGroup, InputRightElement } from "@chakra-ui/react"
2+
import { FaSearch } from "react-icons/fa"
3+
4+
const Searchbar = () => {
5+
return (
6+
<>
7+
<InputGroup mx={8}>
8+
<Input
9+
variant="filled"
10+
type="text"
11+
placeholder="Search"
12+
fontSize={{ base: "sm", md: "inherit" }}
13+
borderRadius="8px"
14+
/>
15+
<InputRightElement pointerEvents="none">
16+
<Icon as={FaSearch} color="ui.dim" />
17+
</InputRightElement>
18+
</InputGroup>
19+
</>
20+
)
21+
}
22+
23+
export default Searchbar

frontend/src/components/Common/Sidebar.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,11 @@ const Sidebar = () => {
6969
<Box
7070
position="sticky"
7171
display={{ base: "none", md: "flex" }}
72+
boxShadow="md"
7273
minW="250px"
7374
h="100vh"
7475
top="0"
75-
p={4}
76+
p={6}
7677
>
7778
<Box justifyContent="center" w="100%">
7879
<Center>
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Button, Flex, Icon, useDisclosure } from "@chakra-ui/react"
2-
import { FaPlus } from "react-icons/fa"
2+
import { FaEdit, FaPlus } from "react-icons/fa"
33

44
import AddUser from "../Admin/AddUser"
55
import AddItem from "../Items/AddItem"
@@ -8,33 +8,33 @@ interface NavbarProps {
88
type: string
99
}
1010

11-
const Navbar = ({ type }: NavbarProps) => {
11+
const TableActionsButtons = ({ type }: NavbarProps) => {
1212
const addUserModal = useDisclosure()
1313
const addItemModal = useDisclosure()
1414

1515
return (
1616
<>
17-
<Flex py={8} gap={4}>
18-
{/* TODO: Complete search functionality */}
19-
{/* <InputGroup w={{ base: '100%', md: 'auto' }}>
20-
<InputLeftElement pointerEvents='none'>
21-
<Icon as={FaSearch} color='ui.dim' />
22-
</InputLeftElement>
23-
<Input type='text' placeholder='Search' fontSize={{ base: 'sm', md: 'inherit' }} borderRadius='8px' />
24-
</InputGroup> */}
17+
<Flex py={8} gap={4} justify="end">
2518
<Button
2619
variant="primary"
27-
gap={1}
28-
fontSize={{ base: "sm", md: "inherit" }}
20+
gap={2}
2921
onClick={type === "User" ? addUserModal.onOpen : addItemModal.onOpen}
3022
>
3123
<Icon as={FaPlus} /> Add {type}
3224
</Button>
25+
{type === "User" && (
26+
<>
27+
<Button variant="primary" gap={2}>
28+
<Icon as={FaEdit} />
29+
Edit Organization
30+
</Button>
31+
</>
32+
)}
3333
<AddUser isOpen={addUserModal.isOpen} onClose={addUserModal.onClose} />
3434
<AddItem isOpen={addItemModal.isOpen} onClose={addItemModal.onClose} />
3535
</Flex>
3636
</>
3737
)
3838
}
3939

40-
export default Navbar
40+
export default TableActionsButtons

0 commit comments

Comments
 (0)