recycle_bin 1.1.0 → 1.2.0

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.
data/docs/logo.svg ADDED
@@ -0,0 +1,71 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="200" height="200">
2
+ <defs>
3
+ <!-- Gradient for the main container -->
4
+ <linearGradient id="containerGradient" x1="0%" y1="0%" x2="100%" y2="100%">
5
+ <stop offset="0%" style="stop-color:#667eea;stop-opacity:1" />
6
+ <stop offset="100%" style="stop-color:#764ba2;stop-opacity:1" />
7
+ </linearGradient>
8
+
9
+ <!-- Gradient for the lid -->
10
+ <linearGradient id="lidGradient" x1="0%" y1="0%" x2="100%" y2="100%">
11
+ <stop offset="0%" style="stop-color:#8b9cf7;stop-opacity:1" />
12
+ <stop offset="100%" style="stop-color:#667eea;stop-opacity:1" />
13
+ </linearGradient>
14
+
15
+ <!-- Shadow filter -->
16
+ <filter id="dropShadow" x="-50%" y="-50%" width="200%" height="200%">
17
+ <feDropShadow dx="3" dy="6" stdDeviation="4" flood-color="rgba(0,0,0,0.3)"/>
18
+ </filter>
19
+
20
+ <!-- Glow effect -->
21
+ <filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
22
+ <feGaussianBlur stdDeviation="3" result="coloredBlur"/>
23
+ <feMerge>
24
+ <feMergeNode in="coloredBlur"/>
25
+ <feMergeNode in="SourceGraphic"/>
26
+ </feMerge>
27
+ </filter>
28
+ </defs>
29
+
30
+ <!-- Background circle -->
31
+ <circle cx="100" cy="100" r="95" fill="url(#containerGradient)" filter="url(#dropShadow)" opacity="0.1"/>
32
+
33
+ <!-- Main trash bin body -->
34
+ <rect x="60" y="80" width="80" height="90" rx="8" ry="8" fill="url(#containerGradient)" filter="url(#dropShadow)"/>
35
+
36
+ <!-- Trash bin lid -->
37
+ <rect x="50" y="70" width="100" height="12" rx="6" ry="6" fill="url(#lidGradient)" filter="url(#dropShadow)"/>
38
+
39
+ <!-- Lid handle -->
40
+ <rect x="90" y="55" width="20" height="8" rx="4" ry="4" fill="url(#lidGradient)"/>
41
+ <rect x="95" y="63" width="10" height="12" fill="url(#lidGradient)"/>
42
+
43
+ <!-- Vertical lines on trash bin -->
44
+ <line x1="80" y1="90" x2="80" y2="155" stroke="rgba(255,255,255,0.3)" stroke-width="2" stroke-linecap="round"/>
45
+ <line x1="100" y1="90" x2="100" y2="155" stroke="rgba(255,255,255,0.3)" stroke-width="2" stroke-linecap="round"/>
46
+ <line x1="120" y1="90" x2="120" y2="155" stroke="rgba(255,255,255,0.3)" stroke-width="2" stroke-linecap="round"/>
47
+
48
+ <!-- Restore arrow (curved arrow indicating recovery) -->
49
+ <g transform="translate(130, 40)" filter="url(#glow)">
50
+ <path d="M 0 15 Q 10 5 20 15 Q 15 10 15 20" stroke="#28a745" stroke-width="3" fill="none" stroke-linecap="round"/>
51
+ <polygon points="12,18 18,18 15,24" fill="#28a745"/>
52
+ </g>
53
+
54
+ <!-- Floating particles (representing restored items) -->
55
+ <circle cx="45" cy="50" r="3" fill="#28a745" opacity="0.7">
56
+ <animate attributeName="cy" values="50;45;50" dur="2s" repeatCount="indefinite"/>
57
+ </circle>
58
+ <circle cx="155" cy="60" r="2" fill="#ffc107" opacity="0.8">
59
+ <animate attributeName="cy" values="60;55;60" dur="1.5s" repeatCount="indefinite"/>
60
+ <animate attributeName="opacity" values="0.8;0.4;0.8" dur="1.5s" repeatCount="indefinite"/>
61
+ </circle>
62
+ <circle cx="40" cy="120" r="2.5" fill="#17a2b8" opacity="0.6">
63
+ <animate attributeName="cy" values="120;115;120" dur="2.5s" repeatCount="indefinite"/>
64
+ </circle>
65
+
66
+ <!-- Subtle highlight on the bin -->
67
+ <rect x="62" y="82" width="15" height="60" rx="4" ry="4" fill="rgba(255,255,255,0.2)"/>
68
+
69
+ <!-- Brand text (small) -->
70
+ <text x="100" y="190" text-anchor="middle" font-family="Inter, sans-serif" font-size="14" font-weight="600" fill="url(#containerGradient)">RecycleBin</text>
71
+ </svg>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RecycleBin
4
- VERSION = '1.1.0'
4
+ VERSION = '1.2.0'
5
5
  end
data/lib/recycle_bin.rb CHANGED
@@ -165,15 +165,52 @@ module RecycleBin
165
165
  # Configuration class for RecycleBin
166
166
  class Configuration
167
167
  attr_accessor :enable_web_interface, :items_per_page, :ui_theme,
168
- :auto_cleanup_after, :current_user_method, :max_items_per_page
168
+ :auto_cleanup_after, :current_user_method, :max_items_per_page,
169
+ :search_settings, :export_settings, :error_logging_service,
170
+ :enable_advanced_filters, :enable_search_highlighting,
171
+ :max_search_results, :enable_export,
172
+ :export_formats, :export_max_items, :enable_audit_logging
169
173
 
170
174
  def initialize
175
+ # Basic settings
171
176
  @enable_web_interface = true
172
177
  @items_per_page = 25
173
178
  @max_items_per_page = 1000
174
179
  @ui_theme = 'default'
175
180
  @auto_cleanup_after = nil
176
181
  @current_user_method = :current_user
182
+
183
+ # Search settings
184
+ @search_settings = {
185
+ enable_full_text_search: true,
186
+ searchable_fields: %w[title name email content body description],
187
+ max_search_length: 100,
188
+ search_timeout: 30.seconds,
189
+ enable_fuzzy_search: false,
190
+ min_search_length: 2
191
+ }
192
+
193
+ # Export settings
194
+ @export_settings = {
195
+ enable_csv_export: true,
196
+ enable_json_export: true,
197
+ max_export_items: 10_000,
198
+ export_timeout: 5.minutes,
199
+ include_metadata: true,
200
+ compress_large_exports: true
201
+ }
202
+
203
+ # Advanced features
204
+ @enable_advanced_filters = true
205
+ @enable_search_highlighting = true
206
+ @max_search_results = 10_000
207
+ @enable_export = true
208
+ @export_formats = %w[csv json]
209
+ @export_max_items = 10_000
210
+ @enable_audit_logging = false
211
+
212
+ # Error logging service (can be set to external service like Sentry)
213
+ @error_logging_service = nil
177
214
  end
178
215
 
179
216
  def authorize_with(&block)
@@ -183,5 +220,78 @@ module RecycleBin
183
220
  def authorization_method
184
221
  @authorization_method || proc { true }
185
222
  end
223
+
224
+ # Search configuration methods
225
+ def search_config
226
+ @search_settings
227
+ end
228
+
229
+ def enable_full_text_search=(value)
230
+ @search_settings[:enable_full_text_search] = value
231
+ end
232
+
233
+ def searchable_fields=(fields)
234
+ @search_settings[:searchable_fields] = Array(fields)
235
+ end
236
+
237
+ def max_search_length=(length)
238
+ @search_settings[:max_search_length] = length
239
+ end
240
+
241
+ def search_timeout=(timeout)
242
+ @search_settings[:search_timeout] = timeout
243
+ end
244
+
245
+ # Export configuration methods
246
+ def export_config
247
+ @export_settings
248
+ end
249
+
250
+ def enable_csv_export=(value)
251
+ @export_settings[:enable_csv_export] = value
252
+ end
253
+
254
+ def enable_json_export=(value)
255
+ @export_settings[:enable_json_export] = value
256
+ end
257
+
258
+ def max_export_items=(count)
259
+ @export_settings[:max_export_items] = count
260
+ end
261
+
262
+ def export_timeout=(timeout)
263
+ @export_settings[:export_timeout] = timeout
264
+ end
265
+
266
+ # Validation methods
267
+ def valid?
268
+ validate_configuration
269
+ end
270
+
271
+ def validate_configuration
272
+ errors = []
273
+
274
+ # Validate search settings
275
+ errors << 'min_search_length cannot be greater than max_search_length' if @search_settings[:min_search_length] > @search_settings[:max_search_length]
276
+
277
+ errors << 'search_timeout must be positive' if @search_settings[:search_timeout] <= 0
278
+
279
+ # Validate export settings
280
+ errors << 'max_export_items must be positive' if @export_settings[:max_export_items] <= 0
281
+
282
+ errors << 'export_timeout must be positive' if @export_settings[:export_timeout] <= 0
283
+
284
+ # Validate basic settings
285
+ errors << 'items_per_page must be positive' if @items_per_page <= 0
286
+
287
+ errors << 'max_items_per_page cannot be less than items_per_page' if @max_items_per_page < @items_per_page
288
+
289
+ errors.empty?
290
+ end
291
+
292
+ def errors
293
+ validate_configuration
294
+ []
295
+ end
186
296
  end
187
297
  end
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: recycle_bin
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rishi Somani
8
8
  - Shobhit Jain
9
9
  - Raghav Agrawal
10
+ autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2025-05-25 00:00:00.000000000 Z
13
+ date: 2025-09-08 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: rails
@@ -92,13 +93,21 @@ files:
92
93
  - app/controllers/recycle_bin/application_controller.rb
93
94
  - app/controllers/recycle_bin/trash_controller.rb
94
95
  - app/helpers/recycle_bin/application_helper.rb
95
- - app/views/layouts/recycle_bin/application.html.erb
96
- - app/views/layouts/recycle_bin/recycle_bin/application.html.erb
97
- - app/views/layouts/recycle_bin/recycle_bin/trash/index.html.erb
98
- - app/views/layouts/recycle_bin/recycle_bin/trash/show.html.erb
96
+ - app/views/recycle_bin/layouts/recycle_bin.html.erb
97
+ - app/views/recycle_bin/shared/_error_messages.html.erb
98
+ - app/views/recycle_bin/shared/_flash_messages.html.erb
99
+ - app/views/recycle_bin/trash/_action_history.html.erb
100
+ - app/views/recycle_bin/trash/_associations.html.erb
101
+ - app/views/recycle_bin/trash/_filters.html.erb
102
+ - app/views/recycle_bin/trash/_item.html.erb
103
+ - app/views/recycle_bin/trash/_pagination.html.erb
104
+ - app/views/recycle_bin/trash/_stats.html.erb
105
+ - app/views/recycle_bin/trash/dashboard.html.erb
99
106
  - app/views/recycle_bin/trash/index.html.erb
100
107
  - app/views/recycle_bin/trash/show.html.erb
101
108
  - config/routes.rb
109
+ - docs/index.html
110
+ - docs/logo.svg
102
111
  - lib/generators/recycle_bin/add_deleted_at/add_deleted_at_generator.rb
103
112
  - lib/generators/recycle_bin/add_deleted_at/templates/add_deleted_at_migration.rb.erb
104
113
  - lib/generators/recycle_bin/install/install_generator.rb
@@ -108,7 +117,6 @@ files:
108
117
  - lib/recycle_bin/install/templates/recycle_bin.rb
109
118
  - lib/recycle_bin/soft_deletable.rb
110
119
  - lib/recycle_bin/version.rb
111
- - recycle_bin.gemspec
112
120
  - sig/recycle_bin.rbs
113
121
  homepage: https://github.com/R95-del/recycle_bin
114
122
  licenses:
@@ -121,6 +129,7 @@ metadata:
121
129
  bug_tracker_uri: https://github.com/R95-del/recycle_bin/issues
122
130
  documentation_uri: https://github.com/R95-del/recycle_bin/blob/main/README.md
123
131
  wiki_uri: https://github.com/R95-del/recycle_bin/wiki
132
+ post_install_message:
124
133
  rdoc_options: []
125
134
  require_paths:
126
135
  - lib
@@ -135,7 +144,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
144
  - !ruby/object:Gem::Version
136
145
  version: '0'
137
146
  requirements: []
138
- rubygems_version: 3.6.6
147
+ rubygems_version: 3.5.18
148
+ signing_key:
139
149
  specification_version: 4
140
150
  summary: Soft delete and trash management for Ruby on Rails applications
141
151
  test_files: []
@@ -1,266 +0,0 @@
1
-
2
- <!DOCTYPE html>
3
- <html>
4
- <head>
5
- <title>Recycle Bin</title>
6
- <meta name="viewport" content="width=device-width,initial-scale=1">
7
- <%= csrf_meta_tags %>
8
- <%= csp_meta_tag %>
9
-
10
- <style>
11
- /* Simple, clean CSS for V1 MVP */
12
- * {
13
- box-sizing: border-box;
14
- margin: 0;
15
- padding: 0;
16
- }
17
-
18
- body {
19
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
20
- line-height: 1.6;
21
- color: #333;
22
- background-color: #f8f9fa;
23
- }
24
-
25
- .container {
26
- max-width: 1200px;
27
- margin: 0 auto;
28
- padding: 0 20px;
29
- }
30
-
31
- /* Header */
32
- .header {
33
- background: #fff;
34
- border-bottom: 1px solid #dee2e6;
35
- padding: 1rem 0;
36
- margin-bottom: 2rem;
37
- }
38
-
39
- .header h1 {
40
- color: #495057;
41
- font-size: 1.5rem;
42
- display: flex;
43
- align-items: center;
44
- gap: 0.5rem;
45
- }
46
-
47
- .header .trash-icon {
48
- font-size: 1.8rem;
49
- }
50
-
51
- /* Navigation */
52
- .nav {
53
- margin-top: 1rem;
54
- }
55
-
56
- .nav a {
57
- color: #6c757d;
58
- text-decoration: none;
59
- margin-right: 1.5rem;
60
- padding: 0.5rem 0;
61
- border-bottom: 2px solid transparent;
62
- transition: all 0.2s;
63
- }
64
-
65
- .nav a:hover,
66
- .nav a.active {
67
- color: #495057;
68
- border-bottom-color: #007bff;
69
- }
70
-
71
- /* Cards */
72
- .card {
73
- background: #fff;
74
- border-radius: 8px;
75
- box-shadow: 0 1px 3px rgba(0,0,0,0.1);
76
- padding: 1.5rem;
77
- margin-bottom: 1rem;
78
- }
79
-
80
- /* Buttons */
81
- .btn {
82
- display: inline-block;
83
- padding: 0.5rem 1rem;
84
- border: none;
85
- border-radius: 4px;
86
- text-decoration: none;
87
- cursor: pointer;
88
- font-size: 0.875rem;
89
- transition: all 0.2s;
90
- }
91
-
92
- .btn-primary {
93
- background: #007bff;
94
- color: white;
95
- }
96
-
97
- .btn-primary:hover {
98
- background: #0056b3;
99
- }
100
-
101
- .btn-success {
102
- background: #28a745;
103
- color: white;
104
- }
105
-
106
- .btn-success:hover {
107
- background: #1e7e34;
108
- }
109
-
110
- .btn-danger {
111
- background: #dc3545;
112
- color: white;
113
- }
114
-
115
- .btn-danger:hover {
116
- background: #c82333;
117
- }
118
-
119
- .btn-sm {
120
- padding: 0.25rem 0.75rem;
121
- font-size: 0.8rem;
122
- }
123
-
124
- /* Tables */
125
- .table {
126
- width: 100%;
127
- border-collapse: collapse;
128
- background: #fff;
129
- border-radius: 8px;
130
- overflow: hidden;
131
- box-shadow: 0 1px 3px rgba(0,0,0,0.1);
132
- }
133
-
134
- .table th,
135
- .table td {
136
- padding: 1rem;
137
- text-align: left;
138
- border-bottom: 1px solid #dee2e6;
139
- }
140
-
141
- .table th {
142
- background: #f8f9fa;
143
- font-weight: 600;
144
- color: #495057;
145
- }
146
-
147
- .table tr:hover {
148
- background: #f8f9fa;
149
- }
150
-
151
- /* Stats */
152
- .stats {
153
- display: grid;
154
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
155
- gap: 1rem;
156
- margin-bottom: 2rem;
157
- }
158
-
159
- .stat-card {
160
- background: #fff;
161
- padding: 1.5rem;
162
- border-radius: 8px;
163
- box-shadow: 0 1px 3px rgba(0,0,0,0.1);
164
- text-align: center;
165
- }
166
-
167
- .stat-number {
168
- font-size: 2rem;
169
- font-weight: bold;
170
- color: #007bff;
171
- }
172
-
173
- .stat-label {
174
- color: #6c757d;
175
- font-size: 0.875rem;
176
- margin-top: 0.5rem;
177
- }
178
-
179
- /* Empty state */
180
- .empty-state {
181
- text-align: center;
182
- padding: 4rem 2rem;
183
- color: #6c757d;
184
- }
185
-
186
- .empty-state-icon {
187
- font-size: 4rem;
188
- margin-bottom: 1rem;
189
- }
190
-
191
- /* Responsive */
192
- @media (max-width: 768px) {
193
- .container {
194
- padding: 0 15px;
195
- }
196
-
197
- .table {
198
- font-size: 0.875rem;
199
- }
200
-
201
- .table th,
202
- .table td {
203
- padding: 0.75rem 0.5rem;
204
- }
205
-
206
- .btn {
207
- font-size: 0.8rem;
208
- padding: 0.4rem 0.8rem;
209
- }
210
- }
211
-
212
- /* Alerts */
213
- .alert {
214
- padding: 0.75rem 1rem;
215
- margin-bottom: 1rem;
216
- border-radius: 4px;
217
- }
218
-
219
- .alert-success {
220
- background: #d4edda;
221
- color: #155724;
222
- border: 1px solid #c3e6cb;
223
- }
224
-
225
- .alert-danger {
226
- background: #f8d7da;
227
- color: #721c24;
228
- border: 1px solid #f5c6cb;
229
- }
230
-
231
- .alert-info {
232
- background: #d1ecf1;
233
- color: #0c5460;
234
- border: 1px solid #bee5eb;
235
- }
236
- </style>
237
- </head>
238
-
239
- <body>
240
- <div class="header">
241
- <div class="container">
242
- <h1>
243
- <span class="trash-icon">🗑️</span>
244
- Recycle Bin
245
- </h1>
246
- <nav class="nav">
247
- <%= link_to "All Items", recycle_bin.trash_index_path,
248
- class: ("active" if current_page?(recycle_bin.trash_index_path)) %>
249
- <%= link_to "Statistics", "#", class: "disabled" %>
250
- </nav>
251
- </div>
252
- </div>
253
-
254
- <div class="container">
255
- <% if notice %>
256
- <div class="alert alert-success"><%= notice %></div>
257
- <% end %>
258
-
259
- <% if alert %>
260
- <div class="alert alert-danger"><%= alert %></div>
261
- <% end %>
262
-
263
- <%= yield %>
264
- </div>
265
- </body>
266
- </html>
@@ -1,133 +0,0 @@
1
- <% content_for :title, "Recycle Bin" %>
2
-
3
- <!-- Statistics Cards -->
4
- <div class="stats">
5
- <div class="stat-card">
6
- <div class="stat-number"><%= @deleted_items.count %></div>
7
- <div class="stat-label">Items in Trash</div>
8
- </div>
9
-
10
- <div class="stat-card">
11
- <div class="stat-number"><%= @model_types.count %></div>
12
- <div class="stat-label">Different Types</div>
13
- </div>
14
-
15
- <div class="stat-card">
16
- <div class="stat-number">
17
- <%= @deleted_items.where('deleted_at > ?', 1.day.ago).count %>
18
- </div>
19
- <div class="stat-label">Deleted Today</div>
20
- </div>
21
- </div>
22
-
23
- <!-- Main Content -->
24
- <div class="card">
25
- <% if @deleted_items.any? %>
26
- <h2 style="margin-bottom: 1.5rem; color: #495057;">
27
- Deleted Items
28
- <span style="font-size: 0.8em; color: #6c757d;">
29
- (<%= @deleted_items.count %> items)
30
- </span>
31
- </h2>
32
-
33
- <!-- Model Type Filter -->
34
- <div style="margin-bottom: 1.5rem;">
35
- <strong>Filter by type:</strong>
36
- <%= link_to "All", recycle_bin.trash_index_path,
37
- class: "btn btn-sm #{'btn-primary' if params[:type].blank?}" %>
38
- <% @model_types.each do |model_type| %>
39
- <%= link_to model_type, recycle_bin.trash_index_path(type: model_type),
40
- class: "btn btn-sm #{'btn-primary' if params[:type] == model_type}" %>
41
- <% end %>
42
- </div>
43
-
44
- <!-- Items Table -->
45
- <table class="table">
46
- <thead>
47
- <tr>
48
- <th>Type</th>
49
- <th>Title</th>
50
- <th>Deleted At</th>
51
- <th>Actions</th>
52
- </tr>
53
- </thead>
54
- <tbody>
55
- <% @deleted_items.each do |item| %>
56
- <tr>
57
- <td>
58
- <strong><%= item.class.name %></strong>
59
- </td>
60
- <td>
61
- <%= link_to truncate(item.recyclable_title, length: 50),
62
- recycle_bin.trash_path(item),
63
- style: "text-decoration: none; color: #007bff;" %>
64
- </td>
65
- <td>
66
- <span style="color: #6c757d;">
67
- <%= time_ago_in_words(item.deleted_at) %> ago
68
- </span>
69
- <br>
70
- <small style="color: #adb5bd;">
71
- <%= item.deleted_at.strftime('%B %d, %Y at %I:%M %p') %>
72
- </small>
73
- </td>
74
- <td>
75
- <%= link_to "View", recycle_bin.trash_path(item),
76
- class: "btn btn-sm btn-primary" %>
77
- <%= link_to "Restore", recycle_bin.restore_trash_path(item),
78
- method: :patch,
79
- class: "btn btn-sm btn-success",
80
- data: {
81
- confirm: "Are you sure you want to restore this #{item.class.name.downcase}?"
82
- } %>
83
- <%= link_to "Delete Forever", recycle_bin.trash_path(item),
84
- method: :delete,
85
- class: "btn btn-sm btn-danger",
86
- data: {
87
- confirm: "This will permanently delete this #{item.class.name.downcase}. This action cannot be undone!"
88
- } %>
89
- </td>
90
- </tr>
91
- <% end %>
92
- </tbody>
93
- </table>
94
-
95
- <!-- Bulk Actions -->
96
- <div style="margin-top: 2rem; padding-top: 1rem; border-top: 1px solid #dee2e6;">
97
- <p style="color: #6c757d; font-size: 0.875rem;">
98
- <strong>Bulk Actions:</strong>
99
- Select items above to restore or delete multiple items at once.
100
- <em>(Coming in v1.1)</em>
101
- </p>
102
- </div>
103
-
104
- <% else %>
105
- <!-- Empty State -->
106
- <div class="empty-state">
107
- <div class="empty-state-icon">🎉</div>
108
- <h3>Your trash is empty!</h3>
109
- <p>When you delete items from your application, they'll appear here so you can restore them if needed.</p>
110
-
111
- <div style="margin-top: 2rem;">
112
- <h4 style="color: #495057;">How to use RecycleBin:</h4>
113
- <div style="text-align: left; max-width: 500px; margin: 1rem auto;">
114
- <p><strong>1.</strong> Add <code>include RecycleBin::SoftDeletable</code> to your models</p>
115
- <p><strong>2.</strong> Add <code>deleted_at:datetime</code> column to your tables</p>
116
- <p><strong>3.</strong> Call <code>.destroy</code> on records - they'll come here instead of being deleted</p>
117
- <p><strong>4.</strong> Use <code>.restore</code> to bring them back</p>
118
- </div>
119
- </div>
120
- </div>
121
- <% end %>
122
- </div>
123
-
124
- <!-- Help Section -->
125
- <div class="card" style="margin-top: 2rem; background: #f8f9fa;">
126
- <h4 style="color: #495057; margin-bottom: 1rem;">💡 Pro Tips</h4>
127
- <ul style="color: #6c757d; line-height: 1.8;">
128
- <li><strong>Restore:</strong> Click "Restore" to bring items back to your application</li>
129
- <li><strong>Permanent Delete:</strong> "Delete Forever" removes items completely (cannot be undone)</li>
130
- <li><strong>Auto-cleanup:</strong> Items older than 30 days are automatically cleaned up</li>
131
- <li><strong>Search:</strong> Use your browser's find (Ctrl/Cmd+F) to search this page</li>
132
- </ul>
133
- </div>