create-bdpa-react-scaffold 1.9.0 → 2.0.2
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/create-ui-lib.js +607 -84
- package/package.json +2 -2
package/create-ui-lib.js
CHANGED
|
@@ -658,6 +658,7 @@ export function cn(...inputs) {
|
|
|
658
658
|
write("src/index.js", `
|
|
659
659
|
export { Button } from "./components/ui/button.jsx";
|
|
660
660
|
|
|
661
|
+
export { default as Home } from "./pages/Home.jsx";
|
|
661
662
|
export { default as Login } from "./pages/auth/Login.jsx";
|
|
662
663
|
export { default as Register } from "./pages/auth/Register.jsx";
|
|
663
664
|
|
|
@@ -669,8 +670,50 @@ export { hashPassword, verifyPassword, getPasswordStrength, getPasswordStrengthL
|
|
|
669
670
|
`);
|
|
670
671
|
|
|
671
672
|
write("src/App.jsx", `
|
|
672
|
-
import { useState } from "react";
|
|
673
673
|
import { Routes, Route, useNavigate } from "react-router-dom";
|
|
674
|
+
import { toast } from "sonner";
|
|
675
|
+
import Home from "./pages/Home.jsx";
|
|
676
|
+
import Login from "./pages/auth/Login.jsx";
|
|
677
|
+
import Register from "./pages/auth/Register.jsx";
|
|
678
|
+
import ComponentTest from "./pages/ComponentTest.jsx";
|
|
679
|
+
|
|
680
|
+
export default function App() {
|
|
681
|
+
const navigate = useNavigate();
|
|
682
|
+
|
|
683
|
+
return (
|
|
684
|
+
<Routes>
|
|
685
|
+
<Route path="/" element={<Home />} />
|
|
686
|
+
<Route
|
|
687
|
+
path="/login"
|
|
688
|
+
element={
|
|
689
|
+
<Login
|
|
690
|
+
onSubmit={() => {
|
|
691
|
+
toast.success("Login submitted!");
|
|
692
|
+
navigate("/");
|
|
693
|
+
}}
|
|
694
|
+
/>
|
|
695
|
+
}
|
|
696
|
+
/>
|
|
697
|
+
<Route
|
|
698
|
+
path="/register"
|
|
699
|
+
element={
|
|
700
|
+
<Register
|
|
701
|
+
onSubmit={() => {
|
|
702
|
+
toast.success("Registration submitted!");
|
|
703
|
+
navigate("/");
|
|
704
|
+
}}
|
|
705
|
+
/>
|
|
706
|
+
}
|
|
707
|
+
/>
|
|
708
|
+
<Route path="/component-test" element={<ComponentTest />} />
|
|
709
|
+
</Routes>
|
|
710
|
+
);
|
|
711
|
+
}
|
|
712
|
+
`);
|
|
713
|
+
|
|
714
|
+
write("src/pages/Home.jsx", `
|
|
715
|
+
import { useState } from "react";
|
|
716
|
+
import { useNavigate } from "react-router-dom";
|
|
674
717
|
import { Button } from "@/components/ui/button";
|
|
675
718
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
676
719
|
import { Input } from "@/components/ui/input";
|
|
@@ -679,24 +722,38 @@ import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
|
|
|
679
722
|
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
|
680
723
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
|
681
724
|
import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet";
|
|
725
|
+
import { Badge } from "@/components/ui/badge";
|
|
726
|
+
import { Alert, AlertTitle, AlertDescription } from "@/components/ui/alert";
|
|
727
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
|
728
|
+
import { Checkbox } from "@/components/ui/checkbox";
|
|
729
|
+
import { Progress } from "@/components/ui/progress";
|
|
730
|
+
import { Separator } from "@/components/ui/separator";
|
|
731
|
+
import { Switch } from "@/components/ui/switch";
|
|
732
|
+
import { Textarea } from "@/components/ui/textarea";
|
|
733
|
+
import { Skeleton } from "@/components/ui/skeleton";
|
|
734
|
+
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
|
682
735
|
import { toast } from "sonner";
|
|
683
|
-
import { Menu } from "lucide-react";
|
|
684
|
-
import { ApiClient } from "
|
|
685
|
-
import Login from "./pages/auth/Login.jsx";
|
|
686
|
-
import Register from "./pages/auth/Register.jsx";
|
|
736
|
+
import { Menu, Info, CheckCircle } from "lucide-react";
|
|
737
|
+
import { ApiClient } from "@/utils/api.js";
|
|
687
738
|
|
|
688
739
|
const enrollmentData = [
|
|
689
740
|
{ name: "Alex", course: "Web Design Fundamentals", status: "Enrolled" },
|
|
690
741
|
{ name: "Jordan", course: "Advanced Web App Design", status: "Waitlisted" },
|
|
691
|
-
{ name: "Taylor", course: "eSports Strategy", status: "Enrolled" }
|
|
742
|
+
{ name: "Taylor", course: "eSports Strategy", status: "Enrolled" },
|
|
692
743
|
];
|
|
693
744
|
|
|
694
|
-
|
|
745
|
+
const navLinks = [
|
|
746
|
+
{ label: "Home", href: "/" },
|
|
747
|
+
{ label: "Login", href: "/login" },
|
|
748
|
+
{ label: "Register", href: "/register" },
|
|
749
|
+
{ label: "Component Test", href: "/component-test" },
|
|
750
|
+
];
|
|
751
|
+
|
|
752
|
+
export default function Home() {
|
|
695
753
|
const [modalOpen, setModalOpen] = useState(false);
|
|
696
754
|
const [posts, setPosts] = useState([]);
|
|
697
755
|
const [loadingPosts, setLoadingPosts] = useState(false);
|
|
698
756
|
const [postsError, setPostsError] = useState("");
|
|
699
|
-
const navigate = useNavigate();
|
|
700
757
|
const client = new ApiClient("https://jsonplaceholder.typicode.com");
|
|
701
758
|
|
|
702
759
|
const fetchPosts = async () => {
|
|
@@ -711,12 +768,6 @@ function Dashboard() {
|
|
|
711
768
|
setLoadingPosts(false);
|
|
712
769
|
};
|
|
713
770
|
|
|
714
|
-
const navLinks = [
|
|
715
|
-
{ label: "Home", href: "/" },
|
|
716
|
-
{ label: "Login", href: "/login" },
|
|
717
|
-
{ label: "Register", href: "/register" }
|
|
718
|
-
];
|
|
719
|
-
|
|
720
771
|
return (
|
|
721
772
|
<div className="flex h-screen overflow-hidden">
|
|
722
773
|
|
|
@@ -737,7 +788,6 @@ function Dashboard() {
|
|
|
737
788
|
|
|
738
789
|
{/* Navbar */}
|
|
739
790
|
<nav className="bg-white border-b px-4 py-3 flex items-center justify-between">
|
|
740
|
-
{/* Mobile sidebar trigger */}
|
|
741
791
|
<Sheet>
|
|
742
792
|
<SheetTrigger asChild>
|
|
743
793
|
<Button variant="ghost" size="icon" className="md:hidden">
|
|
@@ -762,14 +812,10 @@ function Dashboard() {
|
|
|
762
812
|
{/* Page content */}
|
|
763
813
|
<div className="p-6 space-y-6 overflow-auto">
|
|
764
814
|
|
|
765
|
-
{/* BDPA Logo
|
|
815
|
+
{/* BDPA Logo */}
|
|
766
816
|
<Card className="text-center">
|
|
767
817
|
<CardContent className="pt-6">
|
|
768
|
-
<img
|
|
769
|
-
src="/BDPA_edited.png"
|
|
770
|
-
alt="BDPA Logo"
|
|
771
|
-
className="h-32 mx-auto mb-4"
|
|
772
|
-
/>
|
|
818
|
+
<img src="/BDPA_edited.png" alt="BDPA Logo" className="h-32 mx-auto mb-4" />
|
|
773
819
|
<h1 className="text-3xl font-bold text-blue-600">Welcome to BDPA</h1>
|
|
774
820
|
<p className="text-gray-600 mt-2">Black Data Professionals Association</p>
|
|
775
821
|
</CardContent>
|
|
@@ -782,14 +828,28 @@ function Dashboard() {
|
|
|
782
828
|
<TabsTrigger value="components">Components</TabsTrigger>
|
|
783
829
|
<TabsTrigger value="auth">Auth</TabsTrigger>
|
|
784
830
|
</TabsList>
|
|
785
|
-
<TabsContent value="overview"
|
|
786
|
-
|
|
787
|
-
|
|
831
|
+
<TabsContent value="overview">
|
|
832
|
+
<Alert className="mt-2">
|
|
833
|
+
<CheckCircle className="h-4 w-4" />
|
|
834
|
+
<AlertTitle>Welcome!</AlertTitle>
|
|
835
|
+
<AlertDescription>Welcome to the BDPA React Scaffold and Demo. shadcn/ui components are fully installed.</AlertDescription>
|
|
836
|
+
</Alert>
|
|
837
|
+
</TabsContent>
|
|
838
|
+
<TabsContent value="components">
|
|
839
|
+
<Alert className="mt-2" variant="default">
|
|
840
|
+
<Info className="h-4 w-4" />
|
|
841
|
+
<AlertTitle>Components</AlertTitle>
|
|
842
|
+
<AlertDescription>Buttons, Cards, Inputs, Tables, Badges, Selects, and more — all from shadcn/ui.</AlertDescription>
|
|
843
|
+
</Alert>
|
|
844
|
+
</TabsContent>
|
|
845
|
+
<TabsContent value="auth">
|
|
846
|
+
<p className="mt-2 text-sm">Login + Registration pages included.</p>
|
|
847
|
+
</TabsContent>
|
|
788
848
|
</Tabs>
|
|
789
849
|
|
|
790
850
|
<div className="grid md:grid-cols-2 gap-6">
|
|
791
851
|
|
|
792
|
-
{/* Form
|
|
852
|
+
{/* Sample Form */}
|
|
793
853
|
<Card>
|
|
794
854
|
<CardHeader><CardTitle>Sample Form</CardTitle></CardHeader>
|
|
795
855
|
<CardContent className="space-y-4">
|
|
@@ -812,7 +872,7 @@ function Dashboard() {
|
|
|
812
872
|
</CardContent>
|
|
813
873
|
</Card>
|
|
814
874
|
|
|
815
|
-
{/* Table
|
|
875
|
+
{/* Enrollment Table */}
|
|
816
876
|
<Card>
|
|
817
877
|
<CardHeader><CardTitle>Enrollment Overview</CardTitle></CardHeader>
|
|
818
878
|
<CardContent>
|
|
@@ -842,10 +902,85 @@ function Dashboard() {
|
|
|
842
902
|
<Card>
|
|
843
903
|
<CardHeader><CardTitle>Button Variants</CardTitle></CardHeader>
|
|
844
904
|
<CardContent className="flex flex-wrap gap-3">
|
|
845
|
-
<
|
|
905
|
+
<TooltipProvider>
|
|
906
|
+
<Tooltip>
|
|
907
|
+
<TooltipTrigger asChild><Button>Primary</Button></TooltipTrigger>
|
|
908
|
+
<TooltipContent>Primary action</TooltipContent>
|
|
909
|
+
</Tooltip>
|
|
910
|
+
</TooltipProvider>
|
|
846
911
|
<Button variant="secondary">Secondary</Button>
|
|
847
912
|
<Button variant="destructive">Danger</Button>
|
|
848
913
|
<Button variant="outline">Outline</Button>
|
|
914
|
+
<Button variant="ghost">Ghost</Button>
|
|
915
|
+
<Button variant="link">Link</Button>
|
|
916
|
+
</CardContent>
|
|
917
|
+
</Card>
|
|
918
|
+
|
|
919
|
+
<Separator />
|
|
920
|
+
|
|
921
|
+
{/* Badges */}
|
|
922
|
+
<Card>
|
|
923
|
+
<CardHeader><CardTitle>Badges</CardTitle></CardHeader>
|
|
924
|
+
<CardContent className="flex flex-wrap gap-2">
|
|
925
|
+
<Badge>Default</Badge>
|
|
926
|
+
<Badge variant="secondary">Secondary</Badge>
|
|
927
|
+
<Badge variant="destructive">Destructive</Badge>
|
|
928
|
+
<Badge variant="outline">Outline</Badge>
|
|
929
|
+
</CardContent>
|
|
930
|
+
</Card>
|
|
931
|
+
|
|
932
|
+
{/* Select / Checkbox / Switch / Textarea / Progress */}
|
|
933
|
+
<div className="grid md:grid-cols-2 gap-6">
|
|
934
|
+
<Card>
|
|
935
|
+
<CardHeader><CardTitle>Select & Switch</CardTitle></CardHeader>
|
|
936
|
+
<CardContent className="space-y-4">
|
|
937
|
+
<div className="space-y-1">
|
|
938
|
+
<Label>Course Level</Label>
|
|
939
|
+
<Select>
|
|
940
|
+
<SelectTrigger>
|
|
941
|
+
<SelectValue placeholder="Select level" />
|
|
942
|
+
</SelectTrigger>
|
|
943
|
+
<SelectContent>
|
|
944
|
+
<SelectItem value="beginner">Beginner</SelectItem>
|
|
945
|
+
<SelectItem value="intermediate">Intermediate</SelectItem>
|
|
946
|
+
<SelectItem value="advanced">Advanced</SelectItem>
|
|
947
|
+
</SelectContent>
|
|
948
|
+
</Select>
|
|
949
|
+
</div>
|
|
950
|
+
<div className="flex items-center gap-2">
|
|
951
|
+
<Checkbox id="terms" />
|
|
952
|
+
<Label htmlFor="terms">Accept terms & conditions</Label>
|
|
953
|
+
</div>
|
|
954
|
+
<div className="flex items-center gap-2">
|
|
955
|
+
<Switch id="notifications" />
|
|
956
|
+
<Label htmlFor="notifications">Enable notifications</Label>
|
|
957
|
+
</div>
|
|
958
|
+
</CardContent>
|
|
959
|
+
</Card>
|
|
960
|
+
|
|
961
|
+
<Card>
|
|
962
|
+
<CardHeader><CardTitle>Textarea & Progress</CardTitle></CardHeader>
|
|
963
|
+
<CardContent className="space-y-4">
|
|
964
|
+
<div className="space-y-1">
|
|
965
|
+
<Label htmlFor="bio">Bio</Label>
|
|
966
|
+
<Textarea id="bio" placeholder="Tell us about yourself..." />
|
|
967
|
+
</div>
|
|
968
|
+
<div className="space-y-1">
|
|
969
|
+
<Label>Profile Completion</Label>
|
|
970
|
+
<Progress value={65} className="h-2" />
|
|
971
|
+
<p className="text-xs text-muted-foreground">65% complete</p>
|
|
972
|
+
</div>
|
|
973
|
+
</CardContent>
|
|
974
|
+
</Card>
|
|
975
|
+
</div>
|
|
976
|
+
|
|
977
|
+
{/* Skeleton */}
|
|
978
|
+
<Card>
|
|
979
|
+
<CardHeader><CardTitle>Skeleton Loading State</CardTitle></CardHeader>
|
|
980
|
+
<CardContent className="space-y-2">
|
|
981
|
+
<Skeleton className="h-4 w-full" />
|
|
982
|
+
<Skeleton className="h-4 w-3/4" />
|
|
983
|
+
<Skeleton className="h-4 w-1/2" />
|
|
849
984
|
</CardContent>
|
|
850
985
|
</Card>
|
|
851
986
|
|
|
@@ -874,9 +1009,7 @@ function Dashboard() {
|
|
|
874
1009
|
{/* Dialog + Toast */}
|
|
875
1010
|
<div className="flex gap-4">
|
|
876
1011
|
<Button onClick={() => setModalOpen(true)}>Open Dialog</Button>
|
|
877
|
-
<Button onClick={() => toast.success("This is a toast!")}>
|
|
878
|
-
Show Toast
|
|
879
|
-
</Button>
|
|
1012
|
+
<Button onClick={() => toast.success("This is a toast!")}>Show Toast</Button>
|
|
880
1013
|
</div>
|
|
881
1014
|
|
|
882
1015
|
<Dialog open={modalOpen} onOpenChange={setModalOpen}>
|
|
@@ -894,38 +1027,6 @@ function Dashboard() {
|
|
|
894
1027
|
</div>
|
|
895
1028
|
);
|
|
896
1029
|
}
|
|
897
|
-
|
|
898
|
-
export default function App() {
|
|
899
|
-
const navigate = useNavigate();
|
|
900
|
-
|
|
901
|
-
return (
|
|
902
|
-
<Routes>
|
|
903
|
-
<Route path="/" element={<Dashboard />} />
|
|
904
|
-
<Route
|
|
905
|
-
path="/login"
|
|
906
|
-
element={
|
|
907
|
-
<Login
|
|
908
|
-
onSubmit={() => {
|
|
909
|
-
alert("Login submitted!");
|
|
910
|
-
navigate("/");
|
|
911
|
-
}}
|
|
912
|
-
/>
|
|
913
|
-
}
|
|
914
|
-
/>
|
|
915
|
-
<Route
|
|
916
|
-
path="/register"
|
|
917
|
-
element={
|
|
918
|
-
<Register
|
|
919
|
-
onSubmit={() => {
|
|
920
|
-
alert("Registration submitted!");
|
|
921
|
-
navigate("/");
|
|
922
|
-
}}
|
|
923
|
-
/>
|
|
924
|
-
}
|
|
925
|
-
/>
|
|
926
|
-
</Routes>
|
|
927
|
-
);
|
|
928
|
-
}
|
|
929
1030
|
`);
|
|
930
1031
|
|
|
931
1032
|
// Note: All UI components (Card, Input, Form, Table, Navbar, Tabs, Toast, etc.)
|
|
@@ -937,32 +1038,83 @@ export default function App() {
|
|
|
937
1038
|
// -------------------------------
|
|
938
1039
|
|
|
939
1040
|
write("src/pages/auth/Login.jsx", `
|
|
1041
|
+
import { useState } from "react";
|
|
940
1042
|
import { Button } from "@/components/ui/button";
|
|
941
1043
|
import { Input } from "@/components/ui/input";
|
|
942
1044
|
import { Label } from "@/components/ui/label";
|
|
943
1045
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
1046
|
+
import { Alert, AlertDescription } from "@/components/ui/alert";
|
|
1047
|
+
import { Checkbox } from "@/components/ui/checkbox";
|
|
1048
|
+
import { Separator } from "@/components/ui/separator";
|
|
1049
|
+
import { Badge } from "@/components/ui/badge";
|
|
944
1050
|
|
|
945
1051
|
export default function Login({ onSubmit }) {
|
|
1052
|
+
const [email, setEmail] = useState("");
|
|
1053
|
+
const [password, setPassword] = useState("");
|
|
1054
|
+
const [error, setError] = useState("");
|
|
1055
|
+
const [rememberMe, setRememberMe] = useState(false);
|
|
1056
|
+
|
|
1057
|
+
const handleSubmit = (e) => {
|
|
1058
|
+
e.preventDefault();
|
|
1059
|
+
if (!email || !password) {
|
|
1060
|
+
setError("Email and password are required.");
|
|
1061
|
+
return;
|
|
1062
|
+
}
|
|
1063
|
+
setError("");
|
|
1064
|
+
if (onSubmit) onSubmit({ email, password, rememberMe });
|
|
1065
|
+
};
|
|
1066
|
+
|
|
946
1067
|
return (
|
|
947
1068
|
<div className="flex items-center justify-center min-h-screen bg-gray-100">
|
|
948
1069
|
<Card className="w-full max-w-sm">
|
|
949
1070
|
<CardHeader>
|
|
950
|
-
<
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
<div className="space-y-1">
|
|
954
|
-
<Label htmlFor="email">Email</Label>
|
|
955
|
-
<Input id="email" type="email" placeholder="you@example.com" />
|
|
956
|
-
</div>
|
|
957
|
-
<div className="space-y-1">
|
|
958
|
-
<Label htmlFor="password">Password</Label>
|
|
959
|
-
<Input id="password" type="password" placeholder="••••••••" />
|
|
1071
|
+
<div className="flex items-center justify-between">
|
|
1072
|
+
<CardTitle>Sign In</CardTitle>
|
|
1073
|
+
<Badge variant="outline">shadcn/ui</Badge>
|
|
960
1074
|
</div>
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
1075
|
+
</CardHeader>
|
|
1076
|
+
<CardContent>
|
|
1077
|
+
<form onSubmit={handleSubmit} className="space-y-4">
|
|
1078
|
+
{error && (
|
|
1079
|
+
<Alert variant="destructive">
|
|
1080
|
+
<AlertDescription>{error}</AlertDescription>
|
|
1081
|
+
</Alert>
|
|
1082
|
+
)}
|
|
1083
|
+
<div className="space-y-1">
|
|
1084
|
+
<Label htmlFor="email">Email</Label>
|
|
1085
|
+
<Input
|
|
1086
|
+
id="email"
|
|
1087
|
+
type="email"
|
|
1088
|
+
placeholder="you@example.com"
|
|
1089
|
+
value={email}
|
|
1090
|
+
onChange={(e) => setEmail(e.target.value)}
|
|
1091
|
+
/>
|
|
1092
|
+
</div>
|
|
1093
|
+
<div className="space-y-1">
|
|
1094
|
+
<Label htmlFor="password">Password</Label>
|
|
1095
|
+
<Input
|
|
1096
|
+
id="password"
|
|
1097
|
+
type="password"
|
|
1098
|
+
placeholder="Password"
|
|
1099
|
+
value={password}
|
|
1100
|
+
onChange={(e) => setPassword(e.target.value)}
|
|
1101
|
+
/>
|
|
1102
|
+
</div>
|
|
1103
|
+
<div className="flex items-center gap-2">
|
|
1104
|
+
<Checkbox
|
|
1105
|
+
id="remember"
|
|
1106
|
+
checked={rememberMe}
|
|
1107
|
+
onCheckedChange={setRememberMe}
|
|
1108
|
+
/>
|
|
1109
|
+
<Label htmlFor="remember" className="text-sm">Remember me</Label>
|
|
1110
|
+
</div>
|
|
1111
|
+
<Button type="submit" className="w-full">
|
|
1112
|
+
Sign In
|
|
1113
|
+
</Button>
|
|
1114
|
+
</form>
|
|
1115
|
+
<Separator className="my-4" />
|
|
964
1116
|
<p className="text-sm text-center text-gray-600">
|
|
965
|
-
Don
|
|
1117
|
+
Don't have an account?{" "}
|
|
966
1118
|
<a href="/register" className="text-blue-600 hover:underline">
|
|
967
1119
|
Create one
|
|
968
1120
|
</a>
|
|
@@ -973,35 +1125,108 @@ export default function Login({ onSubmit }) {
|
|
|
973
1125
|
);
|
|
974
1126
|
}`);
|
|
975
1127
|
|
|
1128
|
+
|
|
976
1129
|
write("src/pages/auth/Register.jsx", `
|
|
1130
|
+
import { useState } from "react";
|
|
977
1131
|
import { Button } from "@/components/ui/button";
|
|
978
1132
|
import { Input } from "@/components/ui/input";
|
|
979
1133
|
import { Label } from "@/components/ui/label";
|
|
980
1134
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
1135
|
+
import { Alert, AlertDescription } from "@/components/ui/alert";
|
|
1136
|
+
import { Progress } from "@/components/ui/progress";
|
|
1137
|
+
import { Separator } from "@/components/ui/separator";
|
|
1138
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
|
1139
|
+
import { Badge } from "@/components/ui/badge";
|
|
1140
|
+
|
|
1141
|
+
function calcStrength(pw) {
|
|
1142
|
+
let s = 0;
|
|
1143
|
+
if (pw.length >= 8) s++;
|
|
1144
|
+
if (pw.length >= 12) s++;
|
|
1145
|
+
if (/[a-z]/.test(pw) && /[A-Z]/.test(pw)) s++;
|
|
1146
|
+
if (/\\d/.test(pw)) s++;
|
|
1147
|
+
if (/[^A-Za-z0-9]/.test(pw)) s++;
|
|
1148
|
+
return Math.min(s, 4);
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
const strengthLabels = ["Weak", "Fair", "Good", "Strong", "Very Strong"];
|
|
1152
|
+
const strengthColors = ["bg-red-500", "bg-orange-400", "bg-yellow-400", "bg-green-400", "bg-green-600"];
|
|
981
1153
|
|
|
982
1154
|
export default function Register({ onSubmit }) {
|
|
1155
|
+
const [name, setName] = useState("");
|
|
1156
|
+
const [email, setEmail] = useState("");
|
|
1157
|
+
const [password, setPassword] = useState("");
|
|
1158
|
+
const [role, setRole] = useState("");
|
|
1159
|
+
const [error, setError] = useState("");
|
|
1160
|
+
const strength = calcStrength(password);
|
|
1161
|
+
|
|
1162
|
+
const handleSubmit = (e) => {
|
|
1163
|
+
e.preventDefault();
|
|
1164
|
+
if (!name || !email || !password) {
|
|
1165
|
+
setError("All fields are required.");
|
|
1166
|
+
return;
|
|
1167
|
+
}
|
|
1168
|
+
if (password.length < 8) {
|
|
1169
|
+
setError("Password must be at least 8 characters.");
|
|
1170
|
+
return;
|
|
1171
|
+
}
|
|
1172
|
+
setError("");
|
|
1173
|
+
if (onSubmit) onSubmit({ name, email, password, role });
|
|
1174
|
+
};
|
|
1175
|
+
|
|
983
1176
|
return (
|
|
984
1177
|
<div className="flex items-center justify-center min-h-screen bg-gray-100">
|
|
985
1178
|
<Card className="w-full max-w-sm">
|
|
986
1179
|
<CardHeader>
|
|
987
|
-
<
|
|
1180
|
+
<div className="flex items-center justify-between">
|
|
1181
|
+
<CardTitle>Create Account</CardTitle>
|
|
1182
|
+
<Badge variant="outline">shadcn/ui</Badge>
|
|
1183
|
+
</div>
|
|
988
1184
|
</CardHeader>
|
|
989
|
-
<CardContent
|
|
1185
|
+
<CardContent>
|
|
1186
|
+
<form onSubmit={handleSubmit} className="space-y-4">
|
|
1187
|
+
{error && (
|
|
1188
|
+
<Alert variant="destructive">
|
|
1189
|
+
<AlertDescription>{error}</AlertDescription>
|
|
1190
|
+
</Alert>
|
|
1191
|
+
)}
|
|
990
1192
|
<div className="space-y-1">
|
|
991
1193
|
<Label htmlFor="name">Full Name</Label>
|
|
992
|
-
<Input id="name" placeholder="Your Name" />
|
|
1194
|
+
<Input id="name" placeholder="Your Name" value={name} onChange={(e) => setName(e.target.value)} />
|
|
993
1195
|
</div>
|
|
994
1196
|
<div className="space-y-1">
|
|
995
1197
|
<Label htmlFor="email">Email</Label>
|
|
996
|
-
<Input id="email" type="email" placeholder="you@example.com" />
|
|
1198
|
+
<Input id="email" type="email" placeholder="you@example.com" value={email} onChange={(e) => setEmail(e.target.value)} />
|
|
1199
|
+
</div>
|
|
1200
|
+
<div className="space-y-1">
|
|
1201
|
+
<Label htmlFor="r-role">Role</Label>
|
|
1202
|
+
<Select onValueChange={setRole}>
|
|
1203
|
+
<SelectTrigger id="r-role">
|
|
1204
|
+
<SelectValue placeholder="Select your role" />
|
|
1205
|
+
</SelectTrigger>
|
|
1206
|
+
<SelectContent>
|
|
1207
|
+
<SelectItem value="student">Student</SelectItem>
|
|
1208
|
+
<SelectItem value="mentor">Mentor</SelectItem>
|
|
1209
|
+
<SelectItem value="admin">Admin</SelectItem>
|
|
1210
|
+
</SelectContent>
|
|
1211
|
+
</Select>
|
|
997
1212
|
</div>
|
|
998
1213
|
<div className="space-y-1">
|
|
999
1214
|
<Label htmlFor="password">Password</Label>
|
|
1000
|
-
<Input id="password" type="password" placeholder="••••••••" />
|
|
1215
|
+
<Input id="password" type="password" placeholder="••••••••" value={password} onChange={(e) => setPassword(e.target.value)} />
|
|
1001
1216
|
</div>
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1217
|
+
{password && (
|
|
1218
|
+
<div className="space-y-1">
|
|
1219
|
+
<Progress value={(strength / 4) * 100} className="h-2" />
|
|
1220
|
+
<p className="text-xs text-muted-foreground">
|
|
1221
|
+
Strength: <span className="font-medium">{strengthLabels[strength]}</span>
|
|
1222
|
+
</p>
|
|
1223
|
+
</div>
|
|
1224
|
+
)}
|
|
1225
|
+
<Button type="submit" className="w-full">
|
|
1226
|
+
Register
|
|
1227
|
+
</Button>
|
|
1228
|
+
</form>
|
|
1229
|
+
<Separator className="my-4" />
|
|
1005
1230
|
<p className="text-sm text-center text-gray-600">
|
|
1006
1231
|
Already have an account?{" "}
|
|
1007
1232
|
<a href="/login" className="text-blue-600 hover:underline">
|
|
@@ -1015,6 +1240,304 @@ export default function Register({ onSubmit }) {
|
|
|
1015
1240
|
}
|
|
1016
1241
|
`);
|
|
1017
1242
|
|
|
1243
|
+
// -------------------------------
|
|
1244
|
+
// ComponentTest page — comprehensive shadcn test
|
|
1245
|
+
// -------------------------------
|
|
1246
|
+
|
|
1247
|
+
write("src/pages/ComponentTest.jsx", `
|
|
1248
|
+
import { useState } from "react";
|
|
1249
|
+
import { Button } from "@/components/ui/button";
|
|
1250
|
+
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
1251
|
+
import { Input } from "@/components/ui/input";
|
|
1252
|
+
import { Label } from "@/components/ui/label";
|
|
1253
|
+
import { Badge } from "@/components/ui/badge";
|
|
1254
|
+
import { Alert, AlertTitle, AlertDescription } from "@/components/ui/alert";
|
|
1255
|
+
import { Checkbox } from "@/components/ui/checkbox";
|
|
1256
|
+
import { Switch } from "@/components/ui/switch";
|
|
1257
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
|
1258
|
+
import { Progress } from "@/components/ui/progress";
|
|
1259
|
+
import { Separator } from "@/components/ui/separator";
|
|
1260
|
+
import { Skeleton } from "@/components/ui/skeleton";
|
|
1261
|
+
import { Textarea } from "@/components/ui/textarea";
|
|
1262
|
+
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
|
|
1263
|
+
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
|
1264
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "@/components/ui/dialog";
|
|
1265
|
+
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
|
1266
|
+
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet";
|
|
1267
|
+
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
|
1268
|
+
import { toast } from "sonner";
|
|
1269
|
+
import { CheckCircle, Info, AlertCircle } from "lucide-react";
|
|
1270
|
+
|
|
1271
|
+
const sampleRows = [
|
|
1272
|
+
{ id: 1, name: "Ada Lovelace", role: "Student", status: "Active" },
|
|
1273
|
+
{ id: 2, name: "Grace Hopper", role: "Mentor", status: "Active" },
|
|
1274
|
+
{ id: 3, name: "Alan Turing", role: "Admin", status: "Inactive" },
|
|
1275
|
+
];
|
|
1276
|
+
|
|
1277
|
+
export default function ComponentTest() {
|
|
1278
|
+
const [dialogOpen, setDialogOpen] = useState(false);
|
|
1279
|
+
const [progress, setProgress] = useState(40);
|
|
1280
|
+
const [switchOn, setSwitchOn] = useState(false);
|
|
1281
|
+
const [checked, setChecked] = useState(false);
|
|
1282
|
+
|
|
1283
|
+
return (
|
|
1284
|
+
<div className="p-6 max-w-4xl mx-auto space-y-8">
|
|
1285
|
+
<div className="flex items-center justify-between">
|
|
1286
|
+
<h1 className="text-3xl font-bold">shadcn/ui Component Test</h1>
|
|
1287
|
+
<Badge>All Components</Badge>
|
|
1288
|
+
</div>
|
|
1289
|
+
|
|
1290
|
+
<Separator />
|
|
1291
|
+
|
|
1292
|
+
{/* Alerts */}
|
|
1293
|
+
<Card>
|
|
1294
|
+
<CardHeader><CardTitle>Alert</CardTitle></CardHeader>
|
|
1295
|
+
<CardContent className="space-y-3">
|
|
1296
|
+
<Alert>
|
|
1297
|
+
<Info className="h-4 w-4" />
|
|
1298
|
+
<AlertTitle>Info</AlertTitle>
|
|
1299
|
+
<AlertDescription>This is a default informational alert.</AlertDescription>
|
|
1300
|
+
</Alert>
|
|
1301
|
+
<Alert variant="destructive">
|
|
1302
|
+
<AlertCircle className="h-4 w-4" />
|
|
1303
|
+
<AlertTitle>Error</AlertTitle>
|
|
1304
|
+
<AlertDescription>Something went wrong. Please try again.</AlertDescription>
|
|
1305
|
+
</Alert>
|
|
1306
|
+
</CardContent>
|
|
1307
|
+
</Card>
|
|
1308
|
+
|
|
1309
|
+
{/* Avatar */}
|
|
1310
|
+
<Card>
|
|
1311
|
+
<CardHeader><CardTitle>Avatar</CardTitle></CardHeader>
|
|
1312
|
+
<CardContent className="flex gap-4">
|
|
1313
|
+
<Avatar>
|
|
1314
|
+
<AvatarImage src="https://github.com/shadcn.png" alt="shadcn" />
|
|
1315
|
+
<AvatarFallback>CN</AvatarFallback>
|
|
1316
|
+
</Avatar>
|
|
1317
|
+
<Avatar>
|
|
1318
|
+
<AvatarFallback>AL</AvatarFallback>
|
|
1319
|
+
</Avatar>
|
|
1320
|
+
<Avatar>
|
|
1321
|
+
<AvatarFallback>GH</AvatarFallback>
|
|
1322
|
+
</Avatar>
|
|
1323
|
+
</CardContent>
|
|
1324
|
+
</Card>
|
|
1325
|
+
|
|
1326
|
+
{/* Badge */}
|
|
1327
|
+
<Card>
|
|
1328
|
+
<CardHeader><CardTitle>Badge</CardTitle></CardHeader>
|
|
1329
|
+
<CardContent className="flex flex-wrap gap-2">
|
|
1330
|
+
<Badge>Default</Badge>
|
|
1331
|
+
<Badge variant="secondary">Secondary</Badge>
|
|
1332
|
+
<Badge variant="destructive">Destructive</Badge>
|
|
1333
|
+
<Badge variant="outline">Outline</Badge>
|
|
1334
|
+
</CardContent>
|
|
1335
|
+
</Card>
|
|
1336
|
+
|
|
1337
|
+
{/* Button */}
|
|
1338
|
+
<Card>
|
|
1339
|
+
<CardHeader><CardTitle>Button</CardTitle></CardHeader>
|
|
1340
|
+
<CardContent className="flex flex-wrap gap-2">
|
|
1341
|
+
<Button onClick={() => toast.success("Primary clicked!")}>Primary</Button>
|
|
1342
|
+
<Button variant="secondary">Secondary</Button>
|
|
1343
|
+
<Button variant="destructive">Destructive</Button>
|
|
1344
|
+
<Button variant="outline">Outline</Button>
|
|
1345
|
+
<Button variant="ghost">Ghost</Button>
|
|
1346
|
+
<Button variant="link">Link</Button>
|
|
1347
|
+
<Button disabled>Disabled</Button>
|
|
1348
|
+
<Button size="sm">Small</Button>
|
|
1349
|
+
<Button size="lg">Large</Button>
|
|
1350
|
+
</CardContent>
|
|
1351
|
+
</Card>
|
|
1352
|
+
|
|
1353
|
+
{/* Checkbox + Switch */}
|
|
1354
|
+
<Card>
|
|
1355
|
+
<CardHeader><CardTitle>Checkbox & Switch</CardTitle></CardHeader>
|
|
1356
|
+
<CardContent className="space-y-3">
|
|
1357
|
+
<div className="flex items-center gap-2">
|
|
1358
|
+
<Checkbox id="test-cb" checked={checked} onCheckedChange={setChecked} />
|
|
1359
|
+
<Label htmlFor="test-cb">Accept terms: {checked ? "Yes" : "No"}</Label>
|
|
1360
|
+
</div>
|
|
1361
|
+
<div className="flex items-center gap-2">
|
|
1362
|
+
<Switch id="test-sw" checked={switchOn} onCheckedChange={setSwitchOn} />
|
|
1363
|
+
<Label htmlFor="test-sw">Notifications: {switchOn ? "On" : "Off"}</Label>
|
|
1364
|
+
</div>
|
|
1365
|
+
</CardContent>
|
|
1366
|
+
</Card>
|
|
1367
|
+
|
|
1368
|
+
{/* Input + Textarea + Select + Label */}
|
|
1369
|
+
<Card>
|
|
1370
|
+
<CardHeader><CardTitle>Input / Textarea / Select</CardTitle></CardHeader>
|
|
1371
|
+
<CardContent className="space-y-4">
|
|
1372
|
+
<div className="space-y-1">
|
|
1373
|
+
<Label htmlFor="ct-name">Name</Label>
|
|
1374
|
+
<Input id="ct-name" placeholder="Enter your name" />
|
|
1375
|
+
</div>
|
|
1376
|
+
<div className="space-y-1">
|
|
1377
|
+
<Label htmlFor="ct-bio">Bio</Label>
|
|
1378
|
+
<Textarea id="ct-bio" placeholder="Tell us about yourself" />
|
|
1379
|
+
</div>
|
|
1380
|
+
<div className="space-y-1">
|
|
1381
|
+
<Label>Role</Label>
|
|
1382
|
+
<Select>
|
|
1383
|
+
<SelectTrigger>
|
|
1384
|
+
<SelectValue placeholder="Choose a role" />
|
|
1385
|
+
</SelectTrigger>
|
|
1386
|
+
<SelectContent>
|
|
1387
|
+
<SelectItem value="student">Student</SelectItem>
|
|
1388
|
+
<SelectItem value="mentor">Mentor</SelectItem>
|
|
1389
|
+
<SelectItem value="admin">Admin</SelectItem>
|
|
1390
|
+
</SelectContent>
|
|
1391
|
+
</Select>
|
|
1392
|
+
</div>
|
|
1393
|
+
</CardContent>
|
|
1394
|
+
</Card>
|
|
1395
|
+
|
|
1396
|
+
{/* Progress */}
|
|
1397
|
+
<Card>
|
|
1398
|
+
<CardHeader><CardTitle>Progress</CardTitle></CardHeader>
|
|
1399
|
+
<CardContent className="space-y-3">
|
|
1400
|
+
<Progress value={progress} />
|
|
1401
|
+
<div className="flex gap-2">
|
|
1402
|
+
<Button size="sm" onClick={() => setProgress(Math.max(0, progress - 10))}>-10</Button>
|
|
1403
|
+
<Button size="sm" onClick={() => setProgress(Math.min(100, progress + 10))}>+10</Button>
|
|
1404
|
+
<span className="text-sm self-center">{progress}%</span>
|
|
1405
|
+
</div>
|
|
1406
|
+
</CardContent>
|
|
1407
|
+
</Card>
|
|
1408
|
+
|
|
1409
|
+
{/* Skeleton */}
|
|
1410
|
+
<Card>
|
|
1411
|
+
<CardHeader><CardTitle>Skeleton</CardTitle></CardHeader>
|
|
1412
|
+
<CardContent className="space-y-2">
|
|
1413
|
+
<div className="flex items-center gap-3">
|
|
1414
|
+
<Skeleton className="h-10 w-10 rounded-full" />
|
|
1415
|
+
<div className="space-y-1 flex-1">
|
|
1416
|
+
<Skeleton className="h-4 w-full" />
|
|
1417
|
+
<Skeleton className="h-4 w-2/3" />
|
|
1418
|
+
</div>
|
|
1419
|
+
</div>
|
|
1420
|
+
</CardContent>
|
|
1421
|
+
</Card>
|
|
1422
|
+
|
|
1423
|
+
{/* Tabs */}
|
|
1424
|
+
<Card>
|
|
1425
|
+
<CardHeader><CardTitle>Tabs</CardTitle></CardHeader>
|
|
1426
|
+
<CardContent>
|
|
1427
|
+
<Tabs defaultValue="tab1">
|
|
1428
|
+
<TabsList>
|
|
1429
|
+
<TabsTrigger value="tab1">Tab One</TabsTrigger>
|
|
1430
|
+
<TabsTrigger value="tab2">Tab Two</TabsTrigger>
|
|
1431
|
+
<TabsTrigger value="tab3">Tab Three</TabsTrigger>
|
|
1432
|
+
</TabsList>
|
|
1433
|
+
<TabsContent value="tab1"><p className="mt-2 text-sm">Content for Tab One.</p></TabsContent>
|
|
1434
|
+
<TabsContent value="tab2"><p className="mt-2 text-sm">Content for Tab Two.</p></TabsContent>
|
|
1435
|
+
<TabsContent value="tab3"><p className="mt-2 text-sm">Content for Tab Three.</p></TabsContent>
|
|
1436
|
+
</Tabs>
|
|
1437
|
+
</CardContent>
|
|
1438
|
+
</Card>
|
|
1439
|
+
|
|
1440
|
+
{/* Table */}
|
|
1441
|
+
<Card>
|
|
1442
|
+
<CardHeader><CardTitle>Table</CardTitle></CardHeader>
|
|
1443
|
+
<CardContent>
|
|
1444
|
+
<Table>
|
|
1445
|
+
<TableHeader>
|
|
1446
|
+
<TableRow>
|
|
1447
|
+
<TableHead>#</TableHead>
|
|
1448
|
+
<TableHead>Name</TableHead>
|
|
1449
|
+
<TableHead>Role</TableHead>
|
|
1450
|
+
<TableHead>Status</TableHead>
|
|
1451
|
+
</TableRow>
|
|
1452
|
+
</TableHeader>
|
|
1453
|
+
<TableBody>
|
|
1454
|
+
{sampleRows.map((r) => (
|
|
1455
|
+
<TableRow key={r.id}>
|
|
1456
|
+
<TableCell>{r.id}</TableCell>
|
|
1457
|
+
<TableCell>{r.name}</TableCell>
|
|
1458
|
+
<TableCell>{r.role}</TableCell>
|
|
1459
|
+
<TableCell>
|
|
1460
|
+
<Badge variant={r.status === "Active" ? "default" : "secondary"}>{r.status}</Badge>
|
|
1461
|
+
</TableCell>
|
|
1462
|
+
</TableRow>
|
|
1463
|
+
))}
|
|
1464
|
+
</TableBody>
|
|
1465
|
+
</Table>
|
|
1466
|
+
</CardContent>
|
|
1467
|
+
</Card>
|
|
1468
|
+
|
|
1469
|
+
{/* Dialog */}
|
|
1470
|
+
<Card>
|
|
1471
|
+
<CardHeader><CardTitle>Dialog</CardTitle></CardHeader>
|
|
1472
|
+
<CardContent>
|
|
1473
|
+
<Button onClick={() => setDialogOpen(true)}>Open Dialog</Button>
|
|
1474
|
+
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
|
|
1475
|
+
<DialogContent>
|
|
1476
|
+
<DialogHeader>
|
|
1477
|
+
<DialogTitle>shadcn Dialog</DialogTitle>
|
|
1478
|
+
<DialogDescription>This is a modal dialog from shadcn/ui.</DialogDescription>
|
|
1479
|
+
</DialogHeader>
|
|
1480
|
+
<p className="text-sm">Dialog content goes here.</p>
|
|
1481
|
+
<Button className="mt-4" onClick={() => setDialogOpen(false)}>Close</Button>
|
|
1482
|
+
</DialogContent>
|
|
1483
|
+
</Dialog>
|
|
1484
|
+
</CardContent>
|
|
1485
|
+
</Card>
|
|
1486
|
+
|
|
1487
|
+
{/* Sheet */}
|
|
1488
|
+
<Card>
|
|
1489
|
+
<CardHeader><CardTitle>Sheet</CardTitle></CardHeader>
|
|
1490
|
+
<CardContent>
|
|
1491
|
+
<Sheet>
|
|
1492
|
+
<SheetTrigger asChild>
|
|
1493
|
+
<Button variant="outline">Open Sheet</Button>
|
|
1494
|
+
</SheetTrigger>
|
|
1495
|
+
<SheetContent>
|
|
1496
|
+
<SheetHeader>
|
|
1497
|
+
<SheetTitle>Side Sheet</SheetTitle>
|
|
1498
|
+
</SheetHeader>
|
|
1499
|
+
<p className="mt-4 text-sm">Sheet content from shadcn/ui.</p>
|
|
1500
|
+
</SheetContent>
|
|
1501
|
+
</Sheet>
|
|
1502
|
+
</CardContent>
|
|
1503
|
+
</Card>
|
|
1504
|
+
|
|
1505
|
+
{/* Tooltip */}
|
|
1506
|
+
<Card>
|
|
1507
|
+
<CardHeader><CardTitle>Tooltip</CardTitle></CardHeader>
|
|
1508
|
+
<CardContent>
|
|
1509
|
+
<TooltipProvider>
|
|
1510
|
+
<Tooltip>
|
|
1511
|
+
<TooltipTrigger asChild>
|
|
1512
|
+
<Button variant="outline">Hover me</Button>
|
|
1513
|
+
</TooltipTrigger>
|
|
1514
|
+
<TooltipContent>
|
|
1515
|
+
<p>This is a shadcn Tooltip</p>
|
|
1516
|
+
</TooltipContent>
|
|
1517
|
+
</Tooltip>
|
|
1518
|
+
</TooltipProvider>
|
|
1519
|
+
</CardContent>
|
|
1520
|
+
</Card>
|
|
1521
|
+
|
|
1522
|
+
{/* Toast */}
|
|
1523
|
+
<Card>
|
|
1524
|
+
<CardHeader><CardTitle>Toast (Sonner)</CardTitle></CardHeader>
|
|
1525
|
+
<CardContent className="flex flex-wrap gap-2">
|
|
1526
|
+
<Button onClick={() => toast.success("Success toast!")}>Success</Button>
|
|
1527
|
+
<Button variant="destructive" onClick={() => toast.error("Error toast!")}>Error</Button>
|
|
1528
|
+
<Button variant="outline" onClick={() => toast.info("Info toast!")}>Info</Button>
|
|
1529
|
+
<Button variant="secondary" onClick={() => toast.warning("Warning toast!")}>Warning</Button>
|
|
1530
|
+
</CardContent>
|
|
1531
|
+
</Card>
|
|
1532
|
+
|
|
1533
|
+
<div className="flex justify-center pt-4">
|
|
1534
|
+
<a href="/" className="text-sm text-blue-600 hover:underline">← Back to Home</a>
|
|
1535
|
+
</div>
|
|
1536
|
+
</div>
|
|
1537
|
+
);
|
|
1538
|
+
}
|
|
1539
|
+
`);
|
|
1540
|
+
|
|
1018
1541
|
// -------------------------------
|
|
1019
1542
|
// Layout Components
|
|
1020
1543
|
// -------------------------------
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-bdpa-react-scaffold",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Scaffold a React + Tailwind
|
|
3
|
+
"version": "2.0.2",
|
|
4
|
+
"description": "Scaffold a React + Tailwind + shadcn/ui component demo via Vite.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"create-bdpa-react-scaffold": "create-ui-lib.js"
|
|
7
7
|
},
|