Sava data from user

Hi everybody

I’m developing a member space where multiple users can register and unregister. They’ll have access to a data table and the ability to click on rows to save and remember their interest in those specific rows.

How would you recommend storing this data for each user? What method would you use? The site can accommodate up to 500 users, and the table can have around 200 rows.

Thanks
O.

i would give each row an unique id and store structure with the selected rows per user via the user blueprint.

the only perfomance issue would be if you wanted to show a count on each row as that would require to parse all 500 users

Thank you for the guidance! Here’s how I’m actually trying to implement this:

The user blueprint :

title: Member
fields:
  selectedItems:
    label: Selected Items
    type: structure
    fields:
      id:
        label: Item ID
        type: text

The JS

$('#myTable tbody').on('click', '.color.black', function(event) {
        event.stopPropagation();
        let $row = $(this).closest('tr');
        let itemId = $row.data('item-id');

        if ($(this).hasClass('selected')) {
            $(this).removeClass('selected');
            updateSelection(itemId, 'remove');
        } else {
            $(this).addClass('selected');
            updateSelection(itemId, 'add');
        }
    });

    function updateSelection(itemId, action) {
        $.ajax({
            url: 'http://localhost:8888/Appel/rssfeed/update-selection',
            method: 'POST',
            data: {
                itemId: itemId,
                action: action
            },
            success: function(response) {
                if (response.status !== 'ok') {
                    console.error('Failed to update selection:', response.message);
                }
            },
            error: function(xhr, status, error) {
                console.error('Failed to update selection:', status, error);
            }
        });
    }

With my config.php

'routes' => [
      [
        'pattern' => 'rssfeed/update-selection',
        'method' => 'POST',
        'action'  => function () {
            $user = kirby()->user();
            if ($user) {
                $itemId = get('itemId');
                $action = get('action');
                $selectedItems = $user->selectedItems()->toStructure();

                if ($action == 'add') {
                    $selectedItems = $selectedItems->append(['id' => $itemId]);
                } elseif ($action == 'remove') {
                    $selectedItems = $selectedItems->filterBy('id', '!=', $itemId);
                }

                try {
                    $user->update([
                        'selectedItems' => $selectedItems->yaml()
                    ]);

                    return [
                        'status' => 'ok'
                    ];
                } catch (Exception $e) {
                    return [
                        'status' => 'error',
                        'message' => 'Failed to update user selection',
                        'error' => $e->getMessage()
                    ];
                }
            }

            return [
                'status' => 'error',
                'message' => 'User not authenticated'
            ];
        }
    ]

For now, selectedItems remains empty in the user’s .txt file, although I feel like my code looks correct.

i think the structure item might have an id from kirby. even if its just an incremented numeric value. it might be better to call it _id or uid.

otherwise it seems fine. any issues with your current implementation?

Well, I’ve changed to

fields:
  selectedItems:
    label: Selected Items
    type: structure
    fields:
      _id:
        label: Item ID
        type: text
$('#myTable tbody').on('click', '.color.black', function(event) {
    event.stopPropagation();
    let $row = $(this).closest('tr');
    let itemId = $row.data('uid'); 

    if ($(this).hasClass('selected')) {
        $(this).removeClass('selected');
        updateSelection(itemId, 'remove');
        console.log('Item removed:', itemId);
    } else {
        $(this).addClass('selected');
        updateSelection(itemId, 'add');
        console.log('Item added:', itemId);
    }
});

    function updateSelection(itemId, action) {
        $.ajax({
            url: 'http://localhost:8888/Appel/rssfeed/update-selection',
            method: 'POST',
            data: {
                itemId: itemId,
                action: action
            },
            success: function(response) {
                if (response.status !== 'ok') {
                    console.error('Failed to update selection:', response.message);
                }
            },
            error: function(xhr, status, error) {
                console.error('Failed to update selection:', status, error);
            }
        });
    }
[
         'pattern' => 'rssfeed/update-selection',
         'method' => 'POST',
         'action'  => function () {
            $user = kirby()->user();
            if ($user) {
               $itemId = get('itemId');
               $action = get('action');
               $selectedItems = $user->selectedItems()->toStructure();

               if ($action == 'add') {
                  $selectedItems = $selectedItems->append(['_id' => $itemId]);
               } elseif ($action == 'remove') {
                  $selectedItems = $selectedItems->filterBy('_id', '!=', $itemId);
               }

               try {
                  $user->update([
                     'selectedItems' => $selectedItems->yaml()
                  ]);

                  return [
                     'status' => 'ok'
                  ];
               } catch (Exception $e) {
                  return [
                     'status' => 'error',
                     'message' => 'Failed to update user selection',
                     'error' => $e->getMessage()
                  ];
               }
            }

            return [
               'status' => 'error',
               'message' => 'User not authenticated'
            ];
         }
      ]

But I don’t see any updates in the user’s txt file, any entries. I can see the data on click with a log, but the user file is not updated. Is it due to permissions ? Or something else in my code ?