Front end post or photo or both

I’ve made a similar form before, and it works whether it has a post or not. This form does not use wp_editor, but you can just modify the code to suit your need.

add_action('wp_ajax_add_story', 'process_story_entry');

function process_story_entry() {
global $current_user;
if ( empty($_POST) || !wp_verify_nonce($_POST[$current_user->user_login],'add_story') ) {
    echo 'You targeted the right function, but sorry, your nonce did not verify.';
    die();
} else {

    // validate data
    $story_title = $_POST['story-title'];
    $story_detail = $_POST['story-detail'];
    $story_type = $_POST['story-type'];
    $lot_term = $_POST['lot-term'];
    $author = $current_user->ID;
    $return = $_POST['_wp_http_referer'];
    $files = $_FILES['profile-picture'];

    // insert story
    $post = array(
        'comment_status' => 'open',
        'post_author' => $current_user->ID,
        'post_content' => $story_detail,
        'post_status' => 'publish',
        'post_title' => $story_title,
        'post_type' => 'story', 
        'tax_input' => array( 'lot-term' => array( $lot_term ) )
    );      
    $new_story = wp_insert_post( $post, true );

    if($new_story){
        // insert attachment
        $attached_files = attach_uploads($files,$new_story);
        // set as post thumbnail
        if($attached_files){
            set_post_thumbnail( $new_story, $attached_files[0] );   
        }
        // set term
        wp_set_post_terms( $new_story, array($story_type), 'story-type' );
    }

    // redirect to referer page
    wp_redirect($return.'#post-'.$new_story); //dion v12 2
    exit;

    die();
}
}

And the helper functions :

function ajax_response($data,$redirect){
    if(ajax_request()){
        $data_json = json_encode($data);
        echo $data_json;            
    } else {
        wp_redirect( $redirect );
        exit;
    }
}

function rearrange( $arr ){
foreach( $arr as $key => $all ){
    foreach( $all as $i => $val ){
        $new[$i][$key] = $val;    
    }    
}
return $new;
}

function attach_uploads($uploads,$post_id = 0){
$files = rearrange($uploads);
if($files[0]['name']==''){
    return false;   
}
foreach($files as $file){
    $upload_file = wp_handle_upload( $file, array('test_form' => false) );
    $attachment = array(
    'post_mime_type' => $upload_file['type'],
    'post_title' => preg_replace('/\.[^.]+$/', '', basename($upload_file['file'])),
    'post_content' => '',
    'post_status' => 'inherit'
    );
    $attach_id = wp_insert_attachment( $attachment, $upload_file['file'], $post_id );
    $attach_array[] = $attach_id;
    require_once(ABSPATH . 'wp-admin/includes/image.php');
    $attach_data = wp_generate_attachment_metadata( $attach_id, $upload_file['file'] );
    wp_update_attachment_metadata( $attach_id, $attach_data );
}
return $attach_array;
}

Hope this help