Building GDPR-Compliant User Deletion: A Full-Stack Approach
How we implemented user deletion at Homi with PII anonymization, analytics provider updates, and proper dependency handling—all while maintaining data integrity.
Remember when we redesigned our Add Property dialog and wrote about it? Turns out that design also didn't survive. Here's how we got it right (this time, we think).
Kristian Elset Bø
Engineer
Last week, I wrote about how we rebuilt our "Add Property" dialog three times in one session based on user feedback in No UI Survives First Contact with Users.
The final design? Three colored cards (blue, green, purple) explaining different import methods. Clean. Simple. Educational.
Plot twist: That design also didn't survive.
One week later, we rebuilt it again. And this time, I think we actually got it right. Here's the story of how "simple" can still be too complex, and why sometimes you need to redesign your redesign.
Our version from the last article looked like this:

What we thought we solved:
What users actually experienced:
The colors made it feel like a marketing page, not a tool. The visual hierarchy was confusing. And worst of all: we were still fighting for attention with three competing sections.
Here's what we got wrong:
Blue, green, and purple gradient cards all screaming for attention. In trying to make each method feel important, we made none of them feel primary.
Users didn't know where to start. The colors suggested equal importance when 99% of users just wanted to paste a URL.
Desktop version showed "Press Cmd+V" with numbered steps.
Mobile version had an actual input field.
Two completely different experiences for the same action. Confusing mental model.
Each card had:
We removed the form complexity but replaced it with informational complexity.
This time, we started with first principles:
Core insight: This dialog has ONE job — help users add a property. Everything else is secondary.
First draft stripped away everything:

The input field became the entire top section:
<InputGroup className="h-11">
<InputGroupInput
placeholder="https://..."
value={propertyUrl}
onChange={(e) => setPropertyUrl(e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter" && propertyUrl) {
handlePrimaryUrlSubmit();
}
}}
/>
<InputGroupAddon align="inline-end">
<InputGroupButton
onClick={handlePrimaryUrlSubmit}
disabled={!propertyUrl}
variant="default"
size="sm"
>
Add
</InputGroupButton>
</InputGroupAddon>
</InputGroup>
Clean. Focused. Obvious what to do.
Instead of three visible cards, we used a single accordion:
"More ways to add properties" ▾
When expanded, shows:
Each with a small description and action button. No colors. No gradients. Just clean typography and spacing.
Original design had footer buttons:
New design? No footer at all for the main view.
Why? Because it's not a form. It's an information hub. Users can:
No "Cancel" needed. No competing CTAs.


Now we just have one accordion that shows everything, instead of three individual ones :)
Single accordion: "More ways to add properties"
Expands to show:
All with consistent styling, clear descriptions, action buttons.
Previous design: Everything colorful and prominent
New design: One thing prominent, everything else subtle
The hero input doesn't need color to stand out—it stands out because nothing else is competing.
We unified the experience:
No more context-switching between devices.
Cards say "Look at all these options!"
Accordions say "Here's the main thing, other stuff available if needed."
Massive psychological difference.
Original: "Create Manually" button in footer
Problem: Far from explanation, unclear relationship
New: "Create Manually" section with description + button together
Result: Clear cause and effect
We were using a custom InputGroup component from our design system. It handles:
Stop reinventing UI patterns. Use what's already built and tested.
<div className="flex items-stretch gap-0">
<Input className="h-11 flex-1 rounded-r-none border-r-0 focus:z-10" />
<Button className="h-11 rounded-l-none px-6">Add</Button>
</div>
Multiple z-index hacks, careful border management, focus state juggling.
<InputGroup className="h-11">
<InputGroupInput placeholder="https://..." />
<InputGroupAddon align="inline-end">
<InputGroupButton variant="default" size="sm">
Add
</InputGroupButton>
</InputGroupAddon>
</InputGroup>
Handles everything correctly. No hacks. No custom CSS.
<Accordion type="single" collapsible>
<AccordionItem value="more-ways">
<AccordionTrigger>More ways to add properties</AccordionTrigger>
<AccordionContent>
{/* All three methods with consistent spacing */}
<div className="space-y-6">
{/* Email to Collection */}
{/* Bulk Import */}
{/* Create Manually */}
</div>
</AccordionContent>
</AccordionItem>
</Accordion>
Single source of expansion. Clean state management. Accessible by default.
How do we know this design is better?
User testing feedback:
"Oh, I just paste the link here? Got it."
"Much cleaner than before."
"I didn't even notice the other options until you asked."
That last one is the win. Good UI should be invisible when you're using the main path.
This is the third major redesign of this dialog:
Each time, we thought we'd nailed it. Each time, users showed us we hadn't.
The irony? We wrote a blog post about iteration and still had to iterate more.
But that's the point.
There's no "done" in UI design. There's only "better than before."
Previous iterations tried to showcase features.
This iteration tries to hide them.
Previous iterations used visual flair to create hierarchy.
This iteration uses space and restraint.
Previous iterations assumed users needed education.
This iteration assumes users know what they want and gets out of their way.
Maybe in six months we'll redesign again. Maybe users will ask for something we can't imagine today.
But for now, the dialog does its job: helps users add properties without getting in their way.
And honestly? That's all it ever needed to do.
If you're redesigning something (again), ask:
The original blog post ended with: "Your first UI design won't be your last."
Turns out your second UI design won't be your last either.
Or your third.
Or your fourth.
That's not a bug in the process—it's the process itself.
Build. Ship. Watch. Learn. Rebuild.
The goal isn't perfection. It's continuous improvement.
Our "Add Property" dialog is better today than yesterday. Tomorrow it might be better still. Or it might need another redesign.
Either way, we'll iterate.
Because no UI survives first contact with users.
Not even the redesigns.
Update: Since publishing this, we've already gotten feedback about the accordion being too subtle. Iteration continues. 😄
Want to see the latest version in action? Try Homi and paste a property URL. Let us know what you think—we're always iterating.

Engineering at Homi, building the future of real estate technology.
Continue reading with these related articles
How we implemented user deletion at Homi with PII anonymization, analytics provider updates, and proper dependency handling—all while maintaining data integrity.
How we rebuilt our 'Add Property' dialog three times in one session based on real user feedback. A case study in iterative design and the importance of staying flexible.
How we built a campaign-ready sync system for Loops that computes dynamic user segments on-demand without polluting our database schema or scattering one-off updates throughout our codebase.