AddSectionDialog.tsx 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. "use client";
  2. import { useState } from "react";
  3. import { useRouter } from "next/navigation";
  4. import { createLayoutSection } from "@/app/actions/layout-configurations";
  5. import { Button } from "@/components/ui/button";
  6. import {
  7. Dialog,
  8. DialogContent,
  9. DialogDescription,
  10. DialogFooter,
  11. DialogHeader,
  12. DialogTitle,
  13. } from "@/components/ui/dialog";
  14. import { Input } from "@/components/ui/input";
  15. import { Label } from "@/components/ui/label";
  16. import { Textarea } from "@/components/ui/textarea";
  17. import { useToast } from "@/hooks/use-toast";
  18. interface AddSectionDialogProps {
  19. configurationId: number;
  20. open: boolean;
  21. onOpenChange: (open: boolean) => void;
  22. }
  23. export function AddSectionDialog({
  24. configurationId,
  25. open,
  26. onOpenChange,
  27. }: AddSectionDialogProps) {
  28. const router = useRouter();
  29. const { toast } = useToast();
  30. const [isLoading, setIsLoading] = useState(false);
  31. const [formData, setFormData] = useState({
  32. name: "",
  33. type: "table",
  34. sheetName: "",
  35. tableName: "",
  36. startingRow: "",
  37. endingRow: "",
  38. });
  39. const handleSubmit = async (e: React.FormEvent) => {
  40. e.preventDefault();
  41. setIsLoading(true);
  42. try {
  43. const result = await createLayoutSection(configurationId, {
  44. name: formData.name,
  45. type: formData.type,
  46. sheetName: formData.sheetName,
  47. tableName: formData.tableName,
  48. startingRow: formData.startingRow ? parseInt(formData.startingRow) : undefined,
  49. endingRow: formData.endingRow ? parseInt(formData.endingRow) : undefined,
  50. });
  51. if (result.success) {
  52. toast({
  53. title: "Section added successfully",
  54. description: `Section "${formData.name}" has been added to the configuration.`,
  55. });
  56. // Reset form and close dialog
  57. setFormData({
  58. name: "",
  59. type: "table",
  60. sheetName: "",
  61. tableName: "",
  62. startingRow: "",
  63. endingRow: "",
  64. });
  65. onOpenChange(false);
  66. // Refresh the page to show the new section
  67. router.refresh();
  68. } else {
  69. toast({
  70. title: "Error adding section",
  71. description: result.error || "Failed to add section",
  72. variant: "destructive",
  73. });
  74. }
  75. } catch (error) {
  76. toast({
  77. title: "Error",
  78. description: "An unexpected error occurred",
  79. variant: "destructive",
  80. });
  81. } finally {
  82. setIsLoading(false);
  83. }
  84. };
  85. const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
  86. const { name, value } = e.target;
  87. setFormData((prev) => ({ ...prev, [name]: value }));
  88. };
  89. return (
  90. <Dialog open={open} onOpenChange={onOpenChange}>
  91. <DialogContent className="sm:max-w-[500px]">
  92. <DialogHeader>
  93. <DialogTitle>Add New Section</DialogTitle>
  94. <DialogDescription>
  95. Create a new section for this layout configuration
  96. </DialogDescription>
  97. </DialogHeader>
  98. <form onSubmit={handleSubmit}>
  99. <div className="grid gap-4 py-4">
  100. <div className="grid gap-2">
  101. <Label htmlFor="name">Section Name *</Label>
  102. <Input
  103. id="name"
  104. name="name"
  105. value={formData.name}
  106. onChange={handleChange}
  107. placeholder="e.g., Customer Information"
  108. required
  109. />
  110. </div>
  111. <div className="grid gap-2">
  112. <Label htmlFor="type">Section Type *</Label>
  113. <Input
  114. id="type"
  115. name="type"
  116. value={formData.type}
  117. onChange={handleChange}
  118. placeholder="e.g., table, header, footer"
  119. required
  120. />
  121. </div>
  122. <div className="grid gap-2">
  123. <Label htmlFor="sheetName">Sheet Name *</Label>
  124. <Input
  125. id="sheetName"
  126. name="sheetName"
  127. value={formData.sheetName}
  128. onChange={handleChange}
  129. placeholder="e.g., Sheet1"
  130. required
  131. />
  132. </div>
  133. <div className="grid gap-2">
  134. <Label htmlFor="tableName">Table Name *</Label>
  135. <Input
  136. id="tableName"
  137. name="tableName"
  138. value={formData.tableName}
  139. onChange={handleChange}
  140. placeholder="e.g., customers"
  141. required
  142. />
  143. </div>
  144. <div className="grid grid-cols-2 gap-4">
  145. <div className="grid gap-2">
  146. <Label htmlFor="startingRow">Starting Row</Label>
  147. <Input
  148. id="startingRow"
  149. name="startingRow"
  150. type="number"
  151. value={formData.startingRow}
  152. onChange={handleChange}
  153. placeholder="e.g., 2"
  154. min="1"
  155. />
  156. </div>
  157. <div className="grid gap-2">
  158. <Label htmlFor="endingRow">Ending Row</Label>
  159. <Input
  160. id="endingRow"
  161. name="endingRow"
  162. type="number"
  163. value={formData.endingRow}
  164. onChange={handleChange}
  165. placeholder="e.g., 100"
  166. min="1"
  167. />
  168. </div>
  169. </div>
  170. </div>
  171. <DialogFooter>
  172. <Button
  173. type="button"
  174. variant="outline"
  175. onClick={() => onOpenChange(false)}
  176. disabled={isLoading}
  177. >
  178. Cancel
  179. </Button>
  180. <Button type="submit" disabled={isLoading}>
  181. {isLoading ? "Adding..." : "Add Section"}
  182. </Button>
  183. </DialogFooter>
  184. </form>
  185. </DialogContent>
  186. </Dialog>
  187. );
  188. }