Skip to content

Commit 59aac29

Browse files
authored
Merge pull request #3 from iClasser/khalid-twitter1
Khalid twitter component updates
2 parents f8ab844 + 3e1ecb0 commit 59aac29

6 files changed

Lines changed: 1021 additions & 108 deletions

File tree

apps/web/app/page.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { useSearchParams, useRouter } from "next/navigation";
55
import "./page.module.css";
66
import QuizMarkdownEditor from "../components/markdown-editor";
77
import ChatgptEditor from "../components/chatgpt-editor";
8+
import XEditor from "../components/x-editor";
9+
810
import GradientEditor from "../components/gradient-editor";
911
import { CardSizeProvider } from "@repo/ui/context/CardSizeContext";
1012

@@ -20,7 +22,12 @@ const tabs = [
2022
{
2123
key: "gradient",
2224
label: "Gradient Card",
23-
}
25+
},
26+
{
27+
key: "x",
28+
label: "X Card",
29+
},
30+
2431
];
2532

2633
function HomeContent() {
@@ -41,6 +48,7 @@ function HomeContent() {
4148
{currentTab === "markdown" ? <QuizMarkdownEditor /> : null}
4249
{currentTab === "chatgpt" ? <ChatgptEditor /> : null}
4350
{currentTab === "gradient" ? <GradientEditor /> : null}
51+
{currentTab === "x" ? <XEditor /> : null}
4452
</CardSizeProvider>
4553
</MainHomeLayout>
4654
);
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
"use client";
2+
import { Slider } from "../ui/slider";
3+
import { Input } from "../ui/input";
4+
import { Textarea } from "../ui/textarea";
5+
import { cn } from "../../lib/cn";
6+
7+
function SliderBox({
8+
keyName,
9+
value,
10+
label,
11+
min,
12+
max,
13+
unit,
14+
widthWrapper = false,
15+
formatValue = false,
16+
setStateValue,
17+
}: {
18+
keyName: string;
19+
value: number;
20+
label: string;
21+
min: number;
22+
max: number;
23+
unit?: string;
24+
formatValue?: boolean;
25+
widthWrapper?: boolean;
26+
setStateValue: (name: string, value: any) => void;
27+
}) {
28+
const comp = (
29+
<>
30+
<label className="block mb-2">
31+
{label || <span>{keyName}</span>}:{" "}
32+
{formatValue ? (
33+
<span>{new Intl.NumberFormat().format(value)}</span>
34+
) : (
35+
value
36+
)}
37+
{unit && <span className="">{unit}</span>}
38+
</label>
39+
<Slider
40+
min={min}
41+
max={max}
42+
name={keyName}
43+
value={[value]}
44+
onValueChange={(val) => setStateValue(keyName, val)}
45+
className="w-full"
46+
/>
47+
</>
48+
);
49+
50+
if (widthWrapper) {
51+
return <WithWrapper>{comp}</WithWrapper>;
52+
}
53+
return comp;
54+
}
55+
56+
function DrawInput({
57+
keyName,
58+
value,
59+
placeholder,
60+
label,
61+
onChange: setStateValue,
62+
isTextArea = false,
63+
type = "text",
64+
className = "",
65+
}: {
66+
keyName: string;
67+
value: string;
68+
placeholder?: string;
69+
label?: React.ReactNode;
70+
onChange: (name: string, value: any) => void;
71+
isTextArea?: boolean;
72+
type?: string;
73+
className?: string;
74+
}) {
75+
return (
76+
<div className={cn("mb-4", className)}>
77+
<label className="block">{label || <span>{keyName}</span>}:</label>
78+
{isTextArea ? (
79+
<Textarea
80+
value={value}
81+
onChange={(e) => setStateValue(keyName, e.target.value)}
82+
className="w-full px-2 border rounded-md"
83+
placeholder={placeholder}
84+
/>
85+
) : (
86+
<Input
87+
type={type}
88+
value={value}
89+
onChange={(e) => setStateValue(keyName, e.target.value)}
90+
className="w-full px-2 border rounded-md"
91+
placeholder={placeholder}
92+
/>
93+
)}
94+
</div>
95+
);
96+
}
97+
98+
function WithWrapper({ children }: { children: React.ReactNode }) {
99+
return (
100+
<div className="flex flex-col mt-4 border p-2 rounded-md">{children}</div>
101+
);
102+
}
103+
104+
function CheckBox({
105+
keyName,
106+
value,
107+
label,
108+
setStateValue,
109+
widthWrapper = false,
110+
}: {
111+
keyName: string;
112+
value: boolean;
113+
label: string;
114+
widthWrapper?: boolean;
115+
setStateValue: (name: string, value: any) => void;
116+
}) {
117+
const component = (
118+
<label className="flex items-center">
119+
<input
120+
type="checkbox"
121+
checked={value}
122+
name={keyName}
123+
onChange={(e) => setStateValue(keyName, e.target.checked)}
124+
className="mr-2"
125+
/>
126+
{label || <span>{keyName}</span>}
127+
</label>
128+
);
129+
130+
if (widthWrapper) {
131+
return <WithWrapper>{component}</WithWrapper>;
132+
}
133+
return component;
134+
}
135+
136+
export { SliderBox, DrawInput, CheckBox };

apps/web/components/gradient-editor.tsx

Lines changed: 3 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@ import { useContext, useEffect, useState } from "react";
44
import { DownloadButton } from "@repo/web-ui/download-button";
55
import { CardSizeContext } from "@repo/ui/context/CardSizeContext";
66
import SocialMediaController from "@repo/web-ui/SocialMediaController";
7-
import { Slider } from "./ui/slider";
8-
import { Input } from "./ui/input";
9-
import { Textarea } from "./ui/textarea";
10-
import { cn } from "../lib/cn";
7+
118
import { Cog, Delete, Move, Package2, Trash2 } from "lucide-react";
129
import { Tabs, TabsList, TabsTrigger, TabsContent } from "./ui/tabs";
10+
import { SliderBox, DrawInput, CheckBox } from "./common";
1311

1412
const STORAGE_KEY = "gradient-editor-v1";
1513

@@ -472,106 +470,4 @@ export default function GradientEditor() {
472470
<DownloadButton className="show-mobile bg-black shadow-2xl text-white p-4 rounded-md hover:bg-sky-700" />
473471
</div>
474472
);
475-
}
476-
477-
function CheckBox({
478-
keyName,
479-
value,
480-
label,
481-
setStateValue,
482-
}: {
483-
keyName: string;
484-
value: boolean;
485-
label: string;
486-
setStateValue: (name: string, value: any) => void;
487-
}) {
488-
return (
489-
<label className="flex items-center">
490-
<input
491-
type="checkbox"
492-
checked={value}
493-
name={keyName}
494-
onChange={(e) => setStateValue(keyName, e.target.checked)}
495-
className="mr-2"
496-
/>
497-
{label || <span>{keyName}</span>}
498-
</label>
499-
);
500-
}
501-
502-
function SliderBox({
503-
keyName,
504-
value,
505-
label,
506-
min,
507-
max,
508-
unit,
509-
setStateValue,
510-
}: {
511-
keyName: string;
512-
value: number;
513-
label: string;
514-
min: number;
515-
max: number;
516-
unit?: string;
517-
setStateValue: (name: string, value: any) => void;
518-
}) {
519-
return (
520-
<>
521-
<label className="block mb-2">
522-
{label || <span>{keyName}</span>}: {value}
523-
{unit && <span className="">{unit}</span>}
524-
</label>
525-
<Slider
526-
min={min}
527-
max={max}
528-
name={keyName}
529-
value={[value]}
530-
onValueChange={(val) => setStateValue(keyName, val)}
531-
className="w-full"
532-
/>
533-
</>
534-
);
535-
}
536-
537-
function DrawInput({
538-
keyName,
539-
value,
540-
placeholder,
541-
label,
542-
onChange: setStateValue,
543-
isTextArea = false,
544-
type = "text",
545-
className = "",
546-
}: {
547-
keyName: string;
548-
value: string;
549-
placeholder?: string;
550-
label?: React.ReactNode;
551-
onChange: (name: string, value: any) => void;
552-
isTextArea?: boolean;
553-
type?: string;
554-
className?: string;
555-
}) {
556-
return (
557-
<div className={cn("mb-4", className)}>
558-
<label className="block">{label || <span>{keyName}</span>}:</label>
559-
{isTextArea ? (
560-
<Textarea
561-
value={value}
562-
onChange={(e) => setStateValue(keyName, e.target.value)}
563-
className="w-full px-2 border rounded-md"
564-
placeholder={placeholder}
565-
/>
566-
) : (
567-
<Input
568-
type={type}
569-
value={value}
570-
onChange={(e) => setStateValue(keyName, e.target.value)}
571-
className="w-full px-2 border rounded-md"
572-
placeholder={placeholder}
573-
/>
574-
)}
575-
</div>
576-
);
577-
}
473+
}

0 commit comments

Comments
 (0)