@@ -6,15 +6,18 @@ import Container from '@/components/container';
66import HeaderContainer from '@/components/header-container' ;
77import Heading from '@/components/heading' ;
88import { Button } from '@/components/ui/button' ;
9- import { BookOpenIcon , LoaderCircleIcon } from 'lucide-react' ;
10- import { FormEvent } from 'react' ;
9+ import { BookOpenIcon , LoaderCircleIcon , XIcon } from 'lucide-react' ;
10+ import React , { FormEvent } from 'react' ;
1111import { LoadBalancerServer } from '@/types/load-balancer-server' ;
1212import { Card , CardContent , CardDescription , CardFooter , CardHeader , CardTitle } from '@/components/ui/card' ;
1313import { Form , FormField , FormFields } from '@/components/ui/form' ;
1414import { Label } from '@/components/ui/label' ;
1515import { Select , SelectContent , SelectGroup , SelectItem , SelectTrigger , SelectValue } from '@/components/ui/select' ;
1616import InputError from '@/components/ui/input-error' ;
1717import FormSuccessful from '@/components/form-successful' ;
18+ import ServerSelect from '@/pages/servers/components/server-select' ;
19+ import { Input } from '@/components/ui/input' ;
20+ import { Switch } from '@/components/ui/switch' ;
1821
1922export default function LoadBalancer ( ) {
2023 const page = usePage < {
@@ -26,26 +29,42 @@ export default function LoadBalancer() {
2629 const form = useForm < {
2730 method : 'round-robin' | 'least-connections' | 'ip-hash' ;
2831 servers : {
29- server : string ;
30- port : string ;
32+ load_balancer_id : number ;
33+ ip : string ;
34+ port : number ;
3135 weight : string ;
3236 backup : boolean ;
3337 } [ ] ;
3438 } > ( {
3539 method : 'round-robin' ,
36- servers : [ ] ,
40+ servers : page . props . loadBalancerServers ,
3741 } ) ;
3842
43+ const addServer = ( ) => {
44+ const newServer : LoadBalancerServer = {
45+ load_balancer_id : 0 ,
46+ ip : '' ,
47+ port : 80 ,
48+ weight : '100' ,
49+ backup : false ,
50+ created_at : '' ,
51+ updated_at : '' ,
52+ } ;
53+
54+ form . setData ( 'servers' , [ ...form . data . servers , newServer ] ) ;
55+ } ;
56+
3957 const submit = ( e : FormEvent ) => {
4058 e . preventDefault ( ) ;
4159 form . post ( route ( 'application.update-load-balancer' , { server : page . props . server . id , site : page . props . site . id } ) , {
42- onSuccess : ( ) => {
43- form . reset ( ) ;
44- } ,
4560 preserveScroll : true ,
4661 } ) ;
4762 } ;
4863
64+ const getFieldError = ( field : string ) : string | undefined => {
65+ return form . errors [ field as keyof typeof form . errors ] ;
66+ } ;
67+
4968 return (
5069 < ServerLayout >
5170 < Head title = { `${ page . props . site . domain } - ${ page . props . server . name } ` } />
@@ -90,6 +109,99 @@ export default function LoadBalancer() {
90109 </ Select >
91110 < InputError message = { form . errors . method } />
92111 </ FormField >
112+
113+ { form . data . servers . map ( ( item , index ) => (
114+ < div key = { `server-${ index } ` } className = "relative rounded-md border border-dashed p-4" >
115+ < XIcon
116+ className = "text-muted-foreground hover:text-foreground absolute top-2 right-2 cursor-pointer"
117+ onClick = { ( ) => {
118+ const updatedServers = [ ...form . data . servers ] ;
119+ updatedServers . splice ( index , 1 ) ;
120+ form . setData ( 'servers' , updatedServers ) ;
121+ } }
122+ />
123+ < div className = "grid grid-cols-1 items-start gap-6 md:grid-cols-2 lg:grid-cols-4" >
124+ < FormField >
125+ < Label htmlFor = { `server-${ index } ` } > Server</ Label >
126+ < ServerSelect
127+ id = { `server-${ index } ` }
128+ value = { item . ip }
129+ valueBy = "local_ip"
130+ onValueChange = { ( server ) => {
131+ const updatedServers = [ ...form . data . servers ] ;
132+ updatedServers [ index ] = {
133+ ...updatedServers [ index ] ,
134+ ip : server ? server . local_ip || '' : '' ,
135+ } ;
136+ form . setData ( 'servers' , updatedServers ) ;
137+ } }
138+ />
139+ < InputError message = { getFieldError ( `servers.${ index } .ip` ) } />
140+ </ FormField >
141+
142+ < FormField >
143+ < Label htmlFor = { `port-${ index } ` } > Port</ Label >
144+ < Input
145+ id = { `port-${ index } ` }
146+ type = "text"
147+ value = { item . port || '' }
148+ onChange = { ( e ) => {
149+ const updatedServers = [ ...form . data . servers ] ;
150+ updatedServers [ index ] = {
151+ ...updatedServers [ index ] ,
152+ port : parseInt ( e . target . value , 10 ) ,
153+ } ;
154+ form . setData ( 'servers' , updatedServers ) ;
155+ } }
156+ />
157+ < InputError message = { getFieldError ( `servers.${ index } .port` ) } />
158+ </ FormField >
159+
160+ < FormField >
161+ < Label htmlFor = { `weight-${ index } ` } > Weight</ Label >
162+ < Input
163+ id = { `weight-${ index } ` }
164+ type = "text"
165+ value = { item . weight || '100' }
166+ onChange = { ( e ) => {
167+ const updatedServers = [ ...form . data . servers ] ;
168+ updatedServers [ index ] = {
169+ ...updatedServers [ index ] ,
170+ weight : e . target . value ,
171+ } ;
172+ form . setData ( 'servers' , updatedServers ) ;
173+ } }
174+ />
175+ < InputError message = { getFieldError ( `servers.${ index } .weight` ) } />
176+ </ FormField >
177+
178+ < FormField >
179+ < Label htmlFor = { `backup-${ index } ` } > Backup</ Label >
180+ < Switch
181+ id = { `backup-${ index } ` }
182+ checked = { item . backup || false }
183+ onCheckedChange = { ( checked ) => {
184+ const updatedServers = [ ...form . data . servers ] ;
185+ updatedServers [ index ] = {
186+ ...updatedServers [ index ] ,
187+ backup : checked ,
188+ } ;
189+ form . setData ( 'servers' , updatedServers ) ;
190+ } }
191+ className = "mt-2"
192+ />
193+ < InputError message = { getFieldError ( `servers.${ index } .backup` ) } />
194+ </ FormField >
195+ </ div >
196+ </ div >
197+ ) ) }
198+
199+ < FormField
200+ onClick = { addServer }
201+ className = "text-muted-foreground hover:text-foreground flex h-[92px] items-center justify-center rounded-md border border-dashed hover:cursor-pointer"
202+ >
203+ Add server to the load balancer
204+ </ FormField >
93205 </ FormFields >
94206 </ Form >
95207 </ CardContent >
0 commit comments