mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
feat(organization): add logo support for organizations
This commit is contained in:
@@ -35,14 +35,16 @@ export function AddOrganization({ organizationId }: Props) {
|
||||
: api.organization.create.useMutation();
|
||||
const [open, setOpen] = useState(false);
|
||||
const [name, setName] = useState("");
|
||||
const [logo, setLogo] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
if (organization) {
|
||||
setName(organization.name);
|
||||
setLogo(organization.logo || "");
|
||||
}
|
||||
}, [organization]);
|
||||
const handleSubmit = async () => {
|
||||
await mutateAsync({ name, organizationId: organizationId ?? "" })
|
||||
await mutateAsync({ name, logo, organizationId: organizationId ?? "" })
|
||||
.then(() => {
|
||||
setOpen(false);
|
||||
toast.success(
|
||||
@@ -91,7 +93,7 @@ export function AddOrganization({ organizationId }: Props) {
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
{organizationId
|
||||
? "Update the organization name"
|
||||
? "Update the organization name and logo"
|
||||
: "Create a new organization to manage your projects."}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
@@ -107,6 +109,18 @@ export function AddOrganization({ organizationId }: Props) {
|
||||
className="col-span-3"
|
||||
/>
|
||||
</div>
|
||||
<div className="grid grid-cols-4 items-center gap-4">
|
||||
<Label htmlFor="logo" className="text-right">
|
||||
Logo URL
|
||||
</Label>
|
||||
<Input
|
||||
id="logo"
|
||||
value={logo}
|
||||
onChange={(e) => setLogo(e.target.value)}
|
||||
placeholder="https://example.com/logo.png"
|
||||
className="col-span-3"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button type="submit" onClick={handleSubmit} isLoading={isLoading}>
|
||||
|
||||
@@ -562,6 +562,7 @@ function SidebarLogo() {
|
||||
"transition-all",
|
||||
state === "collapsed" ? "size-4" : "size-5",
|
||||
)}
|
||||
logoUrl={activeOrganization?.logo}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
@@ -607,6 +608,7 @@ function SidebarLogo() {
|
||||
"transition-all",
|
||||
state === "collapsed" ? "size-6" : "size-10",
|
||||
)}
|
||||
logoUrl={org.logo ?? undefined}
|
||||
/>
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
|
||||
@@ -1,8 +1,20 @@
|
||||
interface Props {
|
||||
className?: string;
|
||||
logoUrl?: string;
|
||||
}
|
||||
|
||||
export const Logo = ({ className = "size-14" }: Props) => {
|
||||
export const Logo = ({ className = "size-14", logoUrl }: Props) => {
|
||||
if (logoUrl) {
|
||||
return (
|
||||
<img
|
||||
src={logoUrl}
|
||||
alt="Organization Logo"
|
||||
className={className}
|
||||
style={{ objectFit: "contain" }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
||||
@@ -11,6 +11,7 @@ export const organizationRouter = createTRPCRouter({
|
||||
.input(
|
||||
z.object({
|
||||
name: z.string(),
|
||||
logo: z.string().optional(),
|
||||
}),
|
||||
)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
@@ -81,6 +82,7 @@ export const organizationRouter = createTRPCRouter({
|
||||
z.object({
|
||||
organizationId: z.string(),
|
||||
name: z.string(),
|
||||
logo: z.string().optional(),
|
||||
}),
|
||||
)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
@@ -92,7 +94,10 @@ export const organizationRouter = createTRPCRouter({
|
||||
}
|
||||
const result = await db
|
||||
.update(organization)
|
||||
.set({ name: input.name })
|
||||
.set({
|
||||
name: input.name,
|
||||
logo: input.logo,
|
||||
})
|
||||
.where(eq(organization.id, input.organizationId))
|
||||
.returning();
|
||||
return result[0];
|
||||
|
||||
Reference in New Issue
Block a user